From e01dda9bafb906123fb4fdc9c951e5da5c40a53b Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 21 Feb 2024 18:45:10 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E2=9C=A8=20CRM=EF=BC=9A=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E5=95=86=E6=9C=BA=E7=9A=84=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/crm/enums/ErrorCodeConstants.java | 1 + .../admin/business/CrmBusinessController.java | 98 ++++++++--- .../vo/business/CrmBusinessExcelVO.java | 75 --------- .../vo/business/CrmBusinessRespVO.java | 157 +++++++++++++----- .../vo/business/CrmBusinessSaveReqVO.java | 62 +++---- .../admin/contract/CrmContractController.java | 2 +- .../admin/product/CrmProductController.java | 53 ++++-- .../product/vo/product/CrmProductRespVO.java | 3 +- .../vo/product/CrmProductSaveReqVO.java | 6 +- .../convert/business/CrmBusinessConvert.java | 23 --- .../convert/product/CrmProductConvert.java | 46 ----- .../dataobject/business/CrmBusinessDO.java | 97 +++++------ .../business/CrmBusinessProductDO.java | 26 +-- .../crm/dal/dataobject/clue/CrmClueDO.java | 2 +- .../dal/dataobject/product/CrmProductDO.java | 6 +- .../crm/dal/mysql/business/package-info.java | 4 - .../crm/dal/mysql/contact/package-info.java | 4 - .../dal/mysql/product/CrmProductMapper.java | 24 +-- .../service/business/CrmBusinessService.java | 9 + .../business/CrmBusinessServiceImpl.java | 124 +++++++------- .../business/CrmBusinessStatusService.java | 14 +- .../CrmBusinessStatusServiceImpl.java | 5 + .../CrmBusinessStatusTypeService.java | 13 ++ .../CrmBusinessStatusTypeServiceImpl.java | 11 +- .../contract/CrmContractServiceImpl.java | 3 +- .../product/CrmProductCategoryService.java | 15 +- .../service/product/CrmProductService.java | 33 +++- .../product/CrmProductServiceImpl.java | 49 ++++-- 28 files changed, 527 insertions(+), 438 deletions(-) delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessExcelVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/product/CrmProductConvert.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/package-info.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/package-info.java diff --git a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java index 7a04208fb..a484c778f 100644 --- a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java +++ b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java @@ -67,6 +67,7 @@ public interface ErrorCodeConstants { // ========== 产品 1_020_008_000 ========== ErrorCode PRODUCT_NOT_EXISTS = new ErrorCode(1_020_008_000, "产品不存在"); ErrorCode PRODUCT_NO_EXISTS = new ErrorCode(1_020_008_001, "产品编号已存在"); + ErrorCode PRODUCT_NOT_ENABLE = new ErrorCode(1_020_008_002, "产品【{}】已禁用"); // ========== 产品分类 1_020_009_000 ========== ErrorCode PRODUCT_CATEGORY_NOT_EXISTS = new ErrorCode(1_020_009_000, "产品分类不存在"); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java index c85c151f5..91b8e95dd 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java @@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.crm.controller.admin.business; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; +import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; @@ -10,15 +12,21 @@ import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusi import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessRespVO; import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessSaveReqVO; import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO; -import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessConvert; import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; +import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO; import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; +import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO; import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService; import cn.iocoder.yudao.module.crm.service.business.CrmBusinessStatusService; import cn.iocoder.yudao.module.crm.service.business.CrmBusinessStatusTypeService; import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; +import cn.iocoder.yudao.module.crm.service.product.CrmProductService; +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; @@ -30,13 +38,15 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import java.io.IOException; +import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.stream.Stream; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CUSTOMER_NOT_EXISTS; @@ -55,6 +65,13 @@ public class CrmBusinessController { private CrmBusinessStatusTypeService businessStatusTypeService; @Resource private CrmBusinessStatusService businessStatusService; + @Resource + private CrmProductService productService; + + @Resource + private AdminUserApi adminUserApi; + @Resource + private DeptApi deptApi; @PostMapping("/create") @Operation(summary = "创建商机") @@ -86,9 +103,25 @@ public class CrmBusinessController { @PreAuthorize("@ss.hasPermission('crm:business:query')") public CommonResult getBusiness(@RequestParam("id") Long id) { CrmBusinessDO business = businessService.getBusiness(id); - return success(BeanUtils.toBean(business, CrmBusinessRespVO.class)); + return success(buildBusinessDetail(business)); } + private CrmBusinessRespVO buildBusinessDetail(CrmBusinessDO business) { + if (business == null) { + return null; + } + CrmBusinessRespVO businessVO = buildBusinessDetailList(Collections.singletonList(business)).get(0); + // 拼接产品项 + List businessProducts = businessService.getBusinessProductListByBusinessId(businessVO.getId()); + Map productMap = productService.getProductMap( + convertSet(businessProducts, CrmBusinessProductDO::getProductId)); + businessVO.setProducts(BeanUtils.toBean(businessProducts, CrmBusinessRespVO.Product.class, businessProductVO -> + MapUtils.findAndThen(productMap, businessProductVO.getProductId(), + product -> businessProductVO.setProductNo(product.getNo()).setProductUnit(product.getUnit())))); + return businessVO; + } + + // TODO 芋艿:处理下 @GetMapping("/list-by-ids") @Operation(summary = "获得商机列表") @Parameter(name = "ids", description = "编号", required = true, example = "[1024]") @@ -97,6 +130,7 @@ public class CrmBusinessController { return success(BeanUtils.toBean(businessService.getBusinessList(ids, getLoginUserId()), CrmBusinessRespVO.class)); } + // TODO 芋艿:处理下 @GetMapping("/simple-all-list") @Operation(summary = "获得联系人的精简列表") @PreAuthorize("@ss.hasPermission('crm:contact:query')") @@ -113,7 +147,7 @@ public class CrmBusinessController { @PreAuthorize("@ss.hasPermission('crm:business:query')") public CommonResult> getBusinessPage(@Valid CrmBusinessPageReqVO pageVO) { PageResult pageResult = businessService.getBusinessPage(pageVO, getLoginUserId()); - return success(buildBusinessDetailPageResult(pageResult)); + return success(new PageResult<>(buildBusinessDetailList(pageResult.getList()), pageResult.getTotal())); } @GetMapping("/page-by-customer") @@ -123,7 +157,7 @@ public class CrmBusinessController { throw exception(CUSTOMER_NOT_EXISTS); } PageResult pageResult = businessService.getBusinessPageByCustomerId(pageReqVO); - return success(buildBusinessDetailPageResult(pageResult)); + return success(new PageResult<>(buildBusinessDetailList(pageResult.getList()), pageResult.getTotal())); } @GetMapping("/page-by-contact") @@ -131,7 +165,7 @@ public class CrmBusinessController { @PreAuthorize("@ss.hasPermission('crm:business:query')") public CommonResult> getBusinessContactPage(@Valid CrmBusinessPageReqVO pageReqVO) { PageResult pageResult = businessService.getBusinessPageByContact(pageReqVO); - return success(buildBusinessDetailPageResult(pageResult)); + return success(new PageResult<>(buildBusinessDetailList(pageResult.getList()), pageResult.getTotal())); } @GetMapping("/export-excel") @@ -141,29 +175,43 @@ public class CrmBusinessController { public void exportBusinessExcel(@Valid CrmBusinessPageReqVO exportReqVO, HttpServletResponse response) throws IOException { exportReqVO.setPageSize(PAGE_SIZE_NONE); - PageResult pageResult = businessService.getBusinessPage(exportReqVO, getLoginUserId()); + List list = businessService.getBusinessPage(exportReqVO, getLoginUserId()).getList(); // 导出 Excel ExcelUtils.write(response, "商机.xls", "数据", CrmBusinessRespVO.class, - buildBusinessDetailPageResult(pageResult).getList()); + buildBusinessDetailList(list)); } - /** - * 构建详细的商机分页结果 - * - * @param pageResult 简单的商机分页结果 - * @return 详细的商机分页结果 - */ - private PageResult buildBusinessDetailPageResult(PageResult pageResult) { - if (CollUtil.isEmpty(pageResult.getList())) { - return PageResult.empty(pageResult.getTotal()); + private List buildBusinessDetailList(List list) { + if (CollUtil.isEmpty(list)) { + return Collections.emptyList(); } - List statusTypeList = businessStatusTypeService.getBusinessStatusTypeList( - convertSet(pageResult.getList(), CrmBusinessDO::getStatusTypeId)); - List statusList = businessStatusService.getBusinessStatusList( - convertSet(pageResult.getList(), CrmBusinessDO::getStatusId)); - List customerList = customerService.getCustomerList( - convertSet(pageResult.getList(), CrmBusinessDO::getCustomerId)); - return CrmBusinessConvert.INSTANCE.convertPage(pageResult, customerList, statusTypeList, statusList); + // 1.1 获取客户列表 + Map customerMap = customerService.getCustomerMap( + convertSet(list, CrmBusinessDO::getCustomerId)); + // 1.2 获取创建人、负责人列表 + Map userMap = adminUserApi.getUserMap(convertListByFlatMap(list, + contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); + Map deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId)); + // 1.3 获得商机状态组 + Map statusTypeMap = businessStatusTypeService.getBusinessStatusTypeMap( + convertSet(list, CrmBusinessDO::getStatusTypeId)); + Map statusMap = businessStatusService.getBusinessStatusMap( + convertSet(list, CrmBusinessDO::getStatusId)); + // 2. 拼接数据 + return BeanUtils.toBean(list, CrmBusinessRespVO.class, businessVO -> { + // 2.1 设置客户名称 + MapUtils.findAndThen(customerMap, businessVO.getCustomerId(), customer -> businessVO.setCustomerName(customer.getName())); + // 2.2 设置创建人、负责人名称 + MapUtils.findAndThen(userMap, NumberUtils.parseLong(businessVO.getCreator()), + user -> businessVO.setCreatorName(user.getNickname())); + MapUtils.findAndThen(userMap, businessVO.getOwnerUserId(), user -> { + businessVO.setOwnerUserName(user.getNickname()); + MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> businessVO.setOwnerUserDeptName(dept.getName())); + }); + // 2.3 设置商机状态 + MapUtils.findAndThen(statusTypeMap, businessVO.getStatusTypeId(), statusType -> businessVO.setStatusTypeName(statusType.getName())); + MapUtils.findAndThen(statusMap, businessVO.getStatusId(), status -> businessVO.setStatusName(status.getName())); + }); } @PutMapping("/transfer") diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessExcelVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessExcelVO.java deleted file mode 100644 index a11949ecd..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessExcelVO.java +++ /dev/null @@ -1,75 +0,0 @@ -package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business; - -import com.alibaba.excel.annotation.ExcelProperty; -import lombok.Data; - -import java.math.BigDecimal; -import java.time.LocalDateTime; -import java.util.Set; - -/** - * 商机 Excel VO - * - * @author ljlleo - */ -@Data -public class CrmBusinessExcelVO { - - @ExcelProperty("主键") - private Long id; - - @ExcelProperty("商机名称") - private String name; - - @ExcelProperty("商机状态类型编号") - private Long statusTypeId; - - @ExcelProperty("商机状态编号") - private Long statusId; - - @ExcelProperty("下次联系时间") - private LocalDateTime contactNextTime; - - @ExcelProperty("客户编号") - private Long customerId; - - @ExcelProperty("预计成交日期") - private LocalDateTime dealTime; - - @ExcelProperty("商机金额") - private BigDecimal price; - - @ExcelProperty("整单折扣") - private BigDecimal discountPercent; - - @ExcelProperty("产品总金额") - private BigDecimal productPrice; - - @ExcelProperty("备注") - private String remark; - - @ExcelProperty("负责人的用户编号") - private Long ownerUserId; - - @ExcelProperty("创建时间") - private LocalDateTime createTime; - - @ExcelProperty("只读权限的用户编号数组") - private Set roUserIds; - - @ExcelProperty("读写权限的用户编号数组") - private Set rwUserIds; - - @ExcelProperty("1赢单2输单3无效") - private Integer endStatus; - - @ExcelProperty("结束时的备注") - private String endRemark; - - @ExcelProperty("最后跟进时间") - private LocalDateTime contactLastTime; - - @ExcelProperty("跟进状态") - private Integer followUpStatus; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessRespVO.java index d3b6ab2fb..41829360a 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessRespVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessRespVO.java @@ -1,69 +1,144 @@ package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business; +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; import lombok.Data; -import org.springframework.format.annotation.DateTimeFormat; +import lombok.NoArgsConstructor; import java.math.BigDecimal; import java.time.LocalDateTime; +import java.util.List; -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -@Schema(description = "管理后台 - 商机 Response VO") +@Schema(description = "管理后台 - CRM 商机 Response VO") @Data +@ExcelIgnoreUnannotated public class CrmBusinessRespVO { - @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "32129") + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32129") + @ExcelProperty("编号") private Long id; @Schema(description = "商机名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") - @NotNull(message = "商机名称不能为空") + @ExcelProperty("商机名称") private String name; - @Schema(description = "商机状态类型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "25714") - @NotNull(message = "商机状态类型不能为空") - private Long statusTypeId; - - @Schema(description = "商机状态编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") - @NotNull(message = "商机状态不能为空") - private Long statusId; - - @Schema(description = "下次联系时间") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime contactNextTime; - @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10299") - @NotNull(message = "客户不能为空") private Long customerId; - - @Schema(description = "预计成交日期") - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - private LocalDateTime dealTime; - - @Schema(description = "商机金额", example = "12371") - private Integer price; - - // TODO @ljileo:折扣使用 Integer 类型,存储时,默认 * 100;展示的时候,前端需要 / 100;避免精度丢失问题 - @Schema(description = "整单折扣") - private Integer discountPercent; - - @Schema(description = "产品总金额", example = "12025") - private BigDecimal productPrice; - - @Schema(description = "备注", example = "随便") - private String remark; - - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) - private LocalDateTime createTime; - @Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") + @ExcelProperty("客户名称") private String customerName; + @Schema(description = "跟进状态", requiredMode = Schema.RequiredMode.REQUIRED, example ="true") + @ExcelProperty("跟进状态") + private Boolean followUpStatus; + + @Schema(description = "最后跟进时间") + @ExcelProperty("最后跟进时间") + private LocalDateTime contactLastTime; + + @Schema(description = "下次联系时间") + @ExcelProperty("下次联系时间") + private LocalDateTime contactNextTime; + + @Schema(description = "负责人的用户编号", example = "25682") + @ExcelProperty("负责人的用户编号") + private Long ownerUserId; + @Schema(description = "负责人名字", example = "25682") + @ExcelProperty("负责人名字") + private String ownerUserName; + @Schema(description = "负责人部门") + @ExcelProperty("负责人部门") + private String ownerUserDeptName; + + @Schema(description = "商机状态类型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "25714") + private Long statusTypeId; @Schema(description = "状态类型名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "进行中") + @ExcelProperty("商机状态类型") private String statusTypeName; + @Schema(description = "商机状态编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") + private Long statusId; @Schema(description = "状态名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "跟进中") + @ExcelProperty("商机状态") private String statusName; + @Schema + @ExcelProperty("1赢单2输单3无效") + private Integer endStatus; + + @ExcelProperty("结束时的备注") + private String endRemark; + + @Schema(description = "预计成交日期") + @ExcelProperty("预计成交日期") + private LocalDateTime dealTime; + + @Schema(description = "产品总金额", example = "12025") + @ExcelProperty("产品总金额") + private BigDecimal totalProductPrice; + + @Schema(description = "整单折扣") + @ExcelProperty("整单折扣") + private BigDecimal discountPercent; + + @Schema(description = "商机总金额", example = "12371") + @ExcelProperty("商机总金额") + private BigDecimal totalPrice; + + @Schema(description = "备注", example = "随便") + @ExcelProperty("备注") + private String remark; + + @Schema(description = "创建人", example = "1024") + @ExcelProperty("创建人") + private String creator; + @Schema(description = "创建人名字", example = "芋道源码") + @ExcelProperty("创建人名字") + private String creatorName; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + + @Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("更新时间") + private LocalDateTime updateTime; + + @Schema(description = "产品列表") + private List products; + + @Schema(description = "产品列表") + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class Product { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "888") + private Long id; + + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529") + private Long productId; + @Schema(description = "产品名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") + private String productName; + @Schema(description = "产品条码", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529") + private String productNo; + @Schema(description = "产品单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") + private Integer productUnit; + + @Schema(description = "产品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") + private BigDecimal productPrice; + + @Schema(description = "合同价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") + private BigDecimal businessPrice; + + @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") + private Integer count; + + @Schema(description = "总计价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") + private BigDecimal totalPrice; + + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java index 0be6264eb..b9816a8fc 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java @@ -1,8 +1,7 @@ package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.crm.enums.business.CrmBizEndStatus; import cn.iocoder.yudao.module.crm.framework.operatelog.core.CrmCustomerParseFunction; +import cn.iocoder.yudao.module.crm.framework.operatelog.core.SysAdminUserParseFunction; import com.mzt.logapi.starter.annotation.DiffLogField; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; @@ -29,75 +28,68 @@ public class CrmBusinessSaveReqVO { @NotNull(message = "商机名称不能为空") private String name; - @Schema(description = "商机状态类型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "25714") - @DiffLogField(name = "商机状态") - @NotNull(message = "商机状态类型不能为空") - private Long statusTypeId; - - @Schema(description = "商机状态编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") - @DiffLogField(name = "商机状态") - @NotNull(message = "商机状态不能为空") - private Long statusId; + @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10299") + @DiffLogField(name = "客户", function = CrmCustomerParseFunction.NAME) + @NotNull(message = "客户不能为空") + private Long customerId; @Schema(description = "下次联系时间") @DiffLogField(name = "下次联系时间") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime contactNextTime; - @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10299") - @DiffLogField(name = "客户", function = CrmCustomerParseFunction.NAME) - @NotNull(message = "客户不能为空") - private Long customerId; + @Schema(description = "负责人用户编号", example = "14334") + @NotNull(message = "负责人不能为空") + @DiffLogField(name = "负责人", function = SysAdminUserParseFunction.NAME) + private Long ownerUserId; + + @Schema(description = "商机状态类型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "25714") + @DiffLogField(name = "商机状态") + @NotNull(message = "商机状态类型不能为空") + private Long statusTypeId; @Schema(description = "预计成交日期") @DiffLogField(name = "预计成交日期") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime dealTime; - @Schema(description = "商机金额", example = "12371") - @DiffLogField(name = "商机金额") - private Integer price; - @Schema(description = "整单折扣") @DiffLogField(name = "整单折扣") - private Integer discountPercent; - - @Schema(description = "产品总金额", example = "12025") - @DiffLogField(name = "产品总金额") - private BigDecimal productPrice; + @NotNull(message = "整单折扣不能为空") + private BigDecimal discountPercent; @Schema(description = "备注", example = "随便") @DiffLogField(name = "备注") private String remark; - @Schema(description = "结束状态", example = "1") - @InEnum(CrmBizEndStatus.class) - private Integer endStatus; - @Schema(description = "联系人编号", example = "110") private Long contactId; // 使用场景,在【联系人详情】添加商机时,如果需要关联两者,需要传递 contactId 字段 - // TODO @puhui999:传递 items 就行啦; @Schema(description = "产品列表") - private List productItems; + private List products; @Schema(description = "产品列表") @Data @NoArgsConstructor @AllArgsConstructor - public static class CrmBusinessProductItem { + public static class Product { @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20529") @NotNull(message = "产品编号不能为空") - private Long id; + private Long productId; + + @Schema(description = "产品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") + @NotNull(message = "产品单价不能为空") + private BigDecimal productPrice; + + @Schema(description = "合同价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "123.00") + @NotNull(message = "合同价格不能为空") + private BigDecimal businessPrice; @Schema(description = "产品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") @NotNull(message = "产品数量不能为空") private Integer count; - @Schema(description = "产品折扣") - private Integer discountPercent; - } } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java index ef0aa849a..d691a1701 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/CrmContractController.java @@ -179,7 +179,7 @@ public class CrmContractController { if (contractList.size() == 1) { List contractProductList = contractService.getContractProductListByContractId(contractList.get(0).getId()); contractProductMap = convertMap(contractProductList, CrmContractProductDO::getProductId); - productList = productService.getProductListByIds(convertSet(contractProductList, CrmContractProductDO::getProductId)); + productList = productService.getProductList(convertSet(contractProductList, CrmContractProductDO::getProductId)); } return CrmContractConvert.INSTANCE.convertList(contractList, userMap, customerList, contactMap, businessMap, contractProductMap, productList); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/CrmProductController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/CrmProductController.java index 94774373d..91d31de7a 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/CrmProductController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/CrmProductController.java @@ -1,16 +1,17 @@ package cn.iocoder.yudao.module.crm.controller.admin.product; import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.SetUtils; +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductPageReqVO; import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductRespVO; import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductSaveReqVO; -import cn.iocoder.yudao.module.crm.convert.product.CrmProductConvert; import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductCategoryDO; import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO; import cn.iocoder.yudao.module.crm.service.product.CrmProductCategoryService; @@ -34,10 +35,9 @@ import java.util.Map; import java.util.stream.Stream; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; +import static java.util.Collections.singletonList; @Tag(name = "管理后台 - CRM 产品") @RestController @@ -49,6 +49,7 @@ public class CrmProductController { private CrmProductService productService; @Resource private CrmProductCategoryService productCategoryService; + @Resource private AdminUserApi adminUserApi; @@ -82,21 +83,30 @@ public class CrmProductController { @PreAuthorize("@ss.hasPermission('crm:product:query')") public CommonResult getProduct(@RequestParam("id") Long id) { CrmProductDO product = productService.getProduct(id); + return success(buildProductDetail(product)); + } + + private CrmProductRespVO buildProductDetail(CrmProductDO product) { if (product == null) { - return success(null); + return null; } - Map userMap = adminUserApi.getUserMap( - SetUtils.asSet(Long.valueOf(product.getCreator()), product.getOwnerUserId())); - CrmProductCategoryDO category = productCategoryService.getProductCategory(product.getCategoryId()); - return success(CrmProductConvert.INSTANCE.convert(product, userMap, category)); + return buildProductDetailList(singletonList(product)).get(0); + } + + @GetMapping("/simple-list") + @Operation(summary = "获得产品精简列表", description = "只包含被开启的产品,主要用于前端的下拉选项") + public CommonResult> getProductSimpleList() { + List list = productService.getProductListByStatus(CommonStatusEnum.ENABLE.getStatus()); + return success(convertList(list, product -> new CrmProductRespVO().setId(product.getId()).setName(product.getName()) + .setUnit(product.getUnit()).setNo(product.getNo()).setPrice(product.getPrice()))); } @GetMapping("/page") @Operation(summary = "获得产品分页") @PreAuthorize("@ss.hasPermission('crm:product:query')") public CommonResult> getProductPage(@Valid CrmProductPageReqVO pageVO) { - PageResult pageResult = productService.getProductPage(pageVO, getLoginUserId()); - return success(new PageResult<>(getProductDetailList(pageResult.getList()), pageResult.getTotal())); + PageResult pageResult = productService.getProductPage(pageVO); + return success(new PageResult<>(buildProductDetailList(pageResult.getList()), pageResult.getTotal())); } @GetMapping("/export-excel") @@ -106,21 +116,30 @@ public class CrmProductController { public void exportProductExcel(@Valid CrmProductPageReqVO exportReqVO, HttpServletResponse response) throws IOException { exportReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = productService.getProductPage(exportReqVO, getLoginUserId()).getList(); + List list = productService.getProductPage(exportReqVO).getList(); // 导出 Excel ExcelUtils.write(response, "产品.xls", "数据", CrmProductRespVO.class, - getProductDetailList(list)); + buildProductDetailList(list)); } - private List getProductDetailList(List list) { + private List buildProductDetailList(List list) { if (CollUtil.isEmpty(list)) { return Collections.emptyList(); } + // 1.1 获得用户信息 Map userMap = adminUserApi.getUserMap( convertSetByFlatMap(list, user -> Stream.of(Long.valueOf(user.getCreator()), user.getOwnerUserId()))); - List productCategoryList = productCategoryService.getProductCategoryList( + // 1.2 获得分类信息 + Map categoryMap = productCategoryService.getProductCategoryMap( convertSet(list, CrmProductDO::getCategoryId)); - return CrmProductConvert.INSTANCE.convertList(list, userMap, productCategoryList); + // 2. 拼接数据 + return BeanUtils.toBean(list, CrmProductRespVO.class, productVO -> { + // 2.1 设置用户信息 + MapUtils.findAndThen(userMap, productVO.getOwnerUserId(), user -> productVO.setOwnerUserName(user.getNickname())); + MapUtils.findAndThen(userMap, Long.valueOf(productVO.getCreator()), user -> productVO.setCreatorName(user.getNickname())); + // 2.2 设置分类名称 + MapUtils.findAndThen(categoryMap, productVO.getCategoryId(), category -> productVO.setCategoryName(category.getName())); + }); } } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/vo/product/CrmProductRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/vo/product/CrmProductRespVO.java index ceca3e5a0..1f659aa77 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/vo/product/CrmProductRespVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/vo/product/CrmProductRespVO.java @@ -8,6 +8,7 @@ import com.alibaba.excel.annotation.ExcelProperty; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import java.math.BigDecimal; import java.time.LocalDateTime; @Schema(description = "管理后台 - CRM 产品 Response VO") @@ -34,7 +35,7 @@ public class CrmProductRespVO { @Schema(description = "价格, 单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") @ExcelProperty("价格,单位:分") - private Long price; + private BigDecimal price; @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "上架") @ExcelProperty(value = "单位", converter = DictConvert.class) diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/vo/product/CrmProductSaveReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/vo/product/CrmProductSaveReqVO.java index 01b2ae443..ef6d5824d 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/vo/product/CrmProductSaveReqVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/product/vo/product/CrmProductSaveReqVO.java @@ -7,6 +7,8 @@ import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; import lombok.Data; +import java.math.BigDecimal; + @Schema(description = "管理后台 - CRM 产品创建/修改 Request VO") @Data public class CrmProductSaveReqVO { @@ -28,10 +30,10 @@ public class CrmProductSaveReqVO { @DiffLogField(name = "单位", function = CrmProductUnitParseFunction.NAME) private Integer unit; - @Schema(description = "价格, 单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") + @Schema(description = "价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "8911") @NotNull(message = "价格不能为空") @DiffLogField(name = "价格") - private Long price; + private BigDecimal price; @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "上架") @NotNull(message = "状态不能为空") diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessConvert.java index d7f990043..c86726412 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessConvert.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessConvert.java @@ -1,14 +1,8 @@ package cn.iocoder.yudao.module.crm.convert.business; -import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessRespVO; import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO; import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; import org.mapstruct.Mapper; @@ -16,9 +10,6 @@ import org.mapstruct.Mapping; import org.mapstruct.factory.Mappers; import java.util.List; -import java.util.Map; - -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; /** * 商机 Convert @@ -33,20 +24,6 @@ public interface CrmBusinessConvert { @Mapping(target = "bizId", source = "reqVO.id") CrmPermissionTransferReqBO convert(CrmBusinessTransferReqVO reqVO, Long userId); - default PageResult convertPage(PageResult pageResult, List customerList, - List statusTypeList, List statusList) { - PageResult voPageResult = BeanUtils.toBean(pageResult, CrmBusinessRespVO.class); - // 拼接关联字段 - Map customerMap = convertMap(customerList, CrmCustomerDO::getId, CrmCustomerDO::getName); - Map statusTypeMap = convertMap(statusTypeList, CrmBusinessStatusTypeDO::getId, CrmBusinessStatusTypeDO::getName); - Map statusMap = convertMap(statusList, CrmBusinessStatusDO::getId, CrmBusinessStatusDO::getName); - voPageResult.getList().forEach(type -> type - .setCustomerName(customerMap.get(type.getCustomerId())) - .setStatusTypeName(statusTypeMap.get(type.getStatusTypeId())) - .setStatusName(statusMap.get(type.getStatusId()))); - return voPageResult; - } - @Mapping(target = "id", source = "reqBO.bizId") CrmBusinessDO convert(CrmUpdateFollowUpReqBO reqBO); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/product/CrmProductConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/product/CrmProductConvert.java deleted file mode 100644 index 2165a208f..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/product/CrmProductConvert.java +++ /dev/null @@ -1,46 +0,0 @@ -package cn.iocoder.yudao.module.crm.convert.product; - -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.framework.common.util.collection.MapUtils; -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductRespVO; -import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductCategoryDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO; -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -import java.util.List; -import java.util.Map; -import java.util.Optional; - -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; - -/** - * 产品 Convert - * - * @author ZanGe丶 - */ -@Mapper -public interface CrmProductConvert { - - CrmProductConvert INSTANCE = Mappers.getMapper(CrmProductConvert.class); - - default List convertList(List list, - Map userMap, - List categoryList) { - Map categoryMap = convertMap(categoryList, CrmProductCategoryDO::getId); - return CollectionUtils.convertList(list, - product -> convert(product, userMap, categoryMap.get(product.getCategoryId()))); - } - - default CrmProductRespVO convert(CrmProductDO product, - Map userMap, CrmProductCategoryDO category) { - CrmProductRespVO productVO = BeanUtils.toBean(product, CrmProductRespVO.class); - Optional.ofNullable(category).ifPresent(c -> productVO.setCategoryName(c.getName())); - MapUtils.findAndThen(userMap, productVO.getOwnerUserId(), user -> productVO.setOwnerUserName(user.getNickname())); - MapUtils.findAndThen(userMap, Long.valueOf(productVO.getCreator()), user -> productVO.setCreatorName(user.getNickname())); - return productVO; - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessDO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessDO.java index 3a543712b..803f37a38 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessDO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessDO.java @@ -8,10 +8,11 @@ import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; +import java.math.BigDecimal; import java.time.LocalDateTime; /** - * 商机 DO + * CRM 商机 DO * * @author ljlleo */ @@ -26,7 +27,7 @@ import java.time.LocalDateTime; public class CrmBusinessDO extends BaseDO { /** - * 主键 + * 编号 */ @TableId private Long id; @@ -34,6 +35,33 @@ public class CrmBusinessDO extends BaseDO { * 商机名称 */ private String name; + /** + * 客户编号 + * + * 关联 {@link CrmCustomerDO#getId()} + */ + private Long customerId; + + /** + * 跟进状态 + */ + private Boolean followUpStatus; + /** + * 最后跟进时间 + */ + private LocalDateTime contactLastTime; + /** + * 下次联系时间 + */ + private LocalDateTime contactNextTime; + + /** + * 负责人的用户编号 + * + * 关联 AdminUserDO 的 id 字段 + */ + private Long ownerUserId; + /** * 商机状态类型编号 * @@ -46,39 +74,6 @@ public class CrmBusinessDO extends BaseDO { * 关联 {@link CrmBusinessStatusDO#getId()} */ private Long statusId; - /** - * 下次联系时间 - */ - private LocalDateTime contactNextTime; - /** - * 客户编号 - * - * TODO @ljileo:这个字段,后续要写下关联的实体哈 - * 关联 {@link CrmCustomerDO#getId()} - */ - private Long customerId; - /** - * 预计成交日期 - */ - private LocalDateTime dealTime; - /** - * 商机金额 - * - */ - private Integer price; - /** - * 整单折扣 - * - */ - private Integer discountPercent; - /** - * 产品总金额,单位:分 - */ - private Integer productPrice; - /** - * 备注 - */ - private String remark; /** * 结束状态 * @@ -89,20 +84,28 @@ public class CrmBusinessDO extends BaseDO { * 结束时的备注 */ private String endRemark; - /** - * 最后跟进时间 - */ - private LocalDateTime contactLastTime; - /** - * 跟进状态 - */ - private Boolean followUpStatus; /** - * 负责人的用户编号 - * - * 关联 AdminUserDO 的 id 字段 + * 预计成交日期 */ - private Long ownerUserId; + private LocalDateTime dealTime; + /** + * 产品总金额,单位:元 + * + * productPrice = ∑({@link CrmBusinessProductDO#getTotalPrice()}) + */ + private BigDecimal totalProductPrice; + /** + * 整单折扣,百分比 + */ + private BigDecimal discountPercent; + /** + * 商机总金额,单位:元 + */ + private BigDecimal totalPrice; + /** + * 备注 + */ + private String remark; } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessProductDO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessProductDO.java index 79d6a2a7b..6adc7e42e 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessProductDO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessProductDO.java @@ -7,9 +7,13 @@ import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; +import java.math.BigDecimal; + /** * 商机产品关联表 DO * + * CrmBusinessDO : CrmBusinessProductDO = 1 : N + * * @author lzxhqs */ @TableName("crm_business_product") @@ -40,24 +44,24 @@ public class CrmBusinessProductDO extends BaseDO { */ private Long productId; /** - * 产品单价 + * 产品单价,单位:元 + * + * 冗余 {@link CrmProductDO#getPrice()} */ - private Integer price; + private BigDecimal productPrice; /** - * 销售价格, 单位:分 + * 合同价格, 单位:元 */ - private Integer salesPrice; + private BigDecimal businessPrice; /** * 数量 */ - private Integer count; + private BigDecimal count; /** - * 折扣 + * 总计价格,单位:元 + * + * totalPrice = businessPrice * count */ - private Integer discountPercent; - /** - * 总计价格(折扣后价格) - */ - private Integer totalPrice; + private BigDecimal totalPrice; } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/clue/CrmClueDO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/clue/CrmClueDO.java index 48e600be6..3af6feec4 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/clue/CrmClueDO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/clue/CrmClueDO.java @@ -11,7 +11,7 @@ import lombok.*; import java.time.LocalDateTime; /** - * 线索 DO + * CRM 线索 DO * * @author Wanwan */ diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/product/CrmProductDO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/product/CrmProductDO.java index a3c56ccc9..caeeb53d2 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/product/CrmProductDO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/product/CrmProductDO.java @@ -8,6 +8,8 @@ import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; +import java.math.BigDecimal; + /** * CRM 产品 DO * @@ -43,9 +45,9 @@ public class CrmProductDO extends BaseDO { */ private Integer unit; /** - * 价格,单位:分 + * 价格,单位:元 */ - private Integer price; + private BigDecimal price; /** * 状态 * diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/package-info.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/package-info.java deleted file mode 100644 index 72863e1f4..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * 商机(销售机会) - */ -package cn.iocoder.yudao.module.crm.dal.mysql.business; diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/package-info.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/package-info.java deleted file mode 100644 index 6cb7d4be2..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contact/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * 联系人 - */ -package cn.iocoder.yudao.module.crm.dal.mysql.contact; diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/product/CrmProductMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/product/CrmProductMapper.java index 30a07eec2..4d1d61809 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/product/CrmProductMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/product/CrmProductMapper.java @@ -5,10 +5,10 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductPageReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO; -import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; -import cn.iocoder.yudao.module.crm.util.CrmQueryWrapperUtils; import org.apache.ibatis.annotations.Mapper; +import java.util.List; + /** * CRM 产品 Mapper * @@ -17,21 +17,23 @@ import org.apache.ibatis.annotations.Mapper; @Mapper public interface CrmProductMapper extends BaseMapperX { - default PageResult selectPage(CrmProductPageReqVO reqVO, Long userId) { - MPJLambdaWrapperX query = new MPJLambdaWrapperX<>(); - // 拼接数据权限的查询条件 - CrmQueryWrapperUtils.appendPermissionCondition(query, CrmBizTypeEnum.CRM_PRODUCT.getType(), - CrmProductDO::getId, userId, null, Boolean.FALSE); - // 拼接自身的查询条件 - query.selectAll(CrmProductDO.class) + default PageResult selectPage(CrmProductPageReqVO reqVO) { + return selectPage(reqVO, new MPJLambdaWrapperX() .likeIfPresent(CrmProductDO::getName, reqVO.getName()) .eqIfPresent(CrmProductDO::getStatus, reqVO.getStatus()) - .orderByDesc(CrmProductDO::getId); - return selectJoinPage(reqVO, CrmProductDO.class, query); + .orderByDesc(CrmProductDO::getId)); } default CrmProductDO selectByNo(String no) { return selectOne(CrmProductDO::getNo, no); } + default Long selectCountByCategoryId(Long categoryId) { + return selectCount(CrmProductDO::getCategoryId, categoryId); + } + + default List selectListByStatus(Integer status) { + return selectList(CrmProductDO::getStatus, status); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java index 683070d02..c7dba0101 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java @@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusi import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessSaveReqVO; import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; +import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO; import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; import cn.iocoder.yudao.module.crm.service.business.bo.CrmBusinessUpdateProductReqBO; @@ -90,6 +91,14 @@ public interface CrmBusinessService { */ List getBusinessList(Collection ids); + /** + * 获得指定商机编号的产品列表 + * + * @param businessId 商机编号 + * @return 商机产品列表 + */ + List getBusinessProductListByBusinessId(Long businessId); + /** * 获得商机分页 * diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java index 535578fd2..15dd00ee2 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java @@ -2,9 +2,7 @@ package cn.iocoder.yudao.module.crm.service.business; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; -import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO; @@ -14,7 +12,6 @@ import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessConvert; import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO; import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactBusinessDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO; import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessMapper; import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessProductMapper; import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; @@ -36,14 +33,14 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; +import java.math.BigDecimal; import java.util.Collection; import java.util.List; -import java.util.Map; -import java.util.Set; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.BUSINESS_CONTRACT_EXISTS; +import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.BUSINESS_NOT_EXISTS; import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*; /** @@ -75,27 +72,29 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_CREATE_SUB_TYPE, bizNo = "{{#business.id}}", success = CRM_BUSINESS_CREATE_SUCCESS) public Long createBusiness(CrmBusinessSaveReqVO createReqVO, Long userId) { - createReqVO.setId(null); - // 1. 插入商机 + // 1.1 校验产品项的有效性 + List businessProducts = validateBusinessProducts(createReqVO.getProducts()); + // 1.2 TODO 芋艿:校验关联字 + + // 2.1 插入商机 CrmBusinessDO business = BeanUtils.toBean(createReqVO, CrmBusinessDO.class).setOwnerUserId(userId); + calculateTotalPrice(business, businessProducts); businessMapper.insert(business); - // 1.2 插入商机关联商品 - if (CollUtil.isNotEmpty(createReqVO.getProductItems())) { // 如果有的话 - List productList = buildBusinessProductList(createReqVO.getProductItems(), business.getId()); - businessProductMapper.insertBatch(productList); - // 更新合同商品总金额 - businessMapper.updateById(new CrmBusinessDO().setId(business.getId()).setProductPrice( - getSumValue(productList, CrmBusinessProductDO::getTotalPrice, Integer::sum))); + // 2.2 插入商机关联商品 + if (CollUtil.isNotEmpty(businessProducts)) { + businessProducts.forEach(item -> item.setBusinessId(business.getId())); + businessProductMapper.insertBatch(businessProducts); } + // TODO @puhui999:在联系人的详情页,如果直接【新建商机】,则需要关联下。这里要搞个 CrmContactBusinessDO 表 createContactBusiness(business.getId(), createReqVO.getContactId()); - // 2. 创建数据权限 + // 3. 创建数据权限 // 设置当前操作的人为负责人 permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType()) .setBizId(business.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); - // 3. 记录操作日志上下文 + // 4. 记录操作日志上下文 LogRecordContext.putVariable("business", business); return business.getId(); } @@ -114,15 +113,18 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { success = CRM_BUSINESS_UPDATE_SUCCESS) @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) public void updateBusiness(CrmBusinessSaveReqVO updateReqVO) { - // 1. 校验存在 + // 1.1 校验存在 CrmBusinessDO oldBusiness = validateBusinessExists(updateReqVO.getId()); + // 1.2 校验产品项的有效性 + List businessProducts = validateBusinessProducts(updateReqVO.getProducts()); + // 1.3 TODO 芋艿:校验关联字 // 2.1 更新商机 CrmBusinessDO updateObj = BeanUtils.toBean(updateReqVO, CrmBusinessDO.class); + calculateTotalPrice(updateObj, businessProducts); businessMapper.updateById(updateObj); // 2.2 更新商机关联商品 - List productList = buildBusinessProductList(updateReqVO.getProductItems(), updateObj.getId()); - updateBusinessProduct(productList, updateObj.getId()); + updateBusinessProduct(updateObj.getId(), businessProducts); // TODO @商机待定:如果状态发生变化,插入商机状态变更记录表 // 3. 记录操作日志上下文 @@ -130,6 +132,37 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { LogRecordContext.putVariable("businessName", oldBusiness.getName()); } + private void updateBusinessProduct(Long id, List newList) { + List oldList = businessProductMapper.selectListByBusinessId(id); + List> diffList = diffList(oldList, newList, // id 不同,就认为是不同的记录 + (oldVal, newVal) -> oldVal.getId().equals(newVal.getId())); + if (CollUtil.isNotEmpty(diffList.get(0))) { + diffList.get(0).forEach(o -> o.setBusinessId(id)); + businessProductMapper.insertBatch(diffList.get(0)); + } + if (CollUtil.isNotEmpty(diffList.get(1))) { + businessProductMapper.updateBatch(diffList.get(1)); + } + if (CollUtil.isNotEmpty(diffList.get(2))) { + businessProductMapper.deleteBatchIds(convertSet(diffList.get(2), CrmBusinessProductDO::getId)); + } + } + + private List validateBusinessProducts(List list) { + // 1. 校验产品存在 + productService.validProductList(convertSet(list, CrmBusinessSaveReqVO.Product::getProductId)); + // 2. 转化为 CrmBusinessProductDO 列表 + return convertList(list, o -> BeanUtils.toBean(o, CrmBusinessProductDO.class, item -> { + item.setTotalPrice(MoneyUtils.priceMultiply(item.getBusinessPrice(), item.getCount())); + })); + } + + private void calculateTotalPrice(CrmBusinessDO business, List businessProducts) { + business.setTotalProductPrice(getSumValue(businessProducts, CrmBusinessProductDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO)); + BigDecimal discountPrice = MoneyUtils.priceMultiplyPercent(business.getTotalProductPrice(), business.getDiscountPercent()); + business.setTotalPrice(business.getTotalProductPrice().subtract(discountPrice)); + } + @Override public void updateBusinessFollowUpBatch(List updateFollowUpReqBOList) { businessMapper.updateBatch(CrmBusinessConvert.INSTANCE.convertList(updateFollowUpReqBOList)); @@ -155,44 +188,6 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { LogRecordContext.putVariable("businessName", business.getName()); } - private void updateBusinessProduct(List newProductList, Long businessId) { - List oldProducts = businessProductMapper.selectListByBusinessId(businessId); - List> diffList = CollectionUtils.diffList(oldProducts, newProductList, (oldValue, newValue) -> { - boolean condition = ObjectUtil.equal(oldValue.getProductId(), newValue.getProductId()); - if (condition) { - newValue.setId(oldValue.getId()); // 更新需要原始编号 - } - return condition; - }); - if (CollUtil.isNotEmpty(diffList.get(0))) { - businessProductMapper.insertBatch(diffList.get(0)); - } - if (CollUtil.isNotEmpty(diffList.get(1))) { - businessProductMapper.updateBatch(diffList.get(1)); - } - if (CollUtil.isNotEmpty(diffList.get(2))) { - businessProductMapper.deleteBatchIds(convertSet(diffList.get(2), CrmBusinessProductDO::getId)); - } - } - - private List buildBusinessProductList(List productItems, - Long businessId) { - // 校验商品存在 - Set productIds = convertSet(productItems, CrmBusinessSaveReqVO.CrmBusinessProductItem::getId); - List productList = productService.getProductList(productIds); - if (CollUtil.isEmpty(productIds) || productList.size() != productIds.size()) { - throw exception(PRODUCT_NOT_EXISTS); - } - Map productMap = convertMap(productList, CrmProductDO::getId); - return convertList(productItems, productItem -> { - CrmProductDO product = productMap.get(productItem.getId()); - return BeanUtils.toBean(product, CrmBusinessProductDO.class) - .setId(null).setProductId(productItem.getId()).setBusinessId(businessId) - .setCount(productItem.getCount()).setDiscountPercent(productItem.getDiscountPercent()) - .setTotalPrice(MoneyUtils.calculator(product.getPrice(), productItem.getCount(), productItem.getDiscountPercent())); - }); - } - /** * 删除校验合同是关联合同 * @@ -235,10 +230,10 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @Override public void updateBusinessProduct(CrmBusinessUpdateProductReqBO updateProductReqBO) { - // 更新商机关联商品 - List productList = buildBusinessProductList( - BeanUtils.toBean(updateProductReqBO.getProductItems(), CrmBusinessSaveReqVO.CrmBusinessProductItem.class), updateProductReqBO.getId()); - updateBusinessProduct(productList, updateProductReqBO.getId()); + // 更新商机关联商品 TODO yunai +// List productList = buildBusinessProductList( +// BeanUtils.toBean(updateProductReqBO.getProductItems(), CrmBusinessSaveReqVO.Product.class), updateProductReqBO.getId()); +// updateBusinessProduct(productList, updateProductReqBO.getId()); } //======================= 查询相关 ======================= @@ -265,6 +260,11 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { return businessMapper.selectBatchIds(ids); } + @Override + public List getBusinessProductListByBusinessId(Long businessId) { + return businessProductMapper.selectListByBusinessId(businessId); + } + @Override public PageResult getBusinessPage(CrmBusinessPageReqVO pageReqVO, Long userId) { return businessMapper.selectPage(pageReqVO, userId); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusService.java index a2fc2d18d..d9128b429 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusService.java @@ -5,11 +5,13 @@ import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusine import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusQueryVO; import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusSaveReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; - import jakarta.validation.Valid; import java.util.Collection; import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; /** * 商机状态 Service 接口 @@ -74,4 +76,14 @@ public interface CrmBusinessStatusService { */ List getBusinessStatusList(Collection ids); + /** + * 获得商机状态 Map + * + * @param ids 编号数组 + * @return 商机状态 Map + */ + default Map getBusinessStatusMap(Collection ids) { + return convertMap(getBusinessStatusList(ids), CrmBusinessStatusDO::getId); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusServiceImpl.java index 2e49e99d7..b838fdc6f 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusServiceImpl.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.crm.service.business; +import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusPageReqVO; @@ -13,6 +14,7 @@ import org.springframework.validation.annotation.Validated; import jakarta.annotation.Resource; import java.util.Collection; +import java.util.Collections; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -80,6 +82,9 @@ public class CrmBusinessStatusServiceImpl implements CrmBusinessStatusService { @Override public List getBusinessStatusList(Collection ids) { + if (CollUtil.isEmpty(ids)) { + return Collections.emptyList(); + } return businessStatusMapper.selectBatchIds(ids); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusTypeService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusTypeService.java index 20509994e..a48ff0503 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusTypeService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusTypeService.java @@ -9,6 +9,9 @@ import jakarta.validation.Valid; import java.util.Collection; import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; /** * 商机状态类型 Service 接口 @@ -72,4 +75,14 @@ public interface CrmBusinessStatusTypeService { */ List getBusinessStatusTypeList(Collection ids); + /** + * 获得商机状态类型 Map + * + * @param ids 编号数组 + * @return 商机状态类型 Map + */ + default Map getBusinessStatusTypeMap(Collection ids) { + return convertMap(getBusinessStatusTypeList(ids), CrmBusinessStatusTypeDO::getId); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusTypeServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusTypeServiceImpl.java index d9845976b..85d30e8ce 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusTypeServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusTypeServiceImpl.java @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.crm.service.business; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypePageReqVO; import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeQueryVO; import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeSaveReqVO; @@ -11,19 +10,18 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO; import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessStatusMapper; import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessStatusTypeMapper; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; -import jakarta.annotation.Resource; - import java.util.Collection; +import java.util.Collections; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.BUSINESS_STATUS_TYPE_NOT_EXISTS; import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.BUSINESS_STATUS_TYPE_NAME_EXISTS; +import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.BUSINESS_STATUS_TYPE_NOT_EXISTS; /** * 商机状态类型 Service 实现类 @@ -126,6 +124,9 @@ public class CrmBusinessStatusTypeServiceImpl implements CrmBusinessStatusTypeSe @Override public List getBusinessStatusTypeList(Collection ids) { + if (CollUtil.isEmpty(ids)) { + return Collections.emptyList(); + } return businessStatusTypeMapper.selectBatchIds(ids); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java index 71b9446e4..cdd888544 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java @@ -184,7 +184,8 @@ public class CrmContractServiceImpl implements CrmContractService { return BeanUtils.toBean(product, CrmContractProductDO.class) .setId(null).setProductId(productItem.getId()).setContractId(contractId) .setCount(productItem.getCount()).setDiscountPercent(productItem.getDiscountPercent()) - .setTotalPrice(MoneyUtils.calculator(product.getPrice(), productItem.getCount(), productItem.getDiscountPercent())); + // TODO 芋艿:这里临时注释掉 + .setTotalPrice(MoneyUtils.calculator(null, productItem.getCount(), productItem.getDiscountPercent())); }); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductCategoryService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductCategoryService.java index 56974da11..c68c0cf77 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductCategoryService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductCategoryService.java @@ -3,10 +3,13 @@ package cn.iocoder.yudao.module.crm.service.product; import cn.iocoder.yudao.module.crm.controller.admin.product.vo.category.CrmProductCategoryCreateReqVO; import cn.iocoder.yudao.module.crm.controller.admin.product.vo.category.CrmProductCategoryListReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductCategoryDO; - import jakarta.validation.Valid; + import java.util.Collection; import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; /** * CRM 产品分类 Service 接口 @@ -61,4 +64,14 @@ public interface CrmProductCategoryService { */ List getProductCategoryList(Collection ids); + /** + * 获得产品分类 Map + * + * @param ids 编号数组 + * @return 产品分类 Map + */ + default Map getProductCategoryMap(Collection ids) { + return convertMap(getProductCategoryList(ids), CrmProductCategoryDO::getId); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductService.java index 6d2dd4943..9379734ef 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductService.java @@ -8,6 +8,9 @@ import jakarta.validation.Valid; import java.util.Collection; import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; /** * CRM 产品 Service 接口 @@ -54,28 +57,46 @@ public interface CrmProductService { */ List getProductList(Collection ids); + /** + * 获得产品 Map + * + * @param ids 编号 + * @return 产品 Map + */ + default Map getProductMap(Collection ids) { + return convertMap(getProductList(ids), CrmProductDO::getId); + } + /** * 获得产品分页 * * @param pageReqVO 分页查询 * @return 产品分页 */ - PageResult getProductPage(CrmProductPageReqVO pageReqVO, Long userId); + PageResult getProductPage(CrmProductPageReqVO pageReqVO); /** - * 获得产品 + * 获得产品数量 * * @param categoryId 分类编号 * @return 产品 */ - CrmProductDO getProductByCategoryId(Long categoryId); + Long getProductByCategoryId(Long categoryId); /** - * 获得产品列表 + * 获得指定状态的产品列表 * - * @param ids 产品编号 + * @param status 状态 * @return 产品列表 */ - List getProductListByIds(Collection ids); + List getProductListByStatus(Integer status); + + /** + * 校验产品们的有效性 + * + * @param ids 编号数组 + * @return 产品列表 + */ + List validProductList(Collection ids); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductServiceImpl.java index 95205524e..c44bc6b9e 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/product/CrmProductServiceImpl.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.crm.service.product; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.collection.ListUtil; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductPageReqVO; @@ -15,7 +15,6 @@ import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPerm import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.mzt.logapi.context.LogRecordContext; import com.mzt.logapi.service.impl.DiffParseFunction; import com.mzt.logapi.starter.annotation.LogRecord; @@ -27,8 +26,10 @@ import org.springframework.validation.annotation.Validated; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Map; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*; @@ -138,25 +139,41 @@ public class CrmProductServiceImpl implements CrmProductService { } @Override - public List getProductList(Collection ids) { + public PageResult getProductPage(CrmProductPageReqVO pageReqVO) { + return productMapper.selectPage(pageReqVO); + } + + @Override + public Long getProductByCategoryId(Long categoryId) { + return productMapper.selectCountByCategoryId(categoryId); + } + + @Override + public List getProductListByStatus(Integer status) { + return productMapper.selectListByStatus(status); + } + + @Override + public List validProductList(Collection ids) { if (CollUtil.isEmpty(ids)) { - return ListUtil.empty(); + return Collections.emptyList(); } - return productMapper.selectBatchIds(ids); + List list = productMapper.selectBatchIds(ids); + Map productMap = convertMap(list, CrmProductDO::getId); + for (Long id : ids) { + CrmProductDO product = productMap.get(id); + if (productMap.get(id) == null) { + throw exception(PRODUCT_NOT_EXISTS); + } + if (CommonStatusEnum.isDisable(product.getStatus())) { + throw exception(PRODUCT_NOT_ENABLE, product.getName()); + } + } + return list; } @Override - public PageResult getProductPage(CrmProductPageReqVO pageReqVO, Long userId) { - return productMapper.selectPage(pageReqVO, userId); - } - - @Override - public CrmProductDO getProductByCategoryId(Long categoryId) { - return productMapper.selectOne(new LambdaQueryWrapper().eq(CrmProductDO::getCategoryId, categoryId)); - } - - @Override - public List getProductListByIds(Collection ids) { + public List getProductList(Collection ids) { if (CollUtil.isEmpty(ids)) { return Collections.emptyList(); } From f76a7cd94125022cf422e3e150f349e5cd4eb8e9 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 21 Feb 2024 20:10:13 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E2=9C=A8=20CRM=EF=BC=9A=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E5=95=86=E6=9C=BA=E7=8A=B6=E6=80=81=E7=9A=84=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=EF=BC=8C=E4=B8=8D=E8=B0=83=E6=95=B4=E8=A1=A8?= =?UTF-8?q?=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/crm/enums/ErrorCodeConstants.java | 15 +- .../admin/business/CrmBusinessController.http | 32 ---- .../admin/business/CrmBusinessController.java | 3 +- .../business/CrmBusinessStatusController.java | 118 +++++++++++++ .../CrmBusinessStatusTypeController.java | 141 ---------------- .../vo/business/CrmBusinessRespVO.java | 6 +- .../vo/business/CrmBusinessSaveReqVO.java | 6 +- .../vo/status/CrmBusinessStatusPageReqVO.java | 15 -- .../vo/status/CrmBusinessStatusQueryVO.java | 19 --- .../vo/status/CrmBusinessStatusRespVO.java | 52 ++++-- .../vo/status/CrmBusinessStatusSaveReqVO.java | 48 ++++-- .../type/CrmBusinessStatusTypePageReqVO.java | 15 -- .../vo/type/CrmBusinessStatusTypeQueryVO.java | 19 --- .../vo/type/CrmBusinessStatusTypeRespVO.java | 44 ----- .../type/CrmBusinessStatusTypeSaveReqVO.java | 29 ---- .../business/CrmBusinessStatusConvert.java | 25 --- .../CrmBusinessStatusTypeConvert.java | 44 ----- .../dataobject/business/CrmBusinessDO.java | 2 +- .../business/CrmBusinessStatusTypeDO.java | 11 +- .../dal/mysql/business/CrmBusinessMapper.java | 4 + .../business/CrmBusinessStatusMapper.java | 22 +-- .../business/CrmBusinessStatusTypeMapper.java | 27 +-- .../service/business/CrmBusinessService.java | 8 + .../business/CrmBusinessServiceImpl.java | 5 + .../business/CrmBusinessStatusService.java | 53 ++++-- .../CrmBusinessStatusServiceImpl.java | 155 ++++++++++++++---- .../CrmBusinessStatusTypeService.java | 88 ---------- .../CrmBusinessStatusTypeServiceImpl.java | 133 --------------- 28 files changed, 385 insertions(+), 754 deletions(-) delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.http create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessStatusController.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessStatusTypeController.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/status/CrmBusinessStatusPageReqVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/status/CrmBusinessStatusQueryVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/type/CrmBusinessStatusTypePageReqVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/type/CrmBusinessStatusTypeQueryVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/type/CrmBusinessStatusTypeRespVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/type/CrmBusinessStatusTypeSaveReqVO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessStatusConvert.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessStatusTypeConvert.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusTypeService.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusTypeServiceImpl.java diff --git a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java index a484c778f..61ea1ede9 100644 --- a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java +++ b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/ErrorCodeConstants.java @@ -22,8 +22,6 @@ public interface ErrorCodeConstants { ErrorCode BUSINESS_NOT_EXISTS = new ErrorCode(1_020_002_000, "商机不存在"); ErrorCode BUSINESS_CONTRACT_EXISTS = new ErrorCode(1_020_002_001, "商机已关联合同,不能删除"); - // TODO @lilleo:商机状态、商机类型,都单独错误码段 - // ========== 联系人管理 1-020-003-000 ========== ErrorCode CONTACT_NOT_EXISTS = new ErrorCode(1_020_003_000, "联系人不存在"); ErrorCode CONTACT_BUSINESS_LINK_NOT_EXISTS = new ErrorCode(1_020_003_001, "联系人商机关联不存在"); @@ -77,12 +75,11 @@ public interface ErrorCodeConstants { ErrorCode PRODUCT_CATEGORY_PARENT_NOT_FIRST_LEVEL = new ErrorCode(1_020_009_004, "父分类不能是二级分类"); ErrorCode product_CATEGORY_EXISTS_CHILDREN = new ErrorCode(1_020_009_005, "存在子分类,无法删除"); - // ========== 商机状态类型 1_020_010_000 ========== - ErrorCode BUSINESS_STATUS_TYPE_NOT_EXISTS = new ErrorCode(1_020_010_000, "商机状态类型不存在"); - ErrorCode BUSINESS_STATUS_TYPE_NAME_EXISTS = new ErrorCode(1_020_010_001, "商机状态类型名称已存在"); - - // ========== 商机状态 1_020_011_000 ========== - ErrorCode BUSINESS_STATUS_NOT_EXISTS = new ErrorCode(1_020_011_000, "商机状态不存在"); + // ========== 商机状态 1_020_010_000 ========== + ErrorCode BUSINESS_STATUS_TYPE_NOT_EXISTS = new ErrorCode(1_020_010_000, "商机状态组不存在"); + ErrorCode BUSINESS_STATUS_TYPE_NAME_EXISTS = new ErrorCode(1_020_010_001, "商机状态组的名称已存在"); + ErrorCode BUSINESS_STATUS_UPDATE_FAIL_USED = new ErrorCode(1_020_010_002, "已经被使用的商机状态组,无法进行更新"); + ErrorCode BUSINESS_STATUS_DELETE_FAIL_USED = new ErrorCode(1_020_010_002, "已经被使用的商机状态组,无法进行删除"); // ========== 客户公海规则设置 1_020_012_000 ========== ErrorCode CUSTOMER_POOL_CONFIG_NOT_EXISTS_OR_DISABLED = new ErrorCode(1_020_012_000, "客户公海配置不存在或未启用"); @@ -92,6 +89,4 @@ public interface ErrorCodeConstants { ErrorCode FOLLOW_UP_RECORD_NOT_EXISTS = new ErrorCode(1_020_013_000, "跟进记录不存在"); ErrorCode FOLLOW_UP_RECORD_DELETE_DENIED = new ErrorCode(1_020_013_001, "删除跟进记录失败,原因:没有权限"); - // ========== 待办消息 1_020_014_000 ========== - } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.http b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.http deleted file mode 100644 index 55adb4bd5..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.http +++ /dev/null @@ -1,32 +0,0 @@ -### 请求 /transfer -PUT {{baseUrl}}/crm/business/transfer -Content-Type: application/json -Authorization: Bearer {{token}} -tenant-id: {{adminTenentId}} - -{ - "id": 1, - "ownerUserId": 2, - "transferType": 2, - "permissionType": 2 -} - -### 请求 /update -PUT {{baseUrl}}/crm/business/update -Content-Type: application/json -Authorization: Bearer {{token}} -tenant-id: {{adminTenentId}} - -{ - "id": 1, - "name": "2", - "statusTypeId": 2, - "statusId": 2, - "customerId": 1 -} - -### 请求 /get -GET {{baseUrl}}/crm/business/get?id=1024 -Content-Type: application/json -Authorization: Bearer {{token}} -tenant-id: {{adminTenentId}} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java index 91b8e95dd..dd3c0eb4e 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessController.java @@ -20,7 +20,6 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO; import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService; import cn.iocoder.yudao.module.crm.service.business.CrmBusinessStatusService; -import cn.iocoder.yudao.module.crm.service.business.CrmBusinessStatusTypeService; import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; import cn.iocoder.yudao.module.crm.service.product.CrmProductService; import cn.iocoder.yudao.module.system.api.dept.DeptApi; @@ -62,7 +61,7 @@ public class CrmBusinessController { @Resource private CrmCustomerService customerService; @Resource - private CrmBusinessStatusTypeService businessStatusTypeService; + private CrmBusinessStatusService businessStatusTypeService; @Resource private CrmBusinessStatusService businessStatusService; @Resource diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessStatusController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessStatusController.java new file mode 100644 index 000000000..bdc44679d --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessStatusController.java @@ -0,0 +1,118 @@ +package cn.iocoder.yudao.module.crm.controller.admin.business; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.number.NumberUtils; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusRespVO; +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusSaveReqVO; +import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; +import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO; +import cn.iocoder.yudao.module.crm.service.business.CrmBusinessStatusService; +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; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; + +@Tag(name = "管理后台 - CRM 商机状态") +@RestController +@RequestMapping("/crm/business-status") +@Validated +public class CrmBusinessStatusController { + + @Resource + private CrmBusinessStatusService businessStatusTypeService; + + @Resource + private AdminUserApi adminUserApi; + @Resource + private DeptApi deptApi; + + @PostMapping("/create") + @Operation(summary = "创建商机状态") + @PreAuthorize("@ss.hasPermission('crm:business-status:create')") + public CommonResult createBusinessStatus(@Valid @RequestBody CrmBusinessStatusSaveReqVO createReqVO) { + return success(businessStatusTypeService.createBusinessStatus(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新商机状态") + @PreAuthorize("@ss.hasPermission('crm:business-status:update')") + public CommonResult updateBusinessStatus(@Valid @RequestBody CrmBusinessStatusSaveReqVO updateReqVO) { + businessStatusTypeService.updateBusinessStatus(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除商机状态") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('crm:business-status-type:delete')") + public CommonResult deleteBusinessStatusType(@RequestParam("id") Long id) { + businessStatusTypeService.deleteBusinessStatusType(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得商机状态") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('crm:business-status-type:query')") + public CommonResult getBusinessStatusType(@RequestParam("id") Long id) { + CrmBusinessStatusTypeDO statusType = businessStatusTypeService.getBusinessStatusType(id); + if (statusType == null) { + return success(null); + } + List statuses = businessStatusTypeService.getBusinessStatusListByTypeId(id); + return success(BeanUtils.toBean(statusType, CrmBusinessStatusRespVO.class, + statusTypeVO -> statusTypeVO.setStatuses(BeanUtils.toBean(statuses, CrmBusinessStatusRespVO.Status.class)))); + } + + @GetMapping("/page") + @Operation(summary = "获得商机状态分页") + @PreAuthorize("@ss.hasPermission('crm:business-status-type:query')") + public CommonResult> getBusinessStatusTypePage(@Valid PageParam pageReqVO) { + // 1. 查询数据 + PageResult pageResult = businessStatusTypeService.getBusinessStatusTypePage(pageReqVO); + // 2. 拼接数据 + Map userMap = adminUserApi.getUserMap( + convertSet(pageResult.getList(), statusType -> Long.parseLong(statusType.getCreator()))); + Map deptMap = deptApi.getDeptMap( + convertSetByFlatMap(pageResult.getList(), CrmBusinessStatusTypeDO::getDeptIds, Collection::stream)); + return success(BeanUtils.toBean(pageResult, CrmBusinessStatusRespVO.class, statusTypeVO -> { + statusTypeVO.setCreator(userMap.get(NumberUtils.parseLong(statusTypeVO.getCreator())).getNickname()); + statusTypeVO.setDeptNames(convertList(statusTypeVO.getDeptIds(), + deptId -> deptMap.containsKey(deptId) ? deptMap.get(deptId).getName() : null)); + })); + } + + @GetMapping("/type-simple-list") + @Operation(summary = "获得商机状态列表") + public CommonResult> getBusinessStatusTypeSimpleList() { + List list = businessStatusTypeService.getBusinessStatusTypeList(); + return success(BeanUtils.toBean(list, CrmBusinessStatusRespVO.class)); + } + + @GetMapping("/status-simple-list") + @Operation(summary = "获得商机状态列表") + @Parameter(name = "typeId", description = "商机状态组", required = true, example = "1024") + public CommonResult> getBusinessStatusSimpleList(@RequestParam("typeId") Long typeId) { + List list = businessStatusTypeService.getBusinessStatusListByTypeId(typeId); + return success(BeanUtils.toBean(list, CrmBusinessStatusRespVO.Status.class)); + } + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessStatusTypeController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessStatusTypeController.java deleted file mode 100644 index 337590044..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessStatusTypeController.java +++ /dev/null @@ -1,141 +0,0 @@ -package cn.iocoder.yudao.module.crm.controller.admin.business; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusQueryVO; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusRespVO; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypePageReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeQueryVO; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeRespVO; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeSaveReqVO; -import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessStatusConvert; -import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessStatusTypeConvert; -import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO; -import cn.iocoder.yudao.module.crm.service.business.CrmBusinessStatusService; -import cn.iocoder.yudao.module.crm.service.business.CrmBusinessStatusTypeService; -import cn.iocoder.yudao.module.system.api.dept.DeptApi; -import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.annotation.Resource; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.validation.Valid; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import java.io.IOException; -import java.util.Collection; -import java.util.List; -import java.util.Set; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; - -@Tag(name = "管理后台 - CRM 商机状态类型") -@RestController -@RequestMapping("/crm/business-status-type") -@Validated -public class CrmBusinessStatusTypeController { - - @Resource - private CrmBusinessStatusTypeService businessStatusTypeService; - - @Resource - private CrmBusinessStatusService businessStatusService; - - @Resource - private DeptApi deptApi; - - @PostMapping("/create") - @Operation(summary = "创建商机状态类型") - @PreAuthorize("@ss.hasPermission('crm:business-status-type:create')") - public CommonResult createBusinessStatusType(@Valid @RequestBody CrmBusinessStatusTypeSaveReqVO createReqVO) { - return success(businessStatusTypeService.createBusinessStatusType(createReqVO)); - } - - @PutMapping("/update") - @Operation(summary = "更新商机状态类型") - @PreAuthorize("@ss.hasPermission('crm:business-status-type:update')") - public CommonResult updateBusinessStatusType(@Valid @RequestBody CrmBusinessStatusTypeSaveReqVO updateReqVO) { - businessStatusTypeService.updateBusinessStatusType(updateReqVO); - return success(true); - } - - @DeleteMapping("/delete") - @Operation(summary = "删除商机状态类型") - @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('crm:business-status-type:delete')") - public CommonResult deleteBusinessStatusType(@RequestParam("id") Long id) { - businessStatusTypeService.deleteBusinessStatusType(id); - return success(true); - } - - @GetMapping("/get") - @Operation(summary = "获得商机状态类型") - @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('crm:business-status-type:query')") - public CommonResult getBusinessStatusType(@RequestParam("id") Long id) { - CrmBusinessStatusTypeDO statusType = businessStatusTypeService.getBusinessStatusType(id); - // 处理状态回显 - // TODO @lzxhqs:可以在 businessStatusService 加个 getBusinessStatusListByTypeId 方法,直接返回 List 哈,常用的,尽量封装个简单易懂的方法,不用追求绝对通用哈; - CrmBusinessStatusQueryVO queryVO = new CrmBusinessStatusQueryVO(); - queryVO.setTypeId(id); - List statusList = businessStatusService.selectList(queryVO); - return success(CrmBusinessStatusTypeConvert.INSTANCE.convert(statusType, statusList)); - } - - @GetMapping("/page") - @Operation(summary = "获得商机状态类型分页") - @PreAuthorize("@ss.hasPermission('crm:business-status-type:query')") - public CommonResult> getBusinessStatusTypePage(@Valid CrmBusinessStatusTypePageReqVO pageReqVO) { - PageResult pageResult = businessStatusTypeService.getBusinessStatusTypePage(pageReqVO); - // 处理部门回显 - Set deptIds = CollectionUtils.convertSetByFlatMap(pageResult.getList(), CrmBusinessStatusTypeDO::getDeptIds,Collection::stream); - List deptList = deptApi.getDeptList(deptIds); - return success(CrmBusinessStatusTypeConvert.INSTANCE.convertPage(pageResult, deptList)); - } - - @GetMapping("/export-excel") - @Operation(summary = "导出商机状态类型 Excel") - @PreAuthorize("@ss.hasPermission('crm:business-status-type:export')") - @OperateLog(type = EXPORT) - public void exportBusinessStatusTypeExcel(@Valid CrmBusinessStatusTypePageReqVO pageReqVO, - HttpServletResponse response) throws IOException { - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); - List list = businessStatusTypeService.getBusinessStatusTypePage(pageReqVO).getList(); - // 导出 Excel - ExcelUtils.write(response, "商机状态类型.xls", "数据", CrmBusinessStatusTypeRespVO.class, - BeanUtils.toBean(list, CrmBusinessStatusTypeRespVO.class)); - } - - @GetMapping("/get-simple-list") - @Operation(summary = "获得商机状态类型列表") - @PreAuthorize("@ss.hasPermission('crm:business-status-type:query')") - public CommonResult> getBusinessStatusTypeList() { - CrmBusinessStatusTypeQueryVO queryVO = new CrmBusinessStatusTypeQueryVO(); - queryVO.setStatus(CommonStatusEnum.ENABLE.getStatus()); - List list = businessStatusTypeService.selectList(queryVO); - return success(BeanUtils.toBean(list, CrmBusinessStatusTypeRespVO.class)); - } - - // TODO @ljlleo 这个接口,是不是可以和 getBusinessStatusTypeList 合并成一个? - @GetMapping("/get-status-list") - @Operation(summary = "获得商机状态列表") - @PreAuthorize("@ss.hasPermission('crm:business-status:query')") - public CommonResult> getBusinessStatusListByTypeId(@RequestParam("typeId") Long typeId) { - CrmBusinessStatusQueryVO queryVO = new CrmBusinessStatusQueryVO(); - queryVO.setTypeId(typeId); - List list = businessStatusService.selectList(queryVO); - return success(CrmBusinessStatusConvert.INSTANCE.convertList(list)); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessRespVO.java index 41829360a..6e8ea6741 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessRespVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessRespVO.java @@ -52,10 +52,10 @@ public class CrmBusinessRespVO { @ExcelProperty("负责人部门") private String ownerUserDeptName; - @Schema(description = "商机状态类型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "25714") + @Schema(description = "商机状态组编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "25714") private Long statusTypeId; - @Schema(description = "状态类型名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "进行中") - @ExcelProperty("商机状态类型") + @Schema(description = "商机状组名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "进行中") + @ExcelProperty("商机状态组") private String statusTypeName; @Schema(description = "商机状态编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java index b9816a8fc..8b0c53d21 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java @@ -43,9 +43,9 @@ public class CrmBusinessSaveReqVO { @DiffLogField(name = "负责人", function = SysAdminUserParseFunction.NAME) private Long ownerUserId; - @Schema(description = "商机状态类型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "25714") - @DiffLogField(name = "商机状态") - @NotNull(message = "商机状态类型不能为空") + @Schema(description = "商机状态组编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "25714") + @DiffLogField(name = "商机状态组") + @NotNull(message = "商机状态组不能为空") private Long statusTypeId; @Schema(description = "预计成交日期") diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/status/CrmBusinessStatusPageReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/status/CrmBusinessStatusPageReqVO.java deleted file mode 100644 index b91a954e0..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/status/CrmBusinessStatusPageReqVO.java +++ /dev/null @@ -1,15 +0,0 @@ -package cn.iocoder.yudao.module.crm.controller.admin.business.vo.status; - -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 = "管理后台 - 商机状态分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class CrmBusinessStatusPageReqVO extends PageParam { - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/status/CrmBusinessStatusQueryVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/status/CrmBusinessStatusQueryVO.java deleted file mode 100644 index fbf4d06e1..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/status/CrmBusinessStatusQueryVO.java +++ /dev/null @@ -1,19 +0,0 @@ -package cn.iocoder.yudao.module.crm.controller.admin.business.vo.status; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.ToString; - -import java.util.Collection; - -@Schema(description = "管理后台 - 商机状态 Query VO") -@Data -@ToString(callSuper = true) -public class CrmBusinessStatusQueryVO { - - @Schema(description = "主键集合") - private Collection idList; - - @Schema(description = "状态类型编号") - private Long typeId; -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/status/CrmBusinessStatusRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/status/CrmBusinessStatusRespVO.java index 405a832a5..a2ee1dfe5 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/status/CrmBusinessStatusRespVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/status/CrmBusinessStatusRespVO.java @@ -1,33 +1,51 @@ package cn.iocoder.yudao.module.crm.controller.admin.business.vo.status; -import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; -import com.alibaba.excel.annotation.ExcelProperty; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.List; + @Schema(description = "管理后台 - 商机状态 Response VO") @Data -@ExcelIgnoreUnannotated public class CrmBusinessStatusRespVO { - @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "23899") - @ExcelProperty("主键") + @Schema(description = "状态组编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2934") private Long id; - @Schema(description = "状态类型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "7139") - @ExcelProperty("状态类型编号") - private Long typeId; - - @Schema(description = "状态名", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五") - @ExcelProperty("状态名") + @Schema(description = "状态组名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") private String name; - @Schema(description = "赢单率") - @ExcelProperty("赢单率") - private String percent; + @Schema(description = "使用的部门编号", requiredMode = Schema.RequiredMode.REQUIRED) + private List deptIds; + @Schema(description = "使用的部门名称", requiredMode = Schema.RequiredMode.REQUIRED) + private List deptNames; - @Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @ExcelProperty("排序") - private Integer sort; + @Schema(description = "创建人", requiredMode = Schema.RequiredMode.REQUIRED) + private String creator; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime createTime; + + @Schema(description = "状态集合", requiredMode = Schema.RequiredMode.REQUIRED) + private List statuses; + + @Data + public static class Status { + + @Schema(description = "状态编号", example = "23899") + private Long id; + + @Schema(description = "状态名", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五") + private String name; + + @Schema(description = "赢单率", requiredMode = Schema.RequiredMode.REQUIRED, example = "50") + private BigDecimal percent; + + @Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") + private Integer sort; + + } } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/status/CrmBusinessStatusSaveReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/status/CrmBusinessStatusSaveReqVO.java index 3327b09f7..05ea279af 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/status/CrmBusinessStatusSaveReqVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/status/CrmBusinessStatusSaveReqVO.java @@ -1,32 +1,48 @@ package cn.iocoder.yudao.module.crm.controller.admin.business.vo.status; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; +import lombok.Data; -@Schema(description = "管理后台 - 商机状态新增/修改 Request VO") +import java.math.BigDecimal; +import java.util.List; + +@Schema(description = "管理后台 - 商机状态组新增/修改 Request VO") @Data public class CrmBusinessStatusSaveReqVO { - @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "23899") + @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "2934") private Long id; - @Schema(description = "状态类型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "7139") - @NotNull(message = "状态类型编号不能为空") - private Long typeId; - - @Schema(description = "状态名", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五") - @NotEmpty(message = "状态名不能为空") + @Schema(description = "状态类型名", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") + @NotEmpty(message = "状态类型名不能为空") private String name; - // TODO @lzxhqs::percent 应该是 Integer; - @Schema(description = "赢单率") - private String percent; + @Schema(description = "使用的部门编号") + private List deptIds; - // TODO @lzxhqs:这个是不是不用前端新增和修改的时候传递,交给顺序计算出来,存储起来就好了; - @Schema(description = "排序") - private Integer sort; + @Schema(description = "商机状态集合", requiredMode = Schema.RequiredMode.REQUIRED) + @NotEmpty(message = "商机状态集合不能为空") + private List statuses; + + @Data + public static class Status { + + @Schema(description = "状态编号", example = "23899") + private Long id; + + @Schema(description = "状态名", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五") + @NotEmpty(message = "状态名不能为空") + private String name; + + @Schema(description = "赢单率", requiredMode = Schema.RequiredMode.REQUIRED, example = "50") + @NotNull(message = "赢单率不能为空") + private BigDecimal percent; + + @Schema(description = "排序", hidden = true, example = "1") + private Integer sort; + + } } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/type/CrmBusinessStatusTypePageReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/type/CrmBusinessStatusTypePageReqVO.java deleted file mode 100644 index 03b113cc7..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/type/CrmBusinessStatusTypePageReqVO.java +++ /dev/null @@ -1,15 +0,0 @@ -package cn.iocoder.yudao.module.crm.controller.admin.business.vo.type; - -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 = "管理后台 - 商机状态类型分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class CrmBusinessStatusTypePageReqVO extends PageParam { - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/type/CrmBusinessStatusTypeQueryVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/type/CrmBusinessStatusTypeQueryVO.java deleted file mode 100644 index 9c78f1afc..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/type/CrmBusinessStatusTypeQueryVO.java +++ /dev/null @@ -1,19 +0,0 @@ -package cn.iocoder.yudao.module.crm.controller.admin.business.vo.type; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; -import lombok.ToString; - -import java.util.Collection; - -@Schema(description = "管理后台 - 商机状态类型 Query VO") -@Data -@ToString(callSuper = true) -public class CrmBusinessStatusTypeQueryVO { - - @Schema(description = "主键集合") - private Collection idList; - - @Schema(description = "状态") - private Integer status; -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/type/CrmBusinessStatusTypeRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/type/CrmBusinessStatusTypeRespVO.java deleted file mode 100644 index 9d13d5dc3..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/type/CrmBusinessStatusTypeRespVO.java +++ /dev/null @@ -1,44 +0,0 @@ -package cn.iocoder.yudao.module.crm.controller.admin.business.vo.type; - -import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; -import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; -import com.alibaba.excel.annotation.ExcelProperty; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.time.LocalDateTime; -import java.util.List; - -@Schema(description = "管理后台 - 商机状态类型 Response VO") -@Data -@ExcelIgnoreUnannotated -public class CrmBusinessStatusTypeRespVO { - - @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "2934") - @ExcelProperty("主键") - private Long id; - - @Schema(description = "状态类型名", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") - @ExcelProperty("状态类型名") - private String name; - - @Schema(description = "使用的部门编号", requiredMode = Schema.RequiredMode.REQUIRED) - @ExcelProperty("使用的部门编号") - private List deptIds; - @Schema(description = "使用的部门名称", requiredMode = Schema.RequiredMode.REQUIRED) - @ExcelProperty("使用的部门名称") - private List deptNames; - - @Schema(description = "创建人", requiredMode = Schema.RequiredMode.REQUIRED) - @ExcelProperty("创建人") - private String creator; - - @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) - @ExcelProperty("创建时间") - private LocalDateTime createTime; - - // TODO @ljlleo 字段后缀改成 statuses,保持和 deptIds 风格一致;CrmBusinessStatusDO 改成 VO 哈;一般不使用 do 直接返回 - @Schema(description = "状态集合", requiredMode = Schema.RequiredMode.REQUIRED) - private List statusList; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/type/CrmBusinessStatusTypeSaveReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/type/CrmBusinessStatusTypeSaveReqVO.java deleted file mode 100644 index 23dc7742d..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/type/CrmBusinessStatusTypeSaveReqVO.java +++ /dev/null @@ -1,29 +0,0 @@ -package cn.iocoder.yudao.module.crm.controller.admin.business.vo.type; - -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusSaveReqVO; -import com.google.common.collect.Lists; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import jakarta.validation.constraints.NotEmpty; -import java.util.List; - -@Schema(description = "管理后台 - 商机状态类型新增/修改 Request VO") -@Data -public class CrmBusinessStatusTypeSaveReqVO { - - @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "2934") - private Long id; - - @Schema(description = "状态类型名", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") - @NotEmpty(message = "状态类型名不能为空") - private String name; - - // TODO @lzxhqs: VO 里面,我们不使用默认值哈。这里 Lists.newArrayList() 看看怎么去掉。上面 deptIds 也是类似噢 - @Schema(description = "使用的部门编号", requiredMode = Schema.RequiredMode.REQUIRED) - private List deptIds = Lists.newArrayList(); - - @Schema(description = "商机状态集合", requiredMode = Schema.RequiredMode.REQUIRED) - private List statusList; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessStatusConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessStatusConvert.java deleted file mode 100644 index 52186e3d9..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessStatusConvert.java +++ /dev/null @@ -1,25 +0,0 @@ -package cn.iocoder.yudao.module.crm.convert.business; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusRespVO; -import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -import java.util.List; - -/** - * 商机状态 Convert - * - * @author ljlleo - */ -@Mapper -public interface CrmBusinessStatusConvert { - - CrmBusinessStatusConvert INSTANCE = Mappers.getMapper(CrmBusinessStatusConvert.class); - - List convertList(List list); - - PageResult convertPage(PageResult page); - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessStatusTypeConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessStatusTypeConvert.java deleted file mode 100644 index 4876fb537..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/business/CrmBusinessStatusTypeConvert.java +++ /dev/null @@ -1,44 +0,0 @@ -package cn.iocoder.yudao.module.crm.convert.business; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeRespVO; -import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO; -import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -import java.util.List; -import java.util.Map; - -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; - -// TODO @lzxhqs:看看是不是用 BeanUtils 替代了 -/** - * 商机状态类型 Convert - * - * @author ljlleo - */ -@Mapper -public interface CrmBusinessStatusTypeConvert { - - CrmBusinessStatusTypeConvert INSTANCE = Mappers.getMapper(CrmBusinessStatusTypeConvert.class); - - CrmBusinessStatusTypeRespVO convert(CrmBusinessStatusTypeDO bean); - - PageResult convertPage(PageResult page); - - default PageResult convertPage(PageResult page, List deptList) { - PageResult pageResult = convertPage(page); - // 拼接关联字段 - Map deptMap = convertMap(deptList, DeptRespDTO::getId, DeptRespDTO::getName); - pageResult.getList().forEach(type -> type.setDeptNames(convertList(type.getDeptIds(), deptMap::get))); - return pageResult; - } - - default CrmBusinessStatusTypeRespVO convert(CrmBusinessStatusTypeDO bean, List statusList) { - return convert(bean).setStatusList(statusList); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessDO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessDO.java index 803f37a38..770c0110e 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessDO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessDO.java @@ -63,7 +63,7 @@ public class CrmBusinessDO extends BaseDO { private Long ownerUserId; /** - * 商机状态类型编号 + * 商机状态组编号 * * 关联 {@link CrmBusinessStatusTypeDO#getId()} */ diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessStatusTypeDO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessStatusTypeDO.java index aa9f86251..791a8b700 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessStatusTypeDO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessStatusTypeDO.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.crm.dal.dataobject.business; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler; import com.baomidou.mybatisplus.annotation.KeySequence; @@ -12,7 +11,7 @@ import lombok.*; import java.util.List; /** - * 商机状态类型 DO + * 商机状态组 DO * * @author ljlleo */ @@ -35,17 +34,11 @@ public class CrmBusinessStatusTypeDO extends BaseDO { * 状态类型名 */ private String name; + /** * 使用的部门编号 */ @TableField(typeHandler = LongListTypeHandler.class) private List deptIds; - /** - * 开启状态 - * - * TODO 改成 Integer,关联 CommonStatus - * 枚举 {@link CommonStatusEnum} - */ - private Boolean status; } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java index d7438484f..4e93c5eb3 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessMapper.java @@ -63,4 +63,8 @@ public interface CrmBusinessMapper extends BaseMapperX { return selectJoinList(CrmBusinessDO.class, query); } + default Long selectCountByStatusTypeId(Long statusTypeId) { + return selectCount(CrmBusinessDO::getStatusTypeId, statusTypeId); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessStatusMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessStatusMapper.java index be847ab9d..f157e7dc6 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessStatusMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessStatusMapper.java @@ -1,10 +1,6 @@ package cn.iocoder.yudao.module.crm.dal.mysql.business; -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.business.vo.status.CrmBusinessStatusPageReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusQueryVO; import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; import org.apache.ibatis.annotations.Mapper; @@ -18,20 +14,12 @@ import java.util.List; @Mapper public interface CrmBusinessStatusMapper extends BaseMapperX { - default PageResult selectPage(CrmBusinessStatusPageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .orderByDesc(CrmBusinessStatusDO::getId)); - } - - default List selectList(CrmBusinessStatusQueryVO queryVO) { - return selectList(new LambdaQueryWrapperX() - .eqIfPresent(CrmBusinessStatusDO::getTypeId, queryVO.getTypeId()) - .inIfPresent(CrmBusinessStatusDO::getId, queryVO.getIdList()) - .orderByDesc(CrmBusinessStatusDO::getId)); - } - - default int delete(Long typeId) { + default int deleteByTypeId(Long typeId) { return delete(CrmBusinessStatusDO::getTypeId, typeId); } + default List selectListByTypeId(Long typeId) { + return selectList(CrmBusinessStatusDO::getTypeId, typeId); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessStatusTypeMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessStatusTypeMapper.java index 410ebf050..3444e58a7 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessStatusTypeMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessStatusTypeMapper.java @@ -1,44 +1,27 @@ package cn.iocoder.yudao.module.crm.dal.mysql.business; +import cn.iocoder.yudao.framework.common.pojo.PageParam; 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.business.vo.type.CrmBusinessStatusTypePageReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeQueryVO; import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO; import org.apache.ibatis.annotations.Mapper; -import java.util.List; - /** - * 商机状态类型 Mapper + * 商机状态组 Mapper * * @author ljlleo */ @Mapper public interface CrmBusinessStatusTypeMapper extends BaseMapperX { - default PageResult selectPage(CrmBusinessStatusTypePageReqVO reqVO) { + default PageResult selectPage(PageParam reqVO) { return selectPage(reqVO, new LambdaQueryWrapperX() .orderByDesc(CrmBusinessStatusTypeDO::getId)); } - default List selectList(CrmBusinessStatusTypeQueryVO queryVO) { - return selectList(new LambdaQueryWrapperX() - .eqIfPresent(CrmBusinessStatusTypeDO::getStatus, queryVO.getStatus()) - .inIfPresent(CrmBusinessStatusTypeDO::getId, queryVO.getIdList())); - } - - // TODO @lzxhqs:这个可以改成 selectByName。业务上基于在判断 id 匹配;这样更通用一些;mapper 尽量通用,不关注或者特别关联业务; - /** - * 根据ID和name查询 - * - * @param id 商机状态类型id - * @param name 状态类型名 - * @return result - */ - default CrmBusinessStatusTypeDO selectByIdAndName(Long id, String name) { - return selectOne(CrmBusinessStatusTypeDO::getId, id, CrmBusinessStatusTypeDO::getName, name); + default CrmBusinessStatusTypeDO selectByName(String name) { + return selectOne(CrmBusinessStatusTypeDO::getName, name); } } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java index c7dba0101..696689e8a 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessService.java @@ -138,4 +138,12 @@ public interface CrmBusinessService { */ Long getBusinessCountByCustomerId(Long customerId); + /** + * 获得使用指定商机状态组的商机数量 + * + * @param statusTypeId 商机状态组编号 + * @return 数量 + */ + Long getBusinessCountByStatusTypeId(Long statusTypeId); + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java index 15dd00ee2..2b4e09e2f 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java @@ -295,4 +295,9 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { return businessMapper.selectCount(CrmBusinessDO::getCustomerId, customerId); } + @Override + public Long getBusinessCountByStatusTypeId(Long statusTypeId) { + return businessMapper.selectCountByStatusTypeId(statusTypeId); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusService.java index d9128b429..c813f37cf 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusService.java @@ -1,10 +1,10 @@ package cn.iocoder.yudao.module.crm.service.business; +import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusPageReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusQueryVO; import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusSaveReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; +import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO; import jakarta.validation.Valid; import java.util.Collection; @@ -40,33 +40,56 @@ public interface CrmBusinessStatusService { * * @param id 编号 */ - void deleteBusinessStatus(Long id); + void deleteBusinessStatusType(Long id); /** - * 获得商机状态 + * 获得商机状态组 * * @param id 编号 - * @return 商机状态 + * @return 商机状态组 */ - CrmBusinessStatusDO getBusinessStatus(Long id); + CrmBusinessStatusTypeDO getBusinessStatusType(Long id); /** - * 获得商机状态分页 + * 获得商机状态组列表 + * + * @return 商机状态组列表 + */ + List getBusinessStatusTypeList(); + + /** + * 获得商机状态组分页 * * @param pageReqVO 分页查询 - * @return 商机状态分页 + * @return 商机状态组分页 */ - PageResult getBusinessStatusPage(CrmBusinessStatusPageReqVO pageReqVO); + PageResult getBusinessStatusTypePage(PageParam pageReqVO); - // TODO @ljlleo 常用的 ids 之类的查询,可以封装单独的方法,不用走类似 QueryVO,用起来更方便。 - // TODO @ljlleo 方法名用 getBusinessStatusList /** - * 获得商机状态分页 + * 获得商机状态组列表 * - * @param queryVO 查询参数 - * @return 商机状态分页 + * @param ids 编号数组 + * @return 商机状态组列表 */ - List selectList(CrmBusinessStatusQueryVO queryVO); + List getBusinessStatusTypeList(Collection ids); + + /** + * 获得商机状态组 Map + * + * @param ids 编号数组 + * @return 商机状态组 Map + */ + default Map getBusinessStatusTypeMap(Collection ids) { + return convertMap(getBusinessStatusTypeList(ids), CrmBusinessStatusTypeDO::getId); + } + + /** + * 获得指定类型的商机状态列表 + * + * @param typeId 商机状态组编号 + * @return 商机状态列表 + */ + List getBusinessStatusListByTypeId(Long typeId); /** * 获得商机状态列表 diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusServiceImpl.java index b838fdc6f..349b112c2 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusServiceImpl.java @@ -1,24 +1,29 @@ package cn.iocoder.yudao.module.crm.service.business; import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusPageReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusQueryVO; import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusSaveReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; +import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO; import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessStatusMapper; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - +import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessStatusTypeMapper; import jakarta.annotation.Resource; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.BUSINESS_STATUS_NOT_EXISTS; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.diffList; +import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; /** * 商机状态 Service 实现类 @@ -29,55 +34,135 @@ import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.BUSINESS_STAT @Validated public class CrmBusinessStatusServiceImpl implements CrmBusinessStatusService { + @Resource + private CrmBusinessStatusTypeMapper businessStatusTypeMapper; @Resource private CrmBusinessStatusMapper businessStatusMapper; + @Resource + @Lazy // 延迟加载,避免循环依赖 + private CrmBusinessService businessService; + @Override + @Transactional(rollbackFor = Exception.class) public Long createBusinessStatus(CrmBusinessStatusSaveReqVO createReqVO) { - // 插入 - CrmBusinessStatusDO businessStatus = BeanUtils.toBean(createReqVO, CrmBusinessStatusDO.class); - businessStatusMapper.insert(businessStatus); - // 返回 - return businessStatus.getId(); + // 1.1 检验名称是否存在 + validateBusinessStatusTypeNameUnique(createReqVO.getName(), null); + // 1.2 设置状态的排序 + int sort = 0; + for (CrmBusinessStatusSaveReqVO.Status status : createReqVO.getStatuses()) { + status.setSort(sort++); + } + + // 2.1 插入类型 + CrmBusinessStatusTypeDO statusType = BeanUtils.toBean(createReqVO, CrmBusinessStatusTypeDO.class); + businessStatusTypeMapper.insert(statusType); + // 2.2 插入状态 + List statuses = BeanUtils.toBean(createReqVO.getStatuses(), CrmBusinessStatusDO.class, + status -> status.setTypeId(statusType.getId())); + businessStatusMapper.insertBatch(statuses); + return statusType.getId(); } @Override + @Transactional(rollbackFor = Exception.class) public void updateBusinessStatus(CrmBusinessStatusSaveReqVO updateReqVO) { - // 校验存在 - validateBusinessStatusExists(updateReqVO.getId()); - // 更新 - CrmBusinessStatusDO updateObj = BeanUtils.toBean(updateReqVO, CrmBusinessStatusDO.class); - businessStatusMapper.updateById(updateObj); + // 1.1 校验存在 + validateBusinessStatusTypeNameUnique(updateReqVO.getId()); + // 1.2 校验名称是否存在 + validateBusinessStatusTypeNameUnique(updateReqVO.getName(), updateReqVO.getId()); + // 1.3 设置状态的排序 + int sort = 0; + for (CrmBusinessStatusSaveReqVO.Status status : updateReqVO.getStatuses()) { + status.setSort(sort++); + } + // 1.4 已经使用,无法更新 + if (businessService.getBusinessCountByStatusTypeId(updateReqVO.getId()) > 0) { + throw exception(BUSINESS_STATUS_UPDATE_FAIL_USED); + } + + // 2.1 更新类型 + CrmBusinessStatusTypeDO updateObj = BeanUtils.toBean(updateReqVO, CrmBusinessStatusTypeDO.class); + businessStatusTypeMapper.updateById(updateObj); + // 2.2 更新状态 + updateBusinessStatus(updateReqVO.getId(), BeanUtils.toBean(updateReqVO.getStatuses(), CrmBusinessStatusDO.class)); } - @Override - public void deleteBusinessStatus(Long id) { - // 校验存在 - validateBusinessStatusExists(id); - // TODO @ljlleo 这里可以考虑,如果有商机在使用,不允许删除 - // 删除 - businessStatusMapper.deleteById(id); - } - - private void validateBusinessStatusExists(Long id) { - if (businessStatusMapper.selectById(id) == null) { - throw exception(BUSINESS_STATUS_NOT_EXISTS); + private void updateBusinessStatus(Long id, List newList) { + List oldList = businessStatusMapper.selectListByTypeId(id); + List> diffList = diffList(oldList, newList, // id 不同,就认为是不同的记录 + (oldVal, newVal) -> oldVal.getId().equals(newVal.getId())); + if (CollUtil.isNotEmpty(diffList.get(0))) { + diffList.get(0).forEach(o -> o.setTypeId(id)); + businessStatusMapper.insertBatch(diffList.get(0)); + } + if (CollUtil.isNotEmpty(diffList.get(1))) { + businessStatusMapper.updateBatch(diffList.get(1)); + } + if (CollUtil.isNotEmpty(diffList.get(2))) { + businessStatusMapper.deleteBatchIds(convertSet(diffList.get(2), CrmBusinessStatusDO::getId)); } } - @Override - public CrmBusinessStatusDO getBusinessStatus(Long id) { - return businessStatusMapper.selectById(id); + private void validateBusinessStatusTypeNameUnique(Long id) { + if (businessStatusTypeMapper.selectById(id) == null) { + throw exception(BUSINESS_STATUS_TYPE_NOT_EXISTS); + } + } + + private void validateBusinessStatusTypeNameUnique(String name, Long id) { + CrmBusinessStatusTypeDO statusType = businessStatusTypeMapper.selectByName(name); + if (statusType == null + || statusType.getId().equals(id)) { + return; + } + throw exception(BUSINESS_STATUS_TYPE_NAME_EXISTS); } @Override - public PageResult getBusinessStatusPage(CrmBusinessStatusPageReqVO pageReqVO) { - return businessStatusMapper.selectPage(pageReqVO); + @Transactional(rollbackFor = Exception.class) + public void deleteBusinessStatusType(Long id) { + // 1.1 校验存在 + validateBusinessStatusTypeNameUnique(id); + // 1.2 已经使用,无法更新 + if (businessService.getBusinessCountByStatusTypeId(id) > 0) { + throw exception(BUSINESS_STATUS_DELETE_FAIL_USED); + } + + // 2.1 删除类型 + businessStatusTypeMapper.deleteById(id); + // 2.2 删除状态 + businessStatusMapper.deleteByTypeId(id); } @Override - public List selectList(CrmBusinessStatusQueryVO queryVO) { - return businessStatusMapper.selectList(queryVO); + public CrmBusinessStatusTypeDO getBusinessStatusType(Long id) { + return businessStatusTypeMapper.selectById(id); + } + + @Override + public List getBusinessStatusTypeList() { + return businessStatusTypeMapper.selectList(); + } + + @Override + public PageResult getBusinessStatusTypePage(PageParam pageReqVO) { + return null; + } + + @Override + public List getBusinessStatusTypeList(Collection ids) { + if (CollUtil.isEmpty(ids)) { + return Collections.emptyList(); + } + return businessStatusTypeMapper.selectBatchIds(ids); + } + + @Override + public List getBusinessStatusListByTypeId(Long typeId) { + List list = businessStatusMapper.selectListByTypeId(typeId); + list.sort(Comparator.comparingInt(CrmBusinessStatusDO::getSort)); + return list; } @Override diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusTypeService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusTypeService.java deleted file mode 100644 index a48ff0503..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusTypeService.java +++ /dev/null @@ -1,88 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.business; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypePageReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeQueryVO; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeSaveReqVO; -import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO; -import jakarta.validation.Valid; - -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; - -/** - * 商机状态类型 Service 接口 - * - * @author ljlleo - */ -public interface CrmBusinessStatusTypeService { - - /** - * 创建商机状态类型 - * - * @param createReqVO 创建信息 - * @return 编号 - */ - Long createBusinessStatusType(@Valid CrmBusinessStatusTypeSaveReqVO createReqVO); - - /** - * 更新商机状态类型 - * - * @param updateReqVO 更新信息 - */ - void updateBusinessStatusType(@Valid CrmBusinessStatusTypeSaveReqVO updateReqVO); - - /** - * 删除商机状态类型 - * - * @param id 编号 - */ - void deleteBusinessStatusType(Long id); - - /** - * 获得商机状态类型 - * - * @param id 编号 - * @return 商机状态类型 - */ - CrmBusinessStatusTypeDO getBusinessStatusType(Long id); - - /** - * 获得商机状态类型分页 - * - * @param pageReqVO 分页查询 - * @return 商机状态类型分页 - */ - PageResult getBusinessStatusTypePage(CrmBusinessStatusTypePageReqVO pageReqVO); - - // TODO @ljlleo 常用的 ids 之类的查询,可以封装单独的方法,不用走类似 QueryVO,用起来更方便。 - /** - * 获得商机状态类型列表 - * - * @param queryVO 查询参数 - * @return 商机状态类型列表 - */ - List selectList(CrmBusinessStatusTypeQueryVO queryVO); - - /** - * 获得商机状态类型列表 - * - * @param ids 编号数组 - * @return 商机状态类型列表 - */ - List getBusinessStatusTypeList(Collection ids); - - /** - * 获得商机状态类型 Map - * - * @param ids 编号数组 - * @return 商机状态类型 Map - */ - default Map getBusinessStatusTypeMap(Collection ids) { - return convertMap(getBusinessStatusTypeList(ids), CrmBusinessStatusTypeDO::getId); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusTypeServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusTypeServiceImpl.java deleted file mode 100644 index 85d30e8ce..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusTypeServiceImpl.java +++ /dev/null @@ -1,133 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.business; - -import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypePageReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeQueryVO; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeSaveReqVO; -import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO; -import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO; -import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessStatusMapper; -import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessStatusTypeMapper; -import jakarta.annotation.Resource; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.validation.annotation.Validated; - -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.BUSINESS_STATUS_TYPE_NAME_EXISTS; -import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.BUSINESS_STATUS_TYPE_NOT_EXISTS; - -/** - * 商机状态类型 Service 实现类 - * - * @author ljlleo - */ -@Service -@Validated -public class CrmBusinessStatusTypeServiceImpl implements CrmBusinessStatusTypeService { - - @Resource - private CrmBusinessStatusTypeMapper businessStatusTypeMapper; - - @Resource - private CrmBusinessStatusMapper businessStatusMapper; - - @Override - @Transactional(rollbackFor = Exception.class) - public Long createBusinessStatusType(CrmBusinessStatusTypeSaveReqVO createReqVO) { - //检验名称是否存在 - validateBusinessStatusTypeExists(createReqVO.getName(), null); - // 插入类型 - CrmBusinessStatusTypeDO businessStatusType = BeanUtils.toBean(createReqVO, CrmBusinessStatusTypeDO.class); - businessStatusTypeMapper.insert(businessStatusType); - // 插入状态 - if (CollUtil.isNotEmpty(createReqVO.getStatusList())) { - createReqVO.getStatusList().forEach(status -> status.setTypeId(businessStatusType.getId())); - businessStatusMapper.insertBatch(BeanUtils.toBean(createReqVO.getStatusList(), CrmBusinessStatusDO.class)); - } - return businessStatusType.getId(); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void updateBusinessStatusType(CrmBusinessStatusTypeSaveReqVO updateReqVO) { - // 校验存在 - validateBusinessStatusTypeExists(updateReqVO.getId()); - // 校验名称是否存在 - validateBusinessStatusTypeExists(updateReqVO.getName(), updateReqVO.getId()); - // 更新类型 - CrmBusinessStatusTypeDO updateObj = BeanUtils.toBean(updateReqVO, CrmBusinessStatusTypeDO.class); - businessStatusTypeMapper.updateById(updateObj); - // 更新状态(删除 + 更新) - // TODO @ljlleo 可以参考 DeliveryExpressTemplateServiceImpl 的 updateExpressTemplateFree 方法;主要没变化的,还是不删除了哈。 - businessStatusMapper.delete(updateReqVO.getId()); - updateReqVO.getStatusList().forEach(status -> status.setTypeId(updateReqVO.getId())); - businessStatusMapper.insertBatch(BeanUtils.toBean(updateReqVO.getStatusList(), CrmBusinessStatusDO.class)); - } - - @Override - @Transactional(rollbackFor = Exception.class) - public void deleteBusinessStatusType(Long id) { - // TODO 待添加被引用校验 - //... - - // 校验存在 - validateBusinessStatusTypeExists(id); - // 删除类型 - businessStatusTypeMapper.deleteById(id); - // 删除状态 - businessStatusMapper.delete(id); - } - - private void validateBusinessStatusTypeExists(Long id) { - if (businessStatusTypeMapper.selectById(id) == null) { - throw exception(BUSINESS_STATUS_TYPE_NOT_EXISTS); - } - } - - // TODO @ljlleo 这个方法,这个参考 validateDeptNameUnique 实现。 - private void validateBusinessStatusTypeExists(String name, Long id) { - CrmBusinessStatusTypeDO businessStatusTypeDO = businessStatusTypeMapper.selectByIdAndName(id, name); - if (businessStatusTypeDO != null) { - throw exception(BUSINESS_STATUS_TYPE_NAME_EXISTS); - } -// LambdaQueryWrapper wrapper = new LambdaQueryWrapperX<>(); -// if(null != id) { -// wrapper.ne(CrmBusinessStatusTypeDO::getId, id); -// } -// long cnt = businessStatusTypeMapper.selectCount(wrapper.eq(CrmBusinessStatusTypeDO::getName, name)); -// if (cnt > 0) { -// throw exception(BUSINESS_STATUS_TYPE_NAME_EXISTS); -// } - } - - @Override - public CrmBusinessStatusTypeDO getBusinessStatusType(Long id) { - return businessStatusTypeMapper.selectById(id); - } - - @Override - public PageResult getBusinessStatusTypePage(CrmBusinessStatusTypePageReqVO pageReqVO) { - return businessStatusTypeMapper.selectPage(pageReqVO); - } - - @Override - public List selectList(CrmBusinessStatusTypeQueryVO queryVO) { - return businessStatusTypeMapper.selectList(queryVO); - } - - @Override - public List getBusinessStatusTypeList(Collection ids) { - if (CollUtil.isEmpty(ids)) { - return Collections.emptyList(); - } - return businessStatusTypeMapper.selectBatchIds(ids); - } - -} From 77f98c4d129307a1128af4ba6e88d8bfb52d8737 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 21 Feb 2024 21:49:49 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E2=9C=A8=20CRM=EF=BC=9A=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E5=95=86=E6=9C=BA=E7=9A=84=E6=96=B0=E5=A2=9E=E3=80=81=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../business/CrmBusinessStatusController.java | 18 +++++--- .../vo/status/CrmBusinessStatusSaveReqVO.java | 2 + .../business/CrmBusinessServiceImpl.java | 43 ++++++++++++++++++- .../business/CrmBusinessStatusService.java | 7 +++ .../CrmBusinessStatusServiceImpl.java | 13 ++++-- .../service/contact/CrmContactService.java | 7 +++ .../contact/CrmContactServiceImpl.java | 5 +++ 7 files changed, 84 insertions(+), 11 deletions(-) diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessStatusController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessStatusController.java index bdc44679d..0663d1f28 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessStatusController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/CrmBusinessStatusController.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.crm.controller.admin.business; +import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -29,6 +30,7 @@ import java.util.Map; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @Tag(name = "管理后台 - CRM 商机状态") @RestController @@ -62,7 +64,7 @@ public class CrmBusinessStatusController { @DeleteMapping("/delete") @Operation(summary = "删除商机状态") @Parameter(name = "id", description = "编号", required = true) - @PreAuthorize("@ss.hasPermission('crm:business-status-type:delete')") + @PreAuthorize("@ss.hasPermission('crm:business-status:delete')") public CommonResult deleteBusinessStatusType(@RequestParam("id") Long id) { businessStatusTypeService.deleteBusinessStatusType(id); return success(true); @@ -71,7 +73,7 @@ public class CrmBusinessStatusController { @GetMapping("/get") @Operation(summary = "获得商机状态") @Parameter(name = "id", description = "编号", required = true, example = "1024") - @PreAuthorize("@ss.hasPermission('crm:business-status-type:query')") + @PreAuthorize("@ss.hasPermission('crm:business-status:query')") public CommonResult getBusinessStatusType(@RequestParam("id") Long id) { CrmBusinessStatusTypeDO statusType = businessStatusTypeService.getBusinessStatusType(id); if (statusType == null) { @@ -84,10 +86,13 @@ public class CrmBusinessStatusController { @GetMapping("/page") @Operation(summary = "获得商机状态分页") - @PreAuthorize("@ss.hasPermission('crm:business-status-type:query')") - public CommonResult> getBusinessStatusTypePage(@Valid PageParam pageReqVO) { + @PreAuthorize("@ss.hasPermission('crm:business-status:query')") + public CommonResult> getBusinessStatusPage(@Valid PageParam pageReqVO) { // 1. 查询数据 PageResult pageResult = businessStatusTypeService.getBusinessStatusTypePage(pageReqVO); + if (CollUtil.isEmpty(pageResult.getList())) { + return success(PageResult.empty(pageResult.getTotal())); + } // 2. 拼接数据 Map userMap = adminUserApi.getUserMap( convertSet(pageResult.getList(), statusType -> Long.parseLong(statusType.getCreator()))); @@ -101,9 +106,12 @@ public class CrmBusinessStatusController { } @GetMapping("/type-simple-list") - @Operation(summary = "获得商机状态列表") + @Operation(summary = "获得商机状态组列表") public CommonResult> getBusinessStatusTypeSimpleList() { List list = businessStatusTypeService.getBusinessStatusTypeList(); + // 过滤掉部门不匹配的 + Long deptId = adminUserApi.getUser(getLoginUserId()).getDeptId(); + list.removeIf(statusType -> CollUtil.isNotEmpty(statusType.getDeptIds()) && !statusType.getDeptIds().contains(deptId)); return success(BeanUtils.toBean(list, CrmBusinessStatusRespVO.class)); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/status/CrmBusinessStatusSaveReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/status/CrmBusinessStatusSaveReqVO.java index 05ea279af..e93305c6a 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/status/CrmBusinessStatusSaveReqVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/status/CrmBusinessStatusSaveReqVO.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.crm.controller.admin.business.vo.status; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import lombok.Data; @@ -24,6 +25,7 @@ public class CrmBusinessStatusSaveReqVO { @Schema(description = "商机状态集合", requiredMode = Schema.RequiredMode.REQUIRED) @NotEmpty(message = "商机状态集合不能为空") + @Valid private List statuses; @Data diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java index 2b4e09e2f..9206f741a 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java @@ -19,11 +19,14 @@ import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission; import cn.iocoder.yudao.module.crm.service.business.bo.CrmBusinessUpdateProductReqBO; import cn.iocoder.yudao.module.crm.service.contact.CrmContactBusinessService; +import cn.iocoder.yudao.module.crm.service.contact.CrmContactService; import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; +import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO; import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; import cn.iocoder.yudao.module.crm.service.product.CrmProductService; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import com.mzt.logapi.context.LogRecordContext; import com.mzt.logapi.service.impl.DiffParseFunction; import com.mzt.logapi.starter.annotation.LogRecord; @@ -57,16 +60,26 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @Resource private CrmBusinessProductMapper businessProductMapper; + @Resource + private CrmBusinessStatusService businessStatusService; @Resource @Lazy // 延迟加载,避免循环依赖 private CrmContractService contractService; @Resource + private CrmCustomerService customerService; + @Resource + @Lazy // 延迟加载,避免循环依赖 + private CrmContactService contactService; + @Resource private CrmPermissionService permissionService; @Resource private CrmContactBusinessService contactBusinessService; @Resource private CrmProductService productService; + @Resource + private AdminUserApi adminUserApi; + @Override @Transactional(rollbackFor = Exception.class) @LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_CREATE_SUB_TYPE, bizNo = "{{#business.id}}", @@ -74,10 +87,12 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { public Long createBusiness(CrmBusinessSaveReqVO createReqVO, Long userId) { // 1.1 校验产品项的有效性 List businessProducts = validateBusinessProducts(createReqVO.getProducts()); - // 1.2 TODO 芋艿:校验关联字 + // 1.2 校验关联字段 + validateBusinessForCreate(createReqVO); // 2.1 插入商机 CrmBusinessDO business = BeanUtils.toBean(createReqVO, CrmBusinessDO.class).setOwnerUserId(userId); + business.setStatusId(businessStatusService.getBusinessStatusListByTypeId(createReqVO.getStatusTypeId()).get(0).getId()); // 默认状态 calculateTotalPrice(business, businessProducts); businessMapper.insert(business); // 2.2 插入商机关联商品 @@ -101,6 +116,9 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { // TODO @lzxhqs:CrmContactBusinessService 调用这个;这样逻辑才能收敛哈; private void createContactBusiness(Long businessId, Long contactId) { + if (contactId == null) { + return; + } CrmContactBusinessDO contactBusiness = new CrmContactBusinessDO(); contactBusiness.setBusinessId(businessId); contactBusiness.setContactId(contactId); @@ -113,11 +131,13 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { success = CRM_BUSINESS_UPDATE_SUCCESS) @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) public void updateBusiness(CrmBusinessSaveReqVO updateReqVO) { + updateReqVO.setOwnerUserId(null).setStatusTypeId(null); // 不允许更新的字段 // 1.1 校验存在 CrmBusinessDO oldBusiness = validateBusinessExists(updateReqVO.getId()); // 1.2 校验产品项的有效性 List businessProducts = validateBusinessProducts(updateReqVO.getProducts()); - // 1.3 TODO 芋艿:校验关联字 + // 1.3 校验关联字段 + validateBusinessForCreate(updateReqVO); // 2.1 更新商机 CrmBusinessDO updateObj = BeanUtils.toBean(updateReqVO, CrmBusinessDO.class); @@ -148,6 +168,25 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { } } + private void validateBusinessForCreate(CrmBusinessSaveReqVO saveReqVO) { + // 校验商机状态 + if (saveReqVO.getStatusTypeId() != null) { + businessStatusService.validateBusinessStatusType(saveReqVO.getStatusTypeId()); + } + // 校验客户 + if (saveReqVO.getCustomerId() != null) { + customerService.validateCustomer(saveReqVO.getCustomerId()); + } + // 校验联系人 + if (saveReqVO.getContactId() != null) { + contactService.validateContact(saveReqVO.getContactId()); + } + // 校验负责人 + if (saveReqVO.getOwnerUserId() != null) { + adminUserApi.validateUser(saveReqVO.getOwnerUserId()); + } + } + private List validateBusinessProducts(List list) { // 1. 校验产品存在 productService.validProductList(convertSet(list, CrmBusinessSaveReqVO.Product::getProductId)); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusService.java index c813f37cf..cc527ec3e 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusService.java @@ -50,6 +50,13 @@ public interface CrmBusinessStatusService { */ CrmBusinessStatusTypeDO getBusinessStatusType(Long id); + /** + * 校验商机状态组 + * + * @param id 编号 + */ + void validateBusinessStatusType(Long id); + /** * 获得商机状态组列表 * diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusServiceImpl.java index 349b112c2..580b431aa 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessStatusServiceImpl.java @@ -68,7 +68,7 @@ public class CrmBusinessStatusServiceImpl implements CrmBusinessStatusService { @Transactional(rollbackFor = Exception.class) public void updateBusinessStatus(CrmBusinessStatusSaveReqVO updateReqVO) { // 1.1 校验存在 - validateBusinessStatusTypeNameUnique(updateReqVO.getId()); + validateBusinessStatusTypeExists(updateReqVO.getId()); // 1.2 校验名称是否存在 validateBusinessStatusTypeNameUnique(updateReqVO.getName(), updateReqVO.getId()); // 1.3 设置状态的排序 @@ -104,7 +104,7 @@ public class CrmBusinessStatusServiceImpl implements CrmBusinessStatusService { } } - private void validateBusinessStatusTypeNameUnique(Long id) { + private void validateBusinessStatusTypeExists(Long id) { if (businessStatusTypeMapper.selectById(id) == null) { throw exception(BUSINESS_STATUS_TYPE_NOT_EXISTS); } @@ -123,7 +123,7 @@ public class CrmBusinessStatusServiceImpl implements CrmBusinessStatusService { @Transactional(rollbackFor = Exception.class) public void deleteBusinessStatusType(Long id) { // 1.1 校验存在 - validateBusinessStatusTypeNameUnique(id); + validateBusinessStatusTypeExists(id); // 1.2 已经使用,无法更新 if (businessService.getBusinessCountByStatusTypeId(id) > 0) { throw exception(BUSINESS_STATUS_DELETE_FAIL_USED); @@ -140,6 +140,11 @@ public class CrmBusinessStatusServiceImpl implements CrmBusinessStatusService { return businessStatusTypeMapper.selectById(id); } + @Override + public void validateBusinessStatusType(Long id) { + validateBusinessStatusTypeExists(id); + } + @Override public List getBusinessStatusTypeList() { return businessStatusTypeMapper.selectList(); @@ -147,7 +152,7 @@ public class CrmBusinessStatusServiceImpl implements CrmBusinessStatusService { @Override public PageResult getBusinessStatusTypePage(PageParam pageReqVO) { - return null; + return businessStatusTypeMapper.selectPage(pageReqVO); } @Override diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java index a096ed232..4f7c6de22 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactService.java @@ -87,6 +87,13 @@ public interface CrmContactService { */ CrmContactDO getContact(Long id); + /** + * 校验联系人 + * + * @param id 编号 + */ + void validateContact(Long id); + /** * 获得联系人列表 * diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java index 7b89167e0..b073889cd 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactServiceImpl.java @@ -229,6 +229,11 @@ public class CrmContactServiceImpl implements CrmContactService { return contactMapper.selectById(id); } + @Override + public void validateContact(Long id) { + validateContactExists(id); + } + @Override public List getContactListByIds(Collection ids, Long userId) { if (CollUtil.isEmpty(ids)) {