From f361d05940e3e5ac91004fd5e51cad5e34749858 Mon Sep 17 00:00:00 2001 From: lzxhqs <913313101@qq.com> Date: Sun, 14 Jan 2024 09:52:35 +0800 Subject: [PATCH 01/27] =?UTF-8?q?=E5=95=86=E6=9C=BA=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/optinal/crm_20240114.sql | 55 +++++++++++ .../module/crm/enums/ErrorCodeConstants.java | 1 + .../crm/enums/business/CrmBizEndStatus.java | 52 ++++++++++ yudao-module-crm/yudao-module-crm-biz/pom.xml | 5 + .../admin/business/CrmBusinessController.java | 4 +- .../CrmBusinessStatusTypeController.java | 12 ++- .../vo/business/CrmBusinessSaveReqVO.java | 75 ++++++++++++++ .../product/CrmBusinessProductPageReqVO.java | 18 ++++ .../vo/product/CrmBusinessProductRespVO.java | 14 +++ .../product/CrmBusinessProductSaveReqVO.java | 50 ++++++++++ .../type/CrmBusinessStatusTypeSaveReqVO.java | 2 +- .../convert/business/CrmBusinessConvert.java | 2 +- .../CrmBusinessProductConvert.java | 20 ++++ .../CrmBusinessStatusTypeConvert.java | 6 +- .../dataobject/business/CrmBusinessDO.java | 4 + .../business/CrmBusinessProductDO.java | 74 ++++++++++++++ .../business/CrmBusinessStatusDO.java | 2 +- .../business/CrmBusinessStatusTypeDO.java | 2 + .../business/CrmBusinessProductMapper.java | 21 ++++ .../business/CrmBusinessStatusTypeMapper.java | 11 +++ .../dal/mysql/contract/CrmContractMapper.java | 3 + .../service/business/CrmBusinessService.java | 9 +- .../business/CrmBusinessServiceImpl.java | 98 +++++++++++++++++-- .../CrmBusinessStatusTypeServiceImpl.java | 16 +-- .../business/CrmBusinessServiceImplTest.java | 7 +- 25 files changed, 527 insertions(+), 36 deletions(-) create mode 100644 sql/mysql/optinal/crm_20240114.sql create mode 100644 yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/business/CrmBizEndStatus.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductPageReqVO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductRespVO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductSaveReqVO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessproduct/CrmBusinessProductConvert.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessProductDO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessProductMapper.java diff --git a/sql/mysql/optinal/crm_20240114.sql b/sql/mysql/optinal/crm_20240114.sql new file mode 100644 index 000000000..24f25d4ef --- /dev/null +++ b/sql/mysql/optinal/crm_20240114.sql @@ -0,0 +1,55 @@ + +-- ---------------------------- +-- Table structure for crm_business_product +-- ---------------------------- +DROP TABLE IF EXISTS `crm_business_product`; +CREATE TABLE `crm_business_product` ( + `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键', + `business_id` bigint(0) NOT NULL COMMENT '商机ID', + `product_id` bigint(0) NOT NULL COMMENT '产品ID', + `price` decimal(18, 2) NOT NULL COMMENT '产品单价', + `sales_price` decimal(18, 2) NULL DEFAULT NULL COMMENT '销售价格', + `num` int(0) NULL DEFAULT NULL COMMENT '数量', + `discount` decimal(10, 2) NULL DEFAULT NULL COMMENT '折扣', + `subtotal` decimal(18, 2) NULL DEFAULT NULL COMMENT '小计(折扣后价格)', + `unit` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '单位', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint(0) NOT NULL DEFAULT 1 COMMENT '租户编号', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 29 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '商机产品关联表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for crm_business_status +-- ---------------------------- +DROP TABLE IF EXISTS `crm_business_status`; +CREATE TABLE `crm_business_status` ( + `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `type_id` bigint(0) NOT NULL COMMENT '状态类型编号', + `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '状态名', + `percent` bigint(0) NULL DEFAULT NULL COMMENT '赢单率', + `sort` int(0) NULL DEFAULT NULL COMMENT '排序', + `tenant_id` bigint(0) NOT NULL DEFAULT 0 COMMENT '租户编号', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '商机状态' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Table structure for crm_business_status_type +-- ---------------------------- +DROP TABLE IF EXISTS `crm_business_status_type`; +CREATE TABLE `crm_business_status_type` ( + `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '状态类型名', + `dept_ids` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '使用的部门编号', + `status` int(0) NOT NULL DEFAULT 1 COMMENT '开启状态', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint(0) NOT NULL DEFAULT 0 COMMENT '租户编号', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '商机状态类型' ROW_FORMAT = Dynamic; 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 84df67c13..0132d7d13 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 @@ -17,6 +17,7 @@ public interface ErrorCodeConstants { // ========== 商机管理 1-020-002-000 ========== ErrorCode BUSINESS_NOT_EXISTS = new ErrorCode(1_020_002_000, "商机不存在"); + ErrorCode BUSINESS_CONTRACT_EXISTS = new ErrorCode(1_020_002_001, "商机已关联合同,不能删除"); // TODO @lilleo:商机状态、商机类型,都单独错误码段 diff --git a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/business/CrmBizEndStatus.java b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/business/CrmBizEndStatus.java new file mode 100644 index 000000000..f84610e8d --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/business/CrmBizEndStatus.java @@ -0,0 +1,52 @@ +package cn.iocoder.yudao.module.crm.enums.business; + +import cn.hutool.core.util.ObjUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.Arrays; + +/** + * @author lzxhqs + * @version 1.0 + * @title CrmBizEndStatus + * @description + * @create 2024/1/12 + */ +@RequiredArgsConstructor +@Getter +public enum CrmBizEndStatus implements IntArrayValuable { + WIN(1, "赢单"), + LOSE(2, "输单"), + INVALID(3, "无效"); + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmBizEndStatus::getStatus).toArray(); + + public static boolean isWin(Integer status) { + return ObjectUtil.equal(WIN.getStatus(), status); + } + + public static boolean isLose(Integer status) { + return ObjectUtil.equal(LOSE.getStatus(), status); + } + + public static boolean isInvalid(Integer status) { + return ObjectUtil.equal(INVALID.getStatus(), status); + } + + /** + * 场景类型 + */ + private final Integer status; + /** + * 场景名称 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } +} diff --git a/yudao-module-crm/yudao-module-crm-biz/pom.xml b/yudao-module-crm/yudao-module-crm-biz/pom.xml index 9e1a9e152..1d74efbef 100644 --- a/yudao-module-crm/yudao-module-crm-biz/pom.xml +++ b/yudao-module-crm/yudao-module-crm-biz/pom.xml @@ -22,6 +22,11 @@ yudao-module-system-api ${revision} + + cn.iocoder.boot + yudao-module-system-biz + ${revision} + cn.iocoder.boot yudao-module-crm-api 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 fe8181daf..6bedee3cb 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 @@ -55,14 +55,14 @@ public class CrmBusinessController { @PostMapping("/create") @Operation(summary = "创建商机") @PreAuthorize("@ss.hasPermission('crm:business:create')") - public CommonResult createBusiness(@Valid @RequestBody CrmBusinessCreateReqVO createReqVO) { + public CommonResult createBusiness(@Valid @RequestBody CrmBusinessSaveReqVO createReqVO) { return success(businessService.createBusiness(createReqVO, getLoginUserId())); } @PutMapping("/update") @Operation(summary = "更新商机") @PreAuthorize("@ss.hasPermission('crm:business:update')") - public CommonResult updateBusiness(@Valid @RequestBody CrmBusinessUpdateReqVO updateReqVO) { + public CommonResult updateBusiness(@Valid @RequestBody CrmBusinessSaveReqVO updateReqVO) { businessService.updateBusiness(updateReqVO); return success(true); } 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 index cd4a60e81..9f2e3fbf1 100644 --- 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 @@ -4,6 +4,7 @@ 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; @@ -101,11 +102,12 @@ public class CrmBusinessStatusTypeController { PageResult pageResult = businessStatusTypeService.getBusinessStatusTypePage(pageReqVO); // 处理部门回显 // TODO @ljlleo:可以使用 CollectionUtils.convertSet 替代常用的 stream 操作,更简洁一点;下面几个也是哈; - Set deptIds = pageResult.getList().stream() - .map(CrmBusinessStatusTypeDO::getDeptIds) - .filter(Objects::nonNull) - .flatMap(Collection::stream) - .collect(Collectors.toSet()); +// Set deptIds = pageResult.getList().stream() +// .map(CrmBusinessStatusTypeDO::getDeptIds) +// .filter(Objects::nonNull) +// .flatMap(Collection::stream) +// .collect(Collectors.toSet()); + Set deptIds = CollectionUtils.convertSetByFlatMap(pageResult.getList(), CrmBusinessStatusTypeDO::getDeptIds,Collection::stream); List deptList = deptApi.getDeptList(deptIds); return success(CrmBusinessStatusTypeConvert.INSTANCE.convertPage(pageResult, deptList)); } 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 new file mode 100644 index 000000000..2a17735bb --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/business/CrmBusinessSaveReqVO.java @@ -0,0 +1,75 @@ +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.controller.admin.product.vo.product.CrmProductSaveReqVO; +import cn.iocoder.yudao.module.crm.enums.business.CrmBizEndStatus; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +/** + * @author lzxhqs + */ +@Schema(description = "管理后台 - CRM 商机创建/更新 Request VO") +@Data +public class CrmBusinessSaveReqVO { + + @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "32129") + private Long id; + + @Schema(description = "商机名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") + @NotNull(message = "商机名称不能为空") + 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; + + @Schema(description = "整单折扣") + private Integer discountPercent; + + @Schema(description = "产品总金额", example = "12025") + private BigDecimal productPrice; + + @Schema(description = "备注", example = "随便") + private String remark; + + @Schema(description = "联系人编号", example = "110") + @NotNull(message = "联系人编号不能为空") + private Long contactId; + + @Schema(description = "1赢单2输单3无效", example = "1") + @InEnum(CrmBizEndStatus.class) + private Integer endStatus; + + @Schema(description = "产品列表", example = "") + private List product = new ArrayList<>(); + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductPageReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductPageReqVO.java new file mode 100644 index 000000000..fcf406b5d --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductPageReqVO.java @@ -0,0 +1,18 @@ +package cn.iocoder.yudao.module.crm.controller.admin.business.vo.product; + +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; + + +/** + * @author lzxhqs + */ +@Schema(description = "管理后台 - 商机产品分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class CrmBusinessProductPageReqVO extends PageParam { +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductRespVO.java new file mode 100644 index 000000000..4d24bd3c5 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductRespVO.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.crm.controller.admin.business.vo.product; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * @author lzxhqs + */ +@Schema(description = "管理后台 - 商机产品关联 Response VO") +@Data +@ExcelIgnoreUnannotated +public class CrmBusinessProductRespVO { +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductSaveReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductSaveReqVO.java new file mode 100644 index 000000000..ddcc603c9 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductSaveReqVO.java @@ -0,0 +1,50 @@ +package cn.iocoder.yudao.module.crm.controller.admin.business.vo.product; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * @author lzxhqs + */ +@Schema(description = "管理后台 - CRM 商机产品关联表 创建/更新 Request VO") +@Data +public class CrmBusinessProductSaveReqVO { + + @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "32129") + private Long id; + + @Schema(description = "商机ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") + @NotNull(message = "商机ID不能为空") + private Integer businessId; + + @Schema(description = "产品ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") + @NotNull(message = "产品ID不能为空") + private Integer productId; + + @Schema(description = "产品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") + @NotNull(message = "产品单价不能为空") + private BigDecimal price; + + @Schema(description = "销售价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") + @NotNull(message = "销售价格不能为空") + private BigDecimal salesPrice; + + @Schema(description = "数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") + @NotNull(message = "数量不能为空") + private BigDecimal num; + + @Schema(description = "折扣", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") + @NotNull(message = "折扣不能为空") + private BigDecimal discount; + + @Schema(description = "小计(折扣后价格)", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") + @NotNull(message = "小计(折扣后价格)不能为空") + private BigDecimal subtotal; + + @Schema(description = "单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") + @NotNull(message = "单位不能为空") + private String unit; +} 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 index 096b42e1f..3d61bed1d 100644 --- 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 @@ -24,6 +24,6 @@ public class CrmBusinessStatusTypeSaveReqVO { // TODO @ljlleo VO 里面,我们不使用默认值哈。这里 Lists.newArrayList() 看看怎么去掉。上面 deptIds 也是类似噢 @Schema(description = "商机状态集合", requiredMode = Schema.RequiredMode.REQUIRED) - private List statusList = Lists.newArrayList(); + private List statusList; } 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 a67812f8b..bd65b3901 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 @@ -27,7 +27,7 @@ public interface CrmBusinessConvert { CrmBusinessConvert INSTANCE = Mappers.getMapper(CrmBusinessConvert.class); - CrmBusinessDO convert(CrmBusinessCreateReqVO bean); + CrmBusinessDO convert(CrmBusinessSaveReqVO bean); CrmBusinessDO convert(CrmBusinessUpdateReqVO bean); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessproduct/CrmBusinessProductConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessproduct/CrmBusinessProductConvert.java new file mode 100644 index 000000000..2351aafa2 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessproduct/CrmBusinessProductConvert.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.crm.convert.businessproduct; + +import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductSaveReqVO; +import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author lzxhqs + * @version 1.0 + * @title CrmBusinessProductConvert + * @description + * @create 2024/1/12 + */ +@Mapper +public interface CrmBusinessProductConvert { + CrmBusinessProductConvert INSTANCE = Mappers.getMapper(CrmBusinessProductConvert.class); + + CrmBusinessProductDO convert(CrmProductSaveReqVO product); +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessstatustype/CrmBusinessStatusTypeConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessstatustype/CrmBusinessStatusTypeConvert.java index ae7e36122..0f6e01439 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessstatustype/CrmBusinessStatusTypeConvert.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessstatustype/CrmBusinessStatusTypeConvert.java @@ -41,9 +41,9 @@ public interface CrmBusinessStatusTypeConvert { default CrmBusinessStatusTypeRespVO convert(CrmBusinessStatusTypeDO bean, List statusList) { // TODO @ljlleo 可以链式赋值,简化成一行; - CrmBusinessStatusTypeRespVO result = convert(bean); - result.setStatusList(statusList); - return result; +// CrmBusinessStatusTypeRespVO result = convert(bean); +// result.setStatusList(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 f1d5d4431..68b5f087b 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 @@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.crm.dal.dataobject.business; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; +import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -52,6 +54,7 @@ public class CrmBusinessDO extends BaseDO { * 客户编号 * * TODO @ljileo:这个字段,后续要写下关联的实体哈 + * 关联 {@link CrmCustomerDO#getId()} */ private Long customerId; /** @@ -101,6 +104,7 @@ public class CrmBusinessDO extends BaseDO { * 负责人的用户编号 * * 关联 AdminUserDO 的 id 字段 + * {@link AdminUserDO#getId()} */ private Long ownerUserId; 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 new file mode 100644 index 000000000..3f146c3b3 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessProductDO.java @@ -0,0 +1,74 @@ +package cn.iocoder.yudao.module.crm.dal.dataobject.business; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.crm.dal.dataobject.product.CrmProductDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +import java.math.BigDecimal; + +/** + * 商机产品关联表 DO + * + * @author lzxhqs + */ +@TableName("crm_business_product") +@KeySequence("crm_business_product_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class CrmBusinessProductDO extends BaseDO { + + /** + * 主键 + */ + @TableId + private Long id; + + /** + * 商机ID + * 关联 {@link CrmBusinessDO#getId()} + */ + private Long businessId; + + /** + * 产品ID + * 关联{@link CrmProductDO#getId()} + */ + private Long productId; + + /** + * 产品单价 + */ + private BigDecimal price; + + /** + * 销售价格 + */ + private BigDecimal salesPrice; + + /** + * 数量 + */ + private BigDecimal num; + + /** + * 折扣 + */ + private BigDecimal discount; + + /** + * 小计(折扣后价格) + */ + private BigDecimal subtotal; + + /** + * 单位 + */ + private String unit; +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessStatusDO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessStatusDO.java index f83d0fb27..40c99936b 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessStatusDO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessStatusDO.java @@ -39,7 +39,7 @@ public class CrmBusinessStatusDO { * * TODO 这里是不是改成 Integer 存储,百分比 * 100 ; */ - private String percent; + private Integer percent; /** * 排序 */ 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 d0d2f11f2..75f0094a1 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,5 +1,6 @@ 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; @@ -43,6 +44,7 @@ public class CrmBusinessStatusTypeDO extends BaseDO { * 开启状态 * * 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/CrmBusinessProductMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessProductMapper.java new file mode 100644 index 000000000..37a193f1f --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessProductMapper.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.crm.dal.mysql.business; + + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * 商机产品 Mapper + * @author lzxhqs + */ +@Mapper +public interface CrmBusinessProductMapper extends BaseMapperX { + default void deleteByBusinessId(Long id) { + delete(CrmBusinessProductDO::getBusinessId, id); + } + + default CrmBusinessProductDO selectByBusinessId(Long id) { + return selectOne(CrmBusinessProductDO::getBusinessId, id); + } +} 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 af10bf8c7..9b90549a1 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 @@ -28,4 +28,15 @@ public interface CrmBusinessStatusTypeMapper extends BaseMapperX { default Long selectCountByContactId(Long contactId) { return selectCount(CrmContractDO::getContactId, contactId); } + default CrmContractDO selectByBizId(Long businessId) { + return selectOne(CrmContractDO::getBusinessId, businessId); + } } 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 c2b132648..cff45b3ba 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 @@ -1,10 +1,7 @@ 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.business.CrmBusinessCreateReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessUpdateReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.*; import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; @@ -27,14 +24,14 @@ public interface CrmBusinessService { * @param userId 用户编号 * @return 编号 */ - Long createBusiness(@Valid CrmBusinessCreateReqVO createReqVO, Long userId); + Long createBusiness(@Valid CrmBusinessSaveReqVO createReqVO, Long userId); /** * 更新商机 * * @param updateReqVO 更新信息 */ - void updateBusiness(@Valid CrmBusinessUpdateReqVO updateReqVO); + void updateBusiness(@Valid CrmBusinessSaveReqVO updateReqVO); /** * 删除商机 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 03a14ceb6..9d56b72b8 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 @@ -4,14 +4,18 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; 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.business.CrmBusinessCreateReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessTransferReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessUpdateReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.*; +import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductSaveReqVO; import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessConvert; +import cn.iocoder.yudao.module.crm.convert.businessproduct.CrmBusinessProductConvert; 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.contract.CrmContractDO; 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.dal.mysql.contactbusinesslink.CrmContactBusinessMapper; +import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper; import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum; import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission; @@ -26,11 +30,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.ArrayList; import java.util.Collection; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.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.*; @@ -46,6 +53,13 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @Resource private CrmBusinessMapper businessMapper; + @Resource + private CrmBusinessProductMapper businessProductMapper; + @Resource + private CrmContractMapper contractMapper; + + @Resource + private CrmContactBusinessMapper contactBusinessMapper; @Resource private CrmPermissionService permissionService; @Resource @@ -55,29 +69,79 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @Transactional(rollbackFor = Exception.class) @LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_CREATE_SUB_TYPE, bizNo = "{{#business.id}}", success = CRM_BUSINESS_CREATE_SUCCESS) - public Long createBusiness(CrmBusinessCreateReqVO createReqVO, Long userId) { + public Long createBusiness(CrmBusinessSaveReqVO createReqVO, Long userId) { // 1. 插入商机 CrmBusinessDO business = CrmBusinessConvert.INSTANCE.convert(createReqVO); businessMapper.insert(business); // TODO 商机待定:插入商机与产品的关联表;校验商品存在 - + verifyCrmBusinessProduct(business.getId()); + if (!createReqVO.getProduct().isEmpty()) { + createBusinessProducts(createReqVO.getProduct(), business.getId()); + } // TODO 商机待定:在联系人的详情页,如果直接【新建商机】,则需要关联下。这里要搞个 CrmContactBusinessDO 表 + createContactBusiness(business.getId(), createReqVO.getContactId()); // 2. 创建数据权限 + // 设置当前操作的人为负责人 permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType()) - .setBizId(business.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 设置当前操作的人为负责人 + .setBizId(business.getId()).setUserId(userId).setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); // 4. 记录操作日志上下文 LogRecordContext.putVariable("business", business); return business.getId(); } + /** + * @param businessId 商机id + * @param contactId 联系人id + * @throws + * @description 联系人与商机的关联 + * @author lzxhqs + */ + private void createContactBusiness(Long businessId, Long contactId) { + CrmContactBusinessDO contactBusiness = new CrmContactBusinessDO(); + contactBusiness.setBusinessId(businessId); + contactBusiness.setContactId(contactId); + contactBusinessMapper.insert(contactBusiness); + + } + + /** + * @param products 产品集合 + * @description 插入商机产品关联表 + * @author lzxhqs + */ + private void createBusinessProducts(List products, Long businessId) { + List list = new ArrayList<>(); + for (CrmProductSaveReqVO product : products) { + CrmBusinessProductDO businessProductDO = new CrmBusinessProductDO(); + businessProductDO.setBusinessId(businessId) + .setProductId(product.getId()) + .setPrice(BigDecimal.valueOf(product.getPrice())); + list.add(businessProductDO); + } + businessProductMapper.insertBatch(list); + } + + /** + * @param id businessId + * @description 校验管理的产品存在则删除 + * @author lzxhqs + */ + private void verifyCrmBusinessProduct(Long id) { + CrmBusinessProductDO businessProductDO = businessProductMapper.selectByBusinessId(id); + if (businessProductDO != null) { + //通过商机Id删除 + businessProductMapper.deleteByBusinessId(id); + } + + } @Override @Transactional(rollbackFor = Exception.class) @LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}", success = CRM_BUSINESS_UPDATE_SUCCESS) @CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) - public void updateBusiness(CrmBusinessUpdateReqVO updateReqVO) { + public void updateBusiness(CrmBusinessSaveReqVO updateReqVO) { // 1. 校验存在 CrmBusinessDO oldBusiness = validateBusinessExists(updateReqVO.getId()); @@ -85,6 +149,10 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { CrmBusinessDO updateObj = CrmBusinessConvert.INSTANCE.convert(updateReqVO); businessMapper.updateById(updateObj); // TODO 商机待定:插入商机与产品的关联表;校验商品存在 + verifyCrmBusinessProduct(updateReqVO.getId()); + if (!updateReqVO.getProduct().isEmpty()) { + createBusinessProducts(updateReqVO.getProduct(), updateReqVO.getId()); + } // TODO @商机待定:如果状态发生变化,插入商机状态变更记录表 // 3. 记录操作日志上下文 @@ -101,6 +169,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { // 校验存在 CrmBusinessDO business = validateBusinessExists(id); // TODO @商机待定:需要校验有没关联合同。CrmContractDO 的 businessId 字段 + validateContractExists(id); // 删除 businessMapper.deleteById(id); @@ -111,6 +180,19 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { LogRecordContext.putVariable("businessName", business.getName()); } + /** + * @param businessId 商机id + * @throws + * @description 删除校验合同是关联合同 + * @author lzxhqs + */ + private void validateContractExists(Long businessId) { + CrmContractDO contract = contractMapper.selectByBizId(businessId); + if(contract != null) { + throw exception(BUSINESS_CONTRACT_EXISTS); + } + } + private CrmBusinessDO validateBusinessExists(Long id) { CrmBusinessDO crmBusiness = businessMapper.selectById(id); if (crmBusiness == null) { 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 0ebcda87c..d9845976b 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 @@ -95,14 +95,18 @@ public class CrmBusinessStatusTypeServiceImpl implements CrmBusinessStatusTypeSe // TODO @ljlleo 这个方法,这个参考 validateDeptNameUnique 实现。 private void validateBusinessStatusTypeExists(String name, Long id) { - LambdaQueryWrapper wrapper = new LambdaQueryWrapperX<>(); - if(null != id) { - wrapper.ne(CrmBusinessStatusTypeDO::getId, id); - } - long cnt = businessStatusTypeMapper.selectCount(wrapper.eq(CrmBusinessStatusTypeDO::getName, name)); - if (cnt > 0) { + 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 diff --git a/yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImplTest.java b/yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImplTest.java index 6072b72e6..123b4a981 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImplTest.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/test/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImplTest.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.service.business; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessCreateReqVO; +import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessSaveReqVO; import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessUpdateReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessMapper; @@ -39,7 +40,7 @@ public class CrmBusinessServiceImplTest extends BaseDbUnitTest { @Test public void testCreateBusiness_success() { // 准备参数 - CrmBusinessCreateReqVO reqVO = randomPojo(CrmBusinessCreateReqVO.class); + CrmBusinessSaveReqVO reqVO = randomPojo(CrmBusinessSaveReqVO.class); // 调用 Long businessId = businessService.createBusiness(reqVO, getLoginUserId()); @@ -56,7 +57,7 @@ public class CrmBusinessServiceImplTest extends BaseDbUnitTest { CrmBusinessDO dbBusiness = randomPojo(CrmBusinessDO.class); businessMapper.insert(dbBusiness);// @Sql: 先插入出一条存在的数据 // 准备参数 - CrmBusinessUpdateReqVO reqVO = randomPojo(CrmBusinessUpdateReqVO.class, o -> { + CrmBusinessSaveReqVO reqVO = randomPojo(CrmBusinessSaveReqVO.class, o -> { o.setId(dbBusiness.getId()); // 设置更新的 ID }); @@ -70,7 +71,7 @@ public class CrmBusinessServiceImplTest extends BaseDbUnitTest { @Test public void testUpdateBusiness_notExists() { // 准备参数 - CrmBusinessUpdateReqVO reqVO = randomPojo(CrmBusinessUpdateReqVO.class); + CrmBusinessSaveReqVO reqVO = randomPojo(CrmBusinessSaveReqVO.class); // 调用, 并断言异常 assertServiceException(() -> businessService.updateBusiness(reqVO), BUSINESS_NOT_EXISTS); From a886ad978553427ef532bf295e81fd9014e26a31 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 15 Jan 2024 21:30:32 +0800 Subject: [PATCH 02/27] =?UTF-8?q?=F0=9F=93=96=20CRM=EF=BC=9A=E8=B7=9F?= =?UTF-8?q?=E8=BF=9B=E8=AE=B0=E5=BD=95=E7=9A=84=20code=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/iocoder/yudao/module/crm/enums/DictTypeConstants.java | 2 +- .../crm/service/followup/CrmFollowUpRecordServiceImpl.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/DictTypeConstants.java b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/DictTypeConstants.java index 13c202550..22bb0b426 100644 --- a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/DictTypeConstants.java +++ b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/DictTypeConstants.java @@ -13,6 +13,6 @@ public interface DictTypeConstants { String CRM_AUDIT_STATUS = "crm_audit_status"; // CRM 审批状态 String CRM_PRODUCT_UNIT = "crm_product_unit"; // CRM 产品单位 String CRM_PRODUCT_STATUS = "crm_product_status"; // CRM 产品状态 - String CRM_FOLLOW_UP_TYPE = "crm_follow_up_type"; // 跟进方式 + String CRM_FOLLOW_UP_TYPE = "crm_follow_up_type"; // CRM 跟进方式 } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java index ab5a64d35..213128954 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java @@ -25,6 +25,7 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService { @Resource private CrmFollowUpRecordMapper crmFollowUpRecordMapper; + // TODO @puhui999:数据权限 @Override public Long createFollowUpRecord(CrmFollowUpRecordSaveReqVO createReqVO) { CrmFollowUpRecordDO followUpRecord = BeanUtils.toBean(createReqVO, CrmFollowUpRecordDO.class); @@ -34,6 +35,7 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService { return followUpRecord.getId(); } + // TODO @puhui999:不能编辑~~~ @Override public void updateFollowUpRecord(CrmFollowUpRecordSaveReqVO updateReqVO) { // 校验存在 @@ -43,6 +45,7 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService { crmFollowUpRecordMapper.updateById(updateObj); } + // TODO @puhui999:数据权限 @Override public void deleteFollowUpRecord(Long id) { // 校验存在 @@ -62,6 +65,7 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService { return crmFollowUpRecordMapper.selectById(id); } + // TODO @puhui999:数据权限 @Override public PageResult getFollowUpRecordPage(CrmFollowUpRecordPageReqVO pageReqVO) { return crmFollowUpRecordMapper.selectPage(pageReqVO); From 5ae1d0ab3ed92c1949ad40113b60ad7c5f84d5ad Mon Sep 17 00:00:00 2001 From: kyle <573984425@qq.com> Date: Tue, 16 Jan 2024 11:09:02 +0800 Subject: [PATCH 03/27] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D3=E5=A4=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. AreaConvert缺少两个方法导致编译报缺少转换函数 2. 修复SocialUserBindReqVO.java在因为lombok和mapstruct的问题,导致报未知属性的问题 3. 修复Bpm报缺少AsyncTaskExecutor的问题 --- .../flowable/config/YudaoFlowableConfiguration.java | 4 ++-- .../admin/socail/vo/user/SocialUserBindReqVO.java | 3 +++ .../yudao/module/system/convert/ip/AreaConvert.java | 8 ++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/config/YudaoFlowableConfiguration.java b/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/config/YudaoFlowableConfiguration.java index 6d657a1b4..859eca510 100644 --- a/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/config/YudaoFlowableConfiguration.java +++ b/yudao-framework/yudao-spring-boot-starter-flowable/src/main/java/cn/iocoder/yudao/framework/flowable/config/YudaoFlowableConfiguration.java @@ -17,8 +17,8 @@ public class YudaoFlowableConfiguration { * * 如果不创建,会导致项目启动时,Flowable 报错的问题 */ - @Bean - @ConditionalOnMissingBean + @Bean(name = "applicationTaskExecutor") + @ConditionalOnMissingBean(name = "applicationTaskExecutor") public AsyncListenableTaskExecutor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(8); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/vo/user/SocialUserBindReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/vo/user/SocialUserBindReqVO.java index 5ed0042a8..815f367fa 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/vo/user/SocialUserBindReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/vo/user/SocialUserBindReqVO.java @@ -31,4 +31,7 @@ public class SocialUserBindReqVO { @NotEmpty(message = "state 不能为空") private String state; + public Integer getType() { + return type; + } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/ip/AreaConvert.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/ip/AreaConvert.java index ae98bd25d..6ba76ef92 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/ip/AreaConvert.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/ip/AreaConvert.java @@ -17,4 +17,12 @@ public interface AreaConvert { List convertList3(List list); + /** + * 缺少单个转换 + * @param value + * @return + */ + AreaNodeRespVO map(Area value); + + AppAreaNodeRespVO map3(Area value); } From e21c262bd7e3ed687b5aa1f640ecdec7066dd352 Mon Sep 17 00:00:00 2001 From: kyle <573984425@qq.com> Date: Tue, 9 Jan 2024 09:43:48 +0800 Subject: [PATCH 04/27] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E6=9F=A5?= =?UTF-8?q?=E6=89=BE=E5=80=99=E9=80=89=E4=BA=BA=E7=9A=84=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../candidate/vo/BpmTaskCandidateVO.java | 27 ++ .../BpmCandidateProcessorConfiguration.java | 53 ++++ .../candidate/BpmCandidateSourceInfo.java | 44 ++++ .../BpmCandidateSourceInfoProcessor.java | 52 ++++ .../BpmCandidateSourceInfoProcessorChain.java | 105 ++++++++ ...didateAdminUserApiSourceInfoProcessor.java | 31 +++ ...pmCandidateDeptApiSourceInfoProcessor.java | 49 ++++ ...pmCandidatePostApiSourceInfoProcessor.java | 39 +++ ...pmCandidateRoleApiSourceInfoProcessor.java | 36 +++ ...CandidateScriptApiSourceInfoProcessor.java | 73 ++++++ ...didateUserGroupApiSourceInfoProcessor.java | 40 +++ ...CandidateSourceInfoProcessorChainTest.java | 248 ++++++++++++++++++ 12 files changed, 797 insertions(+) create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/candidate/vo/BpmTaskCandidateVO.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmCandidateProcessorConfiguration.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfo.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessor.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChain.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateAdminUserApiSourceInfoProcessor.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateDeptApiSourceInfoProcessor.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidatePostApiSourceInfoProcessor.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateRoleApiSourceInfoProcessor.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateScriptApiSourceInfoProcessor.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateUserGroupApiSourceInfoProcessor.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChainTest.java diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/candidate/vo/BpmTaskCandidateVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/candidate/vo/BpmTaskCandidateVO.java new file mode 100644 index 000000000..37e877c54 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/candidate/vo/BpmTaskCandidateVO.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo; + +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleBaseVO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.Set; + +/** + * 流程任务分配规则 Base VO,提供给添加、修改、详细的子 VO 使用 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 + * + * @see BpmTaskAssignRuleBaseVO + */ +@Data +public class BpmTaskCandidateVO { + + @Schema(description = "规则类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "bpm_task_assign_rule_type") + @NotNull(message = "规则类型不能为空") + private Integer type; + + @Schema(description = "规则值数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "1,2,3") + @NotNull(message = "规则值数组不能为空") + private Set options; + +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmCandidateProcessorConfiguration.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmCandidateProcessorConfiguration.java new file mode 100644 index 000000000..b9fde2436 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmCandidateProcessorConfiguration.java @@ -0,0 +1,53 @@ +package cn.iocoder.yudao.module.bpm.framework.bpm.config; + +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; +import cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor.*; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.List; + +/** + * BPM 通用的 Configuration 配置类,提供给 Activiti 和 Flowable + * @author kyle + */ +@Configuration(proxyBeanMethods = false) +public class BpmCandidateProcessorConfiguration { + @Bean + public BpmCandidateAdminUserApiSourceInfoProcessor bpmCandidateAdminUserApiSourceInfoProcessor() { + return new BpmCandidateAdminUserApiSourceInfoProcessor(); + } + + @Bean + public BpmCandidateDeptApiSourceInfoProcessor bpmCandidateDeptApiSourceInfoProcessor() { + return new BpmCandidateDeptApiSourceInfoProcessor(); + } + + @Bean + public BpmCandidatePostApiSourceInfoProcessor bpmCandidatePostApiSourceInfoProcessor() { + return new BpmCandidatePostApiSourceInfoProcessor(); + } + + @Bean + public BpmCandidateRoleApiSourceInfoProcessor bpmCandidateRoleApiSourceInfoProcessor() { + return new BpmCandidateRoleApiSourceInfoProcessor(); + } + + @Bean + public BpmCandidateUserGroupApiSourceInfoProcessor bpmCandidateUserGroupApiSourceInfoProcessor() { + return new BpmCandidateUserGroupApiSourceInfoProcessor(); + } + + /** + * 可以自己定制脚本,然后通过这里设置到处理器里面去 + * @param scriptsOp + * @return + */ + @Bean + public BpmCandidateScriptApiSourceInfoProcessor bpmCandidateScriptApiSourceInfoProcessor(ObjectProvider scriptsOp) { + BpmCandidateScriptApiSourceInfoProcessor bpmCandidateScriptApiSourceInfoProcessor = new BpmCandidateScriptApiSourceInfoProcessor(); + bpmCandidateScriptApiSourceInfoProcessor.setScripts(scriptsOp); + return bpmCandidateScriptApiSourceInfoProcessor; + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfo.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfo.java new file mode 100644 index 000000000..1280a53e5 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfo.java @@ -0,0 +1,44 @@ +package cn.iocoder.yudao.module.bpm.service.candidate; + +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleBaseVO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.flowable.engine.delegate.DelegateExecution; + +import java.util.HashSet; +import java.util.Set; + +/** + * 获取候选人信息 + */ +@AllArgsConstructor +@NoArgsConstructor +@Data +public class BpmCandidateSourceInfo { + + @Schema(description = "流程id") + private String processInstanceId; + + @Schema(description = "当前任务ID") + private String taskId; + + /** + * 通过这些规则,生成最终需要生成的用户 + */ + @Schema(description = "当前任务预选规则") + private Set rules; + + @Schema(description = "源执行流程") + private DelegateExecution execution; + + public void addRule(BpmTaskCandidateVO vo) { + assert vo != null; + if (rules == null) { + rules = new HashSet<>(); + } + rules.add(vo); + } +} \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessor.java new file mode 100644 index 000000000..52a8adaaf --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessor.java @@ -0,0 +1,52 @@ +package cn.iocoder.yudao.module.bpm.service.candidate; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +public interface BpmCandidateSourceInfoProcessor { + /** + * 获取该处理器支持的类型 + * 来自 {@link BpmTaskAssignRuleTypeEnum} + * + * @return + */ + Set getSupportedTypes(); + + /** + * 对规则和人员做校验 + * + * @param type 规则 + * @param options 人员id + */ + void validRuleOptions(Integer type, Set options); + + /** + * 默认的处理 + * 如果想去操作所有的规则,则可以覆盖此方法 + * + * @param request + * @param chain + * @return 必须包含的是用户ID,而不是其他的ID + * @throws Exception + */ + default Set process(BpmCandidateSourceInfo request, BpmCandidateSourceInfoProcessorChain chain) throws Exception { + Set rules = request.getRules(); + Set results = new HashSet<>(); + for (BpmTaskCandidateVO rule : rules) { + // 每个处理器都有机会处理自己支持的事件 + if (CollUtil.contains(getSupportedTypes(), rule.getType())) { + results.addAll(doProcess(request, rule)); + } + } + return results; + } + + default Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { + return Collections.emptySet(); + } +} \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChain.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChain.java new file mode 100644 index 000000000..b33fd7356 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChain.java @@ -0,0 +1,105 @@ +package cn.iocoder.yudao.module.bpm.service.candidate; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; +import org.flowable.engine.delegate.DelegateExecution; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.*; +import java.util.stream.Collectors; + +@Service +public class BpmCandidateSourceInfoProcessorChain { + + // 保存处理节点 + + private List processorList; + @Resource + private AdminUserApi adminUserApi; + + /** + * 可添加其他处理器 + * + * @param processorOp + * @return + */ + @Resource + // 动态扩展处理节点 + public BpmCandidateSourceInfoProcessorChain addProcessor(ObjectProvider processorOp) { + List processor = processorOp.orderedStream().collect(Collectors.toList()); + if (null == processorList) { + processorList = new ArrayList<>(processor.size()); + } + processorList.addAll(processor); + return this; + } + + // 获取处理器处理 + public Set process(BpmCandidateSourceInfo sourceInfo) throws Exception { + // Verify our parameters + if (sourceInfo == null) { + throw new IllegalArgumentException(); + } + for (BpmCandidateSourceInfoProcessor processor : processorList) { + try { + for (BpmTaskCandidateVO vo : sourceInfo.getRules()) { + processor.validRuleOptions(vo.getType(), vo.getOptions()); + } + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + Set saveResult = Collections.emptySet(); + Exception saveException = null; + for (BpmCandidateSourceInfoProcessor processor : processorList) { + try { + saveResult = processor.process(sourceInfo, this); + if (CollUtil.isNotEmpty(saveResult)) { + removeDisableUsers(saveResult); + break; + } + } catch (Exception e) { + saveException = e; + break; + } + } + // Return the exception or result state from the last execute() + if ((saveException != null)) { + throw saveException; + } else { + return (saveResult); + } + } + + public Set calculateTaskCandidateUsers(DelegateExecution execution, BpmCandidateSourceInfo sourceInfo) { + sourceInfo.setExecution(execution); + Set results = Collections.emptySet(); + try { + results = process(sourceInfo); + } catch (Exception e) { + e.printStackTrace(); + } + return results; + } + + /** + * 移除禁用用户 + * @param assigneeUserIds + */ + public void removeDisableUsers(Set assigneeUserIds) { + if (CollUtil.isEmpty(assigneeUserIds)) { + return; + } + Map userMap = adminUserApi.getUserMap(assigneeUserIds); + assigneeUserIds.removeIf(id -> { + AdminUserRespDTO user = userMap.get(id); + return user == null || !CommonStatusEnum.ENABLE.getStatus().equals(user.getStatus()); + }); + } +} \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateAdminUserApiSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateAdminUserApiSourceInfoProcessor.java new file mode 100644 index 000000000..5be8fd291 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateAdminUserApiSourceInfoProcessor.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor; + +import cn.iocoder.yudao.framework.common.util.collection.SetUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessor; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; + +import javax.annotation.Resource; +import java.util.Set; + +public class BpmCandidateAdminUserApiSourceInfoProcessor implements BpmCandidateSourceInfoProcessor { + @Resource + private AdminUserApi api; + + @Override + public Set getSupportedTypes() { + return SetUtils.asSet(BpmTaskAssignRuleTypeEnum.USER.getType()); + } + + @Override + public void validRuleOptions(Integer type, Set options) { + api.validateUserList(options); + } + + @Override + public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { + return rule.getOptions(); + } +} \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateDeptApiSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateDeptApiSourceInfoProcessor.java new file mode 100644 index 000000000..73c79b524 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateDeptApiSourceInfoProcessor.java @@ -0,0 +1,49 @@ +package cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor; + +import cn.iocoder.yudao.framework.common.util.collection.SetUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessor; +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 javax.annotation.Resource; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; + +public class BpmCandidateDeptApiSourceInfoProcessor implements BpmCandidateSourceInfoProcessor { + @Resource + private DeptApi api; + @Resource + private AdminUserApi adminUserApi; + + @Override + public Set getSupportedTypes() { + return SetUtils.asSet(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), + BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType()); + } + + @Override + public void validRuleOptions(Integer type, Set options) { + api.validateDeptList(options); + } + + @Override + public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { + if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), rule.getType())) { + List users = adminUserApi.getUserListByDeptIds(rule.getOptions()); + return convertSet(users, AdminUserRespDTO::getId); + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType(), rule.getType())) { + List depts = api.getDeptList(rule.getOptions()); + return convertSet(depts, DeptRespDTO::getLeaderUserId); + } + return Collections.emptySet(); + } +} \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidatePostApiSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidatePostApiSourceInfoProcessor.java new file mode 100644 index 000000000..15abe86bc --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidatePostApiSourceInfoProcessor.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor; + +import cn.iocoder.yudao.framework.common.util.collection.SetUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessor; +import cn.iocoder.yudao.module.system.api.dept.PostApi; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Set; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; + +public class BpmCandidatePostApiSourceInfoProcessor implements BpmCandidateSourceInfoProcessor { + @Resource + private PostApi api; + @Resource + private AdminUserApi adminUserApi; + + @Override + public Set getSupportedTypes() { + return SetUtils.asSet(BpmTaskAssignRuleTypeEnum.POST.getType()); + } + + @Override + public void validRuleOptions(Integer type, Set options) { + api.validPostList(options); + } + + @Override + public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { + List users = adminUserApi.getUserListByPostIds(rule.getOptions()); + return convertSet(users, AdminUserRespDTO::getId); + } +} \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateRoleApiSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateRoleApiSourceInfoProcessor.java new file mode 100644 index 000000000..0e0ef6903 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateRoleApiSourceInfoProcessor.java @@ -0,0 +1,36 @@ +package cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor; + +import cn.iocoder.yudao.framework.common.util.collection.SetUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessor; +import cn.iocoder.yudao.module.system.api.permission.PermissionApi; +import cn.iocoder.yudao.module.system.api.permission.RoleApi; + +import javax.annotation.Resource; +import java.util.Set; + +public class BpmCandidateRoleApiSourceInfoProcessor implements BpmCandidateSourceInfoProcessor { + @Resource + private RoleApi api; + + @Resource + private PermissionApi permissionApi; + + @Override + public Set getSupportedTypes() { + return SetUtils.asSet(BpmTaskAssignRuleTypeEnum.ROLE.getType()); + } + + @Override + public void validRuleOptions(Integer type, Set options) { + api.validRoleList(options); + } + + @Override + public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { + return permissionApi.getUserRoleIdListByRoleIds(rule.getOptions()); + } + +} \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateScriptApiSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateScriptApiSourceInfoProcessor.java new file mode 100644 index 000000000..b14ca2a1b --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateScriptApiSourceInfoProcessor.java @@ -0,0 +1,73 @@ +package cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.common.util.collection.SetUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; +import cn.iocoder.yudao.module.bpm.enums.DictTypeConstants; +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessor; +import cn.iocoder.yudao.module.system.api.dict.DictDataApi; +import org.flowable.engine.delegate.DelegateExecution; +import org.springframework.beans.factory.ObjectProvider; + +import javax.annotation.Resource; +import java.util.*; +import java.util.stream.Collectors; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.TASK_ASSIGN_SCRIPT_NOT_EXISTS; + +public class BpmCandidateScriptApiSourceInfoProcessor implements BpmCandidateSourceInfoProcessor { + @Resource + private DictDataApi dictDataApi; + + /** + * 任务分配脚本 + */ + private Map scriptMap = Collections.emptyMap(); + + public void setScripts(ObjectProvider scriptsOp) { + List scripts = scriptsOp.orderedStream().collect(Collectors.toList()); + setScripts(scripts); + } + + public void setScripts(List scripts) { + this.scriptMap = convertMap(scripts, script -> script.getEnum().getId()); + } + + @Override + public Set getSupportedTypes() { + return SetUtils.asSet(BpmTaskAssignRuleTypeEnum.SCRIPT.getType()); + } + + @Override + public void validRuleOptions(Integer type, Set options) { + dictDataApi.validateDictDataList(DictTypeConstants.TASK_ASSIGN_SCRIPT, + CollectionUtils.convertSet(options, String::valueOf)); + } + + @Override + public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { + return calculateTaskCandidateUsersByScript(request.getExecution(), rule.getOptions()); + } + + private Set calculateTaskCandidateUsersByScript(DelegateExecution execution, Set options) { + // 获得对应的脚本 + List scripts = new ArrayList<>(options.size()); + options.forEach(id -> { + BpmTaskAssignScript script = scriptMap.get(id); + if (script == null) { + throw exception(TASK_ASSIGN_SCRIPT_NOT_EXISTS, id); + } + scripts.add(script); + }); + // 逐个计算任务 + Set userIds = new HashSet<>(); + scripts.forEach(script -> CollUtil.addAll(userIds, script.calculateTaskCandidateUsers(execution))); + return userIds; + } +} \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateUserGroupApiSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateUserGroupApiSourceInfoProcessor.java new file mode 100644 index 000000000..076d1693d --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateUserGroupApiSourceInfoProcessor.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor; + +import cn.iocoder.yudao.framework.common.util.collection.SetUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessor; +import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; + +import javax.annotation.Resource; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class BpmCandidateUserGroupApiSourceInfoProcessor implements BpmCandidateSourceInfoProcessor { + @Resource + private BpmUserGroupService api; + @Resource + private BpmUserGroupService userGroupService; + + @Override + public Set getSupportedTypes() { + return SetUtils.asSet(BpmTaskAssignRuleTypeEnum.USER_GROUP.getType()); + } + + @Override + public void validRuleOptions(Integer type, Set options) { + api.validUserGroups(options); + } + + @Override + public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { + List userGroups = userGroupService.getUserGroupList(rule.getOptions()); + Set userIds = new HashSet<>(); + userGroups.forEach(group -> userIds.addAll(group.getMemberUserIds())); + return userIds; + } + +} \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChainTest.java b/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChainTest.java new file mode 100644 index 000000000..1af972d56 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChainTest.java @@ -0,0 +1,248 @@ +package cn.iocoder.yudao.module.bpm.service.candidate; + +import cn.hutool.core.map.MapUtil; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; +import cn.iocoder.yudao.module.bpm.framework.bpm.config.BpmCandidateProcessorConfiguration; +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl.BpmTaskAssignLeaderX1Script; +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl.BpmTaskAssignLeaderX2Script; +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessorChain; +import cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor.BpmCandidateScriptApiSourceInfoProcessor; +import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleServiceImpl; +import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; +import cn.iocoder.yudao.module.system.api.dept.DeptApi; +import cn.iocoder.yudao.module.system.api.dept.PostApi; +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; +import cn.iocoder.yudao.module.system.api.dict.DictDataApi; +import cn.iocoder.yudao.module.system.api.permission.PermissionApi; +import cn.iocoder.yudao.module.system.api.permission.RoleApi; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; +import org.flowable.engine.delegate.DelegateExecution; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static java.util.Collections.singleton; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +@Import({BpmCandidateSourceInfoProcessorChain.class, BpmCandidateProcessorConfiguration.class, + BpmCandidateScriptApiSourceInfoProcessor.class, BpmTaskAssignLeaderX1Script.class, + BpmTaskAssignLeaderX2Script.class}) +public class BpmCandidateSourceInfoProcessorChainTest extends BaseDbUnitTest { + @Resource + private BpmCandidateSourceInfoProcessorChain processorChain; + + @MockBean + private BpmUserGroupService userGroupService; + @MockBean + private DeptApi deptApi; + @MockBean + private AdminUserApi adminUserApi; + @MockBean + private PermissionApi permissionApi; + @MockBean + private RoleApi roleApi; + @MockBean + private PostApi postApi; + @MockBean + private DictDataApi dictDataApi; + @Resource + private BpmCandidateScriptApiSourceInfoProcessor bpmCandidateScriptApiSourceInfoProcessor; + + @Test + public void testCalculateTaskCandidateUsers_Role() { + // 准备参数 + BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(1L, 2L)) + .setType(BpmTaskAssignRuleTypeEnum.ROLE.getType()); + // mock 方法 + when(permissionApi.getUserRoleIdListByRoleIds(eq(rule.getOptions()))) + .thenReturn(asSet(11L, 22L)); + mockGetUserMap(asSet(11L, 22L)); + + // 调用 + BpmCandidateSourceInfo sourceInfo = new BpmCandidateSourceInfo(); + sourceInfo.addRule(rule); + Set results = processorChain.calculateTaskCandidateUsers(null, sourceInfo); + // 断言 + assertEquals(asSet(11L, 22L), results); + } + + @Test + public void testCalculateTaskCandidateUsers_DeptMember() { + // 准备参数 + BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(1L, 2L)) + .setType(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType()); + // mock 方法 + List users = CollectionUtils.convertList(asSet(11L, 22L), + id -> new AdminUserRespDTO().setId(id)); + when(adminUserApi.getUserListByDeptIds(eq(rule.getOptions()))).thenReturn(users); + mockGetUserMap(asSet(11L, 22L)); + + // 调用 + BpmCandidateSourceInfo sourceInfo = new BpmCandidateSourceInfo(); + sourceInfo.addRule(rule); + Set results = processorChain.calculateTaskCandidateUsers(null, sourceInfo); + // 断言 + assertEquals(asSet(11L, 22L), results); + } + + @Test + public void testCalculateTaskCandidateUsers_DeptLeader() { + // 准备参数 + BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(1L, 2L)) + .setType(BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType()); + // mock 方法 + DeptRespDTO dept1 = randomPojo(DeptRespDTO.class, o -> o.setLeaderUserId(11L)); + DeptRespDTO dept2 = randomPojo(DeptRespDTO.class, o -> o.setLeaderUserId(22L)); + when(deptApi.getDeptList(eq(rule.getOptions()))).thenReturn(Arrays.asList(dept1, dept2)); + mockGetUserMap(asSet(11L, 22L)); + + // 调用 + BpmCandidateSourceInfo sourceInfo = new BpmCandidateSourceInfo(); + sourceInfo.addRule(rule); + Set results = processorChain.calculateTaskCandidateUsers(null, sourceInfo); + // 断言 + assertEquals(asSet(11L, 22L), results); + } + + @Test + public void testCalculateTaskCandidateUsers_Post() { + // 准备参数 + BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(1L, 2L)) + .setType(BpmTaskAssignRuleTypeEnum.POST.getType()); + // mock 方法 + List users = CollectionUtils.convertList(asSet(11L, 22L), + id -> new AdminUserRespDTO().setId(id)); + when(adminUserApi.getUserListByPostIds(eq(rule.getOptions()))).thenReturn(users); + mockGetUserMap(asSet(11L, 22L)); + + // 调用 + BpmCandidateSourceInfo sourceInfo = new BpmCandidateSourceInfo(); + sourceInfo.addRule(rule); + Set results = processorChain.calculateTaskCandidateUsers(null, sourceInfo); + // 断言 + assertEquals(asSet(11L, 22L), results); + } + + @Test + public void testCalculateTaskCandidateUsers_User() { + // 准备参数 + BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(1L, 2L)) + .setType(BpmTaskAssignRuleTypeEnum.USER.getType()); + // mock 方法 + mockGetUserMap(asSet(1L, 2L)); + + // 调用 + BpmCandidateSourceInfo sourceInfo = new BpmCandidateSourceInfo(); + sourceInfo.addRule(rule); + Set results = processorChain.calculateTaskCandidateUsers(null, sourceInfo); + // 断言 + assertEquals(asSet(1L, 2L), results); + } + + @Test + public void testCalculateTaskCandidateUsers_UserGroup() { + // 准备参数 + BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(1L, 2L)) + .setType(BpmTaskAssignRuleTypeEnum.USER_GROUP.getType()); + // mock 方法 + BpmUserGroupDO userGroup1 = randomPojo(BpmUserGroupDO.class, o -> o.setMemberUserIds(asSet(11L, 12L))); + BpmUserGroupDO userGroup2 = randomPojo(BpmUserGroupDO.class, o -> o.setMemberUserIds(asSet(21L, 22L))); + when(userGroupService.getUserGroupList(eq(rule.getOptions()))).thenReturn(Arrays.asList(userGroup1, userGroup2)); + mockGetUserMap(asSet(11L, 12L, 21L, 22L)); + + // 调用 + BpmCandidateSourceInfo sourceInfo = new BpmCandidateSourceInfo(); + sourceInfo.addRule(rule); + Set results = processorChain.calculateTaskCandidateUsers(null, sourceInfo); + // 断言 + assertEquals(asSet(11L, 12L, 21L, 22L), results); + } + + private void mockGetUserMap(Set assigneeUserIds) { + Map userMap = CollectionUtils.convertMap(assigneeUserIds, id -> id, + id -> new AdminUserRespDTO().setId(id).setStatus(CommonStatusEnum.ENABLE.getStatus())); + when(adminUserApi.getUserMap(eq(assigneeUserIds))).thenReturn(userMap); + } + + @Test + public void testCalculateTaskCandidateUsers_Script() { + // 准备参数 + BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(20L, 21L)) + .setType(BpmTaskAssignRuleTypeEnum.SCRIPT.getType()); + // mock 方法 + BpmTaskAssignScript script1 = new BpmTaskAssignScript() { + + @Override + public Set calculateTaskCandidateUsers(DelegateExecution task) { + return singleton(11L); + } + + @Override + public BpmTaskRuleScriptEnum getEnum() { + return BpmTaskRuleScriptEnum.LEADER_X1; + } + }; + BpmTaskAssignScript script2 = new BpmTaskAssignScript() { + + @Override + public Set calculateTaskCandidateUsers(DelegateExecution task) { + return singleton(22L); + } + + @Override + public BpmTaskRuleScriptEnum getEnum() { + return BpmTaskRuleScriptEnum.LEADER_X2; + } + }; + bpmCandidateScriptApiSourceInfoProcessor.setScripts(Arrays.asList(script1, script2)); + mockGetUserMap(asSet(11L, 22L)); + + // 调用 + BpmCandidateSourceInfo sourceInfo = new BpmCandidateSourceInfo(); + sourceInfo.addRule(rule); + Set results = processorChain.calculateTaskCandidateUsers(null, sourceInfo); + // 断言 + assertEquals(asSet(11L, 22L), results); + } + + @Test + public void testRemoveDisableUsers() { + // 准备参数. 1L 可以找到;2L 是禁用的;3L 找不到 + Set assigneeUserIds = asSet(1L, 2L, 3L); + // mock 方法 + AdminUserRespDTO user1 = randomPojo(AdminUserRespDTO.class, o -> o.setId(1L) + .setStatus(CommonStatusEnum.ENABLE.getStatus())); + AdminUserRespDTO user2 = randomPojo(AdminUserRespDTO.class, o -> o.setId(2L) + .setStatus(CommonStatusEnum.DISABLE.getStatus())); + Map userMap = MapUtil.builder(user1.getId(), user1) + .put(user2.getId(), user2).build(); + when(adminUserApi.getUserMap(eq(assigneeUserIds))).thenReturn(userMap); + + // 调用 + processorChain.removeDisableUsers(assigneeUserIds); + // 断言 + assertEquals(asSet(1L), assigneeUserIds); + } + +} \ No newline at end of file From 555bac151d20cd003e7e79e7bdfc03eeac5dc1c6 Mon Sep 17 00:00:00 2001 From: kyle <573984425@qq.com> Date: Tue, 9 Jan 2024 18:39:51 +0800 Subject: [PATCH 05/27] =?UTF-8?q?feat:=20=E5=9F=BA=E6=9C=AC=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E6=B5=81=E7=A8=8B=E6=8A=84=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ateVO.java => BpmTaskCandidateRuleVO.java} | 2 +- .../task/vo/task/BpmTaskApproveReqVO.java | 4 + .../cc/BpmProcessInstanceCopyConvert.java | 25 + .../cc/BpmProcessInstanceCopyDO.java | 52 +++ .../cc/BpmProcessInstanceCopyMapper.java | 9 + .../BpmCandidateProcessorConfiguration.java | 2 +- .../candidate/BpmCandidateSourceInfo.java | 17 +- .../BpmCandidateSourceInfoProcessor.java | 17 +- .../BpmCandidateSourceInfoProcessorChain.java | 16 +- ...didateAdminUserApiSourceInfoProcessor.java | 5 +- ...pmCandidateDeptApiSourceInfoProcessor.java | 5 +- ...pmCandidatePostApiSourceInfoProcessor.java | 5 +- ...pmCandidateRoleApiSourceInfoProcessor.java | 5 +- ...CandidateScriptApiSourceInfoProcessor.java | 6 +- ...didateUserGroupApiSourceInfoProcessor.java | 5 +- .../cc/BpmProcessInstanceCopyService.java | 26 ++ .../cc/BpmProcessInstanceCopyServiceImpl.java | 89 ++++ .../service/cc/BpmProcessInstanceCopyVO.java | 51 ++ .../cc/dto/BpmDelegateExecutionDTO.java | 439 ++++++++++++++++++ .../bpm/service/task/BpmTaskServiceImpl.java | 16 + .../yudao/module/bpm/util/FlowableUtils.java | 78 ++++ ...CandidateSourceInfoProcessorChainTest.java | 21 +- .../cc/BpmProcessInstanceCopyServiceTest.java | 17 + 23 files changed, 859 insertions(+), 53 deletions(-) rename yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/candidate/vo/{BpmTaskCandidateVO.java => BpmTaskCandidateRuleVO.java} (96%) create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/cc/BpmProcessInstanceCopyConvert.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/cc/BpmProcessInstanceCopyDO.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/cc/BpmProcessInstanceCopyMapper.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyService.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyVO.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/dto/BpmDelegateExecutionDTO.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/util/FlowableUtils.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceTest.java diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/candidate/vo/BpmTaskCandidateVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/candidate/vo/BpmTaskCandidateRuleVO.java similarity index 96% rename from yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/candidate/vo/BpmTaskCandidateVO.java rename to yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/candidate/vo/BpmTaskCandidateRuleVO.java index 37e877c54..86ee2d596 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/candidate/vo/BpmTaskCandidateVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/candidate/vo/BpmTaskCandidateRuleVO.java @@ -14,7 +14,7 @@ import java.util.Set; * @see BpmTaskAssignRuleBaseVO */ @Data -public class BpmTaskCandidateVO { +public class BpmTaskCandidateRuleVO { @Schema(description = "规则类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "bpm_task_assign_rule_type") @NotNull(message = "规则类型不能为空") diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java index 14dca13ea..c9b0e9121 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateRuleVO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -17,4 +18,7 @@ public class BpmTaskApproveReqVO { @NotEmpty(message = "审批意见不能为空") private String reason; + @Schema(description = "审批时流程抄送人", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private BpmTaskCandidateRuleVO ccCandidateRule; + } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/cc/BpmProcessInstanceCopyConvert.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/cc/BpmProcessInstanceCopyConvert.java new file mode 100644 index 000000000..3e0a3cd45 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/cc/BpmProcessInstanceCopyConvert.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.module.bpm.convert.cc; + +import cn.iocoder.yudao.module.bpm.dal.dataobject.cc.BpmProcessInstanceCopyDO; +import cn.iocoder.yudao.module.bpm.service.cc.BpmProcessInstanceCopyVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +/** + * 动态表单 Convert + * + * @author 芋艿 + */ +@Mapper +public interface BpmProcessInstanceCopyConvert { + + BpmProcessInstanceCopyConvert INSTANCE = Mappers.getMapper(BpmProcessInstanceCopyConvert.class); + BpmProcessInstanceCopyDO copy(BpmProcessInstanceCopyDO bean); + + BpmProcessInstanceCopyVO convert(BpmProcessInstanceCopyDO bean); + + List convertList2(List list); + +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/cc/BpmProcessInstanceCopyDO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/cc/BpmProcessInstanceCopyDO.java new file mode 100644 index 000000000..4583bc7a7 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/cc/BpmProcessInstanceCopyDO.java @@ -0,0 +1,52 @@ +package cn.iocoder.yudao.module.bpm.dal.dataobject.cc; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * 流程抄送对象 + * + * @author kyle + * @date 2022-05-19 + */ +@TableName(value = "bpm_process_instance_copy", autoResultMap = true) +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class BpmProcessInstanceCopyDO extends BaseDO { + + /** + * 编号 + */ + @TableId + private Long id; + + /** + * 发起人Id + */ + private Long startUserId; + /** + * 表单名 + */ + private String name; + /** + * 流程主键 + */ + private String processInstanceId; + + /** + * 任务主键 + */ + private String taskId; + /** + * 用户主键 + */ + private Long userId; + + +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/cc/BpmProcessInstanceCopyMapper.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/cc/BpmProcessInstanceCopyMapper.java new file mode 100644 index 000000000..c911aa9c5 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/cc/BpmProcessInstanceCopyMapper.java @@ -0,0 +1,9 @@ +package cn.iocoder.yudao.module.bpm.dal.mysql.cc; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.bpm.dal.dataobject.cc.BpmProcessInstanceCopyDO; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface BpmProcessInstanceCopyMapper extends BaseMapperX { +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmCandidateProcessorConfiguration.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmCandidateProcessorConfiguration.java index b9fde2436..293a935d6 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmCandidateProcessorConfiguration.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmCandidateProcessorConfiguration.java @@ -41,7 +41,7 @@ public class BpmCandidateProcessorConfiguration { /** * 可以自己定制脚本,然后通过这里设置到处理器里面去 - * @param scriptsOp + * @param scriptsOp 脚本包装对象 * @return */ @Bean diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfo.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfo.java index 1280a53e5..5970a012e 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfo.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfo.java @@ -1,13 +1,13 @@ package cn.iocoder.yudao.module.bpm.service.candidate; -import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; -import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleBaseVO; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateRuleVO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -import org.flowable.engine.delegate.DelegateExecution; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; import java.util.HashSet; import java.util.Set; @@ -20,21 +20,20 @@ import java.util.Set; public class BpmCandidateSourceInfo { @Schema(description = "流程id") + @NotNull private String processInstanceId; @Schema(description = "当前任务ID") + @NotNull private String taskId; - /** * 通过这些规则,生成最终需要生成的用户 */ @Schema(description = "当前任务预选规则") - private Set rules; + @NotEmpty(message = "不允许空规则") + private Set rules; - @Schema(description = "源执行流程") - private DelegateExecution execution; - - public void addRule(BpmTaskCandidateVO vo) { + public void addRule(BpmTaskCandidateRuleVO vo) { assert vo != null; if (rules == null) { rules = new HashSet<>(); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessor.java index 52a8adaaf..0fe741c20 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessor.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessor.java @@ -1,8 +1,9 @@ package cn.iocoder.yudao.module.bpm.service.candidate; import cn.hutool.core.collection.CollUtil; -import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateRuleVO; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; +import org.flowable.engine.delegate.DelegateExecution; import java.util.Collections; import java.util.HashSet; @@ -29,24 +30,24 @@ public interface BpmCandidateSourceInfoProcessor { * 默认的处理 * 如果想去操作所有的规则,则可以覆盖此方法 * - * @param request - * @param chain + * @param request 原始请求 + * @param delegateExecution 审批过程中的对象 * @return 必须包含的是用户ID,而不是其他的ID * @throws Exception */ - default Set process(BpmCandidateSourceInfo request, BpmCandidateSourceInfoProcessorChain chain) throws Exception { - Set rules = request.getRules(); + default Set process(BpmCandidateSourceInfo request, DelegateExecution delegateExecution) throws Exception { + Set rules = request.getRules(); Set results = new HashSet<>(); - for (BpmTaskCandidateVO rule : rules) { + for (BpmTaskCandidateRuleVO rule : rules) { // 每个处理器都有机会处理自己支持的事件 if (CollUtil.contains(getSupportedTypes(), rule.getType())) { - results.addAll(doProcess(request, rule)); + results.addAll(doProcess(request, rule, delegateExecution)); } } return results; } - default Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { + default Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateRuleVO rule, DelegateExecution delegateExecution) { return Collections.emptySet(); } } \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChain.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChain.java index b33fd7356..d486b96b3 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChain.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChain.java @@ -1,8 +1,9 @@ package cn.iocoder.yudao.module.bpm.service.candidate; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.ListUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateRuleVO; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import org.flowable.engine.delegate.DelegateExecution; @@ -11,7 +12,6 @@ import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.*; -import java.util.stream.Collectors; @Service public class BpmCandidateSourceInfoProcessorChain { @@ -31,7 +31,7 @@ public class BpmCandidateSourceInfoProcessorChain { @Resource // 动态扩展处理节点 public BpmCandidateSourceInfoProcessorChain addProcessor(ObjectProvider processorOp) { - List processor = processorOp.orderedStream().collect(Collectors.toList()); + List processor = ListUtil.toList(processorOp.iterator()); if (null == processorList) { processorList = new ArrayList<>(processor.size()); } @@ -40,14 +40,14 @@ public class BpmCandidateSourceInfoProcessorChain { } // 获取处理器处理 - public Set process(BpmCandidateSourceInfo sourceInfo) throws Exception { + public Set process(BpmCandidateSourceInfo sourceInfo, DelegateExecution execution) throws Exception { // Verify our parameters if (sourceInfo == null) { throw new IllegalArgumentException(); } for (BpmCandidateSourceInfoProcessor processor : processorList) { try { - for (BpmTaskCandidateVO vo : sourceInfo.getRules()) { + for (BpmTaskCandidateRuleVO vo : sourceInfo.getRules()) { processor.validRuleOptions(vo.getType(), vo.getOptions()); } } catch (Exception e) { @@ -59,7 +59,7 @@ public class BpmCandidateSourceInfoProcessorChain { Exception saveException = null; for (BpmCandidateSourceInfoProcessor processor : processorList) { try { - saveResult = processor.process(sourceInfo, this); + saveResult = processor.process(sourceInfo, execution); if (CollUtil.isNotEmpty(saveResult)) { removeDisableUsers(saveResult); break; @@ -78,10 +78,9 @@ public class BpmCandidateSourceInfoProcessorChain { } public Set calculateTaskCandidateUsers(DelegateExecution execution, BpmCandidateSourceInfo sourceInfo) { - sourceInfo.setExecution(execution); Set results = Collections.emptySet(); try { - results = process(sourceInfo); + results = process(sourceInfo, execution); } catch (Exception e) { e.printStackTrace(); } @@ -90,6 +89,7 @@ public class BpmCandidateSourceInfoProcessorChain { /** * 移除禁用用户 + * * @param assigneeUserIds */ public void removeDisableUsers(Set assigneeUserIds) { diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateAdminUserApiSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateAdminUserApiSourceInfoProcessor.java index 5be8fd291..15c89176a 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateAdminUserApiSourceInfoProcessor.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateAdminUserApiSourceInfoProcessor.java @@ -1,11 +1,12 @@ package cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor; import cn.iocoder.yudao.framework.common.util.collection.SetUtils; -import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateRuleVO; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessor; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import org.flowable.engine.delegate.DelegateExecution; import javax.annotation.Resource; import java.util.Set; @@ -25,7 +26,7 @@ public class BpmCandidateAdminUserApiSourceInfoProcessor implements BpmCandidate } @Override - public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { + public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateRuleVO rule, DelegateExecution delegateExecution) { return rule.getOptions(); } } \ No newline at end of file diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateDeptApiSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateDeptApiSourceInfoProcessor.java index 73c79b524..71a7fc87e 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateDeptApiSourceInfoProcessor.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateDeptApiSourceInfoProcessor.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor; import cn.iocoder.yudao.framework.common.util.collection.SetUtils; -import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateRuleVO; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessor; @@ -9,6 +9,7 @@ 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 org.flowable.engine.delegate.DelegateExecution; import javax.annotation.Resource; import java.util.Collections; @@ -36,7 +37,7 @@ public class BpmCandidateDeptApiSourceInfoProcessor implements BpmCandidateSourc } @Override - public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { + public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateRuleVO rule, DelegateExecution delegateExecution) { if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), rule.getType())) { List users = adminUserApi.getUserListByDeptIds(rule.getOptions()); return convertSet(users, AdminUserRespDTO::getId); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidatePostApiSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidatePostApiSourceInfoProcessor.java index 15abe86bc..f4a885960 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidatePostApiSourceInfoProcessor.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidatePostApiSourceInfoProcessor.java @@ -1,13 +1,14 @@ package cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor; import cn.iocoder.yudao.framework.common.util.collection.SetUtils; -import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateRuleVO; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessor; import cn.iocoder.yudao.module.system.api.dept.PostApi; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; +import org.flowable.engine.delegate.DelegateExecution; import javax.annotation.Resource; import java.util.List; @@ -32,7 +33,7 @@ public class BpmCandidatePostApiSourceInfoProcessor implements BpmCandidateSourc } @Override - public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { + public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateRuleVO rule, DelegateExecution delegateExecution) { List users = adminUserApi.getUserListByPostIds(rule.getOptions()); return convertSet(users, AdminUserRespDTO::getId); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateRoleApiSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateRoleApiSourceInfoProcessor.java index 0e0ef6903..92cda1fd6 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateRoleApiSourceInfoProcessor.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateRoleApiSourceInfoProcessor.java @@ -1,12 +1,13 @@ package cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor; import cn.iocoder.yudao.framework.common.util.collection.SetUtils; -import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateRuleVO; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessor; import cn.iocoder.yudao.module.system.api.permission.PermissionApi; import cn.iocoder.yudao.module.system.api.permission.RoleApi; +import org.flowable.engine.delegate.DelegateExecution; import javax.annotation.Resource; import java.util.Set; @@ -29,7 +30,7 @@ public class BpmCandidateRoleApiSourceInfoProcessor implements BpmCandidateSourc } @Override - public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { + public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateRuleVO rule, DelegateExecution delegateExecution) { return permissionApi.getUserRoleIdListByRoleIds(rule.getOptions()); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateScriptApiSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateScriptApiSourceInfoProcessor.java index b14ca2a1b..acfcc9844 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateScriptApiSourceInfoProcessor.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateScriptApiSourceInfoProcessor.java @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.collection.SetUtils; -import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateRuleVO; import cn.iocoder.yudao.module.bpm.enums.DictTypeConstants; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; @@ -51,8 +51,8 @@ public class BpmCandidateScriptApiSourceInfoProcessor implements BpmCandidateSou } @Override - public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { - return calculateTaskCandidateUsersByScript(request.getExecution(), rule.getOptions()); + public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateRuleVO rule, DelegateExecution delegateExecution) { + return calculateTaskCandidateUsersByScript(delegateExecution, rule.getOptions()); } private Set calculateTaskCandidateUsersByScript(DelegateExecution execution, Set options) { diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateUserGroupApiSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateUserGroupApiSourceInfoProcessor.java index 076d1693d..42929b413 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateUserGroupApiSourceInfoProcessor.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateUserGroupApiSourceInfoProcessor.java @@ -1,12 +1,13 @@ package cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor; import cn.iocoder.yudao.framework.common.util.collection.SetUtils; -import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateRuleVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessor; import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; +import org.flowable.engine.delegate.DelegateExecution; import javax.annotation.Resource; import java.util.HashSet; @@ -30,7 +31,7 @@ public class BpmCandidateUserGroupApiSourceInfoProcessor implements BpmCandidate } @Override - public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { + public Set doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateRuleVO rule, DelegateExecution delegateExecution) { List userGroups = userGroupService.getUserGroupList(rule.getOptions()); Set userIds = new HashSet<>(); userGroups.forEach(group -> userIds.addAll(group.getMemberUserIds())); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyService.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyService.java new file mode 100644 index 000000000..58ee02b8e --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyService.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.bpm.service.cc; + +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; + +/** + * 流程抄送Service接口 + * + * 现在是在审批的时候进行流程抄送 + */ +public interface BpmProcessInstanceCopyService { + + /** + * 查询流程抄送 + * + * @param copyId 流程抄送主键 + * @return 流程抄送 + */ + BpmProcessInstanceCopyVO queryById(Long copyId); + + /** + * 抄送 + * @param sourceInfo 抄送源信息,方便抄送处理 + * @return + */ + boolean makeCopy(BpmCandidateSourceInfo sourceInfo); +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java new file mode 100644 index 000000000..b285d6189 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java @@ -0,0 +1,89 @@ +package cn.iocoder.yudao.module.bpm.service.cc; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.module.bpm.convert.cc.BpmProcessInstanceCopyConvert; +import cn.iocoder.yudao.module.bpm.dal.dataobject.cc.BpmProcessInstanceCopyDO; +import cn.iocoder.yudao.module.bpm.dal.mysql.cc.BpmProcessInstanceCopyMapper; +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessorChain; +import cn.iocoder.yudao.module.bpm.service.cc.dto.BpmDelegateExecutionDTO; +import cn.iocoder.yudao.module.bpm.util.FlowableUtils; +import lombok.extern.slf4j.Slf4j; +import org.flowable.engine.RuntimeService; +import org.flowable.engine.delegate.DelegateExecution; +import org.flowable.engine.runtime.ProcessInstance; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +@Slf4j +@Service +@Validated +public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopyService { + @Resource + private BpmProcessInstanceCopyMapper processInstanceCopyMapper; + + /** + * 和flowable有关的,查询流程名用的 + */ + @Resource + private RuntimeService runtimeService; + + /** + * 找抄送人用的 + */ + @Resource + private BpmCandidateSourceInfoProcessorChain processorChain; + + @Override + public BpmProcessInstanceCopyVO queryById(Long copyId) { + BpmProcessInstanceCopyDO bpmProcessInstanceCopyDO = processInstanceCopyMapper.selectById(copyId); + return BpmProcessInstanceCopyConvert.INSTANCE.convert(bpmProcessInstanceCopyDO); + } + + @Override + public boolean makeCopy(BpmCandidateSourceInfo sourceInfo) { + if (null == sourceInfo) { + return false; + } + + DelegateExecution executionEntity = new BpmDelegateExecutionDTO(sourceInfo.getProcessInstanceId()); + Set ccCandidates = processorChain.calculateTaskCandidateUsers(executionEntity, sourceInfo); + if (CollUtil.isEmpty(ccCandidates)) { + log.warn("相关抄送人不存在 {}", sourceInfo.getTaskId()); + return false; + } else { + BpmProcessInstanceCopyDO copyDO = new BpmProcessInstanceCopyDO(); + // 调用 + //设置任务id + copyDO.setTaskId(sourceInfo.getTaskId()); + copyDO.setProcessInstanceId(sourceInfo.getProcessInstanceId()); + ProcessInstance processInstance = runtimeService.createProcessInstanceQuery() + .processInstanceId(sourceInfo.getProcessInstanceId()) + .singleResult(); + if (null == processInstance) { + log.warn("相关流程实例不存在 {}", sourceInfo.getTaskId()); + return false; + } + copyDO.setStartUserId(FlowableUtils.getStartUserIdFromProcessInstance(processInstance)); + copyDO.setName(FlowableUtils.getFlowName(processInstance.getProcessDefinitionId())); + List copyList = new ArrayList<>(ccCandidates.size()); + for (Long userId : ccCandidates) { + BpmProcessInstanceCopyDO copy = BpmProcessInstanceCopyConvert.INSTANCE.copy(copyDO); + copy.setUserId(userId); + copyList.add(copy); + } + return processInstanceCopyMapper.insertBatch(copyList); + } + } + + public List queryByProcessId() { + return null; + } + + +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyVO.java new file mode 100644 index 000000000..f99d92f89 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyVO.java @@ -0,0 +1,51 @@ +package cn.iocoder.yudao.module.bpm.service.cc; + +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.Date; + + +/** + * 流程抄送视图对象 wf_copy + * + * @author ruoyi + * @date 2022-05-19 + */ +@Data +public class BpmProcessInstanceCopyVO { + + /** + * 编号 + */ + @Schema(description = "抄送主键") + private Long id; + + /** + * 发起人Id + */ + @Schema(description = "发起人Id") + private Long startUserId; + /** + * 表单名 + */ + @Schema(description = "流程实例的名字") + private String name; + /** + * 流程主键 + */ + @Schema(description = "流程实例的主键") + private String processInstanceId; + + /** + * 任务主键 + */ + @Schema(description = "发起抄送的任务编号") + private String taskId; + /** + * 用户主键 + */ + @Schema(description = "用户编号") + private Long userId; +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/dto/BpmDelegateExecutionDTO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/dto/BpmDelegateExecutionDTO.java new file mode 100644 index 000000000..47213ae52 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/dto/BpmDelegateExecutionDTO.java @@ -0,0 +1,439 @@ +package cn.iocoder.yudao.module.bpm.service.cc.dto; + +import org.flowable.bpmn.model.FlowElement; +import org.flowable.bpmn.model.FlowableListener; +import org.flowable.engine.delegate.DelegateExecution; +import org.flowable.engine.delegate.ReadOnlyDelegateExecution; +import org.flowable.variable.api.persistence.entity.VariableInstance; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * 仅为了传输processInstanceId + */ +public class BpmDelegateExecutionDTO implements DelegateExecution { + + public BpmDelegateExecutionDTO(String getProcessInstanceId) { + this.getProcessInstanceId = getProcessInstanceId; + } + + private final String getProcessInstanceId; + + @Override + public String getId() { + return null; + } + + @Override + public String getProcessInstanceId() { + return null; + } + + @Override + public String getRootProcessInstanceId() { + return null; + } + + @Override + public String getEventName() { + return null; + } + + @Override + public void setEventName(String eventName) { + + } + + @Override + public String getProcessInstanceBusinessKey() { + return null; + } + + @Override + public String getProcessInstanceBusinessStatus() { + return null; + } + + @Override + public String getProcessDefinitionId() { + return null; + } + + @Override + public String getPropagatedStageInstanceId() { + return null; + } + + @Override + public String getParentId() { + return null; + } + + @Override + public String getSuperExecutionId() { + return null; + } + + @Override + public String getCurrentActivityId() { + return null; + } + + @Override + public String getTenantId() { + return null; + } + + @Override + public FlowElement getCurrentFlowElement() { + return null; + } + + @Override + public void setCurrentFlowElement(FlowElement flowElement) { + + } + + @Override + public FlowableListener getCurrentFlowableListener() { + return null; + } + + @Override + public void setCurrentFlowableListener(FlowableListener currentListener) { + + } + + @Override + public ReadOnlyDelegateExecution snapshotReadOnly() { + return null; + } + + @Override + public DelegateExecution getParent() { + return null; + } + + @Override + public List getExecutions() { + return null; + } + + @Override + public void setActive(boolean isActive) { + + } + + @Override + public boolean isActive() { + return false; + } + + @Override + public boolean isEnded() { + return false; + } + + @Override + public void setConcurrent(boolean isConcurrent) { + + } + + @Override + public boolean isConcurrent() { + return false; + } + + @Override + public boolean isProcessInstanceType() { + return false; + } + + @Override + public void inactivate() { + + } + + @Override + public boolean isScope() { + return false; + } + + @Override + public void setScope(boolean isScope) { + + } + + @Override + public boolean isMultiInstanceRoot() { + return false; + } + + @Override + public void setMultiInstanceRoot(boolean isMultiInstanceRoot) { + + } + + @Override + public Map getVariables() { + return null; + } + + @Override + public Map getVariableInstances() { + return null; + } + + @Override + public Map getVariables(Collection collection) { + return null; + } + + @Override + public Map getVariableInstances(Collection collection) { + return null; + } + + @Override + public Map getVariables(Collection collection, boolean b) { + return null; + } + + @Override + public Map getVariableInstances(Collection collection, boolean b) { + return null; + } + + @Override + public Map getVariablesLocal() { + return null; + } + + @Override + public Map getVariableInstancesLocal() { + return null; + } + + @Override + public Map getVariablesLocal(Collection collection) { + return null; + } + + @Override + public Map getVariableInstancesLocal(Collection collection) { + return null; + } + + @Override + public Map getVariablesLocal(Collection collection, boolean b) { + return null; + } + + @Override + public Map getVariableInstancesLocal(Collection collection, boolean b) { + return null; + } + + @Override + public Object getVariable(String s) { + return null; + } + + @Override + public VariableInstance getVariableInstance(String s) { + return null; + } + + @Override + public Object getVariable(String s, boolean b) { + return null; + } + + @Override + public VariableInstance getVariableInstance(String s, boolean b) { + return null; + } + + @Override + public Object getVariableLocal(String s) { + return null; + } + + @Override + public VariableInstance getVariableInstanceLocal(String s) { + return null; + } + + @Override + public Object getVariableLocal(String s, boolean b) { + return null; + } + + @Override + public VariableInstance getVariableInstanceLocal(String s, boolean b) { + return null; + } + + @Override + public T getVariable(String s, Class aClass) { + return null; + } + + @Override + public T getVariableLocal(String s, Class aClass) { + return null; + } + + @Override + public Set getVariableNames() { + return null; + } + + @Override + public Set getVariableNamesLocal() { + return null; + } + + @Override + public void setVariable(String s, Object o) { + + } + + @Override + public void setVariable(String s, Object o, boolean b) { + + } + + @Override + public Object setVariableLocal(String s, Object o) { + return null; + } + + @Override + public Object setVariableLocal(String s, Object o, boolean b) { + return null; + } + + @Override + public void setVariables(Map map) { + + } + + @Override + public void setVariablesLocal(Map map) { + + } + + @Override + public boolean hasVariables() { + return false; + } + + @Override + public boolean hasVariablesLocal() { + return false; + } + + @Override + public boolean hasVariable(String s) { + return false; + } + + @Override + public boolean hasVariableLocal(String s) { + return false; + } + + @Override + public void removeVariable(String s) { + + } + + @Override + public void removeVariableLocal(String s) { + + } + + @Override + public void removeVariables(Collection collection) { + + } + + @Override + public void removeVariablesLocal(Collection collection) { + + } + + @Override + public void removeVariables() { + + } + + @Override + public void removeVariablesLocal() { + + } + + @Override + public void setTransientVariable(String s, Object o) { + + } + + @Override + public void setTransientVariableLocal(String s, Object o) { + + } + + @Override + public void setTransientVariables(Map map) { + + } + + @Override + public Object getTransientVariable(String s) { + return null; + } + + @Override + public Map getTransientVariables() { + return null; + } + + @Override + public void setTransientVariablesLocal(Map map) { + + } + + @Override + public Object getTransientVariableLocal(String s) { + return null; + } + + @Override + public Map getTransientVariablesLocal() { + return null; + } + + @Override + public void removeTransientVariableLocal(String s) { + + } + + @Override + public void removeTransientVariable(String s) { + + } + + @Override + public void removeTransientVariables() { + + } + + @Override + public void removeTransientVariablesLocal() { + + } +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java index a0f938e67..f58679317 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java @@ -19,6 +19,8 @@ import cn.iocoder.yudao.module.bpm.enums.task.BpmCommentTypeEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum; import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskAddSignTypeEnum; +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; +import cn.iocoder.yudao.module.bpm.service.cc.BpmProcessInstanceCopyService; import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService; import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService; import cn.iocoder.yudao.module.system.api.dept.DeptApi; @@ -94,6 +96,9 @@ public class BpmTaskServiceImpl implements BpmTaskService { @Resource private ManagementService managementService; + @Resource + private BpmProcessInstanceCopyService processInstanceCopyService; + @Override public PageResult getTodoTaskPage(Long userId, BpmTaskTodoPageReqVO pageVO) { // 查询待办任务 @@ -237,6 +242,17 @@ public class BpmTaskServiceImpl implements BpmTaskService { .setReason(reqVO.getReason())); // 处理加签任务 handleParentTask(task); + + // 在能正常审批的情况下抄送流程 + if (null != reqVO.getCcCandidateRule()) { + BpmCandidateSourceInfo sourceInfo = new BpmCandidateSourceInfo(); + sourceInfo.setTaskId(reqVO.getId()); + sourceInfo.setProcessInstanceId(instance.getId()); + sourceInfo.addRule(reqVO.getCcCandidateRule()); + if (!processInstanceCopyService.makeCopy(sourceInfo)) { + throw new RuntimeException("抄送任务失败"); + } + } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/util/FlowableUtils.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/util/FlowableUtils.java new file mode 100644 index 000000000..8e8764faa --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/util/FlowableUtils.java @@ -0,0 +1,78 @@ +package cn.iocoder.yudao.module.bpm.util; + + +import cn.hutool.extra.spring.SpringUtil; +import cn.iocoder.yudao.framework.common.util.number.NumberUtils; +import org.flowable.bpmn.model.BpmnModel; +import org.flowable.bpmn.model.ExtensionElement; +import org.flowable.bpmn.model.FlowElement; +import org.flowable.bpmn.model.FlowNode; +import org.flowable.engine.RepositoryService; +import org.flowable.engine.RuntimeService; +import org.flowable.engine.repository.ProcessDefinition; +import org.flowable.engine.runtime.ProcessInstance; + +import java.util.List; +import java.util.Map; + +/** + * 流程引擎工具类封装 + * + * @author: linjinp + * @create: 2019-12-24 13:51 + **/ +public class FlowableUtils { + + /** + * 获取流程名称 + * + * @param processDefinitionId + * @return + */ + public static String getFlowName(String processDefinitionId) { + RepositoryService repositoryService = SpringUtil.getBean(RepositoryService.class); + ProcessDefinition processDefinition = repositoryService.getProcessDefinition(processDefinitionId); + return processDefinition.getName(); + } + + /** + * 获取节点数据 + * + * @param processInstanceId + * @param nodeId + * @return + */ + public static FlowNode getFlowNode(String processInstanceId, String nodeId) { + + RuntimeService runtimeService = SpringUtil.getBean(RuntimeService.class); + RepositoryService repositoryService = SpringUtil.getBean(RepositoryService.class); + + String definitionld = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult().getProcessDefinitionId(); //获取bpm(模型)对象 + BpmnModel bpmnModel = repositoryService.getBpmnModel(definitionld); + //传节点定义key获取当前节点 + FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(nodeId); + return flowNode; + } + + public static ExtensionElement generateFlowNodeIdExtension(String nodeId) { + ExtensionElement extensionElement = new ExtensionElement(); + extensionElement.setElementText(nodeId); + extensionElement.setName("nodeId"); + extensionElement.setNamespacePrefix("flowable"); + extensionElement.setNamespace("nodeId"); + return extensionElement; + } + + public static String getNodeIdFromExtension(FlowElement flowElement) { + Map> extensionElements = flowElement.getExtensionElements(); + return extensionElements.get("nodeId").get(0).getElementText(); + } + + public static Long getStartUserIdFromProcessInstance(ProcessInstance instance) { + if (null == instance) { + return null; + } + return NumberUtils.parseLong(instance.getStartUserId()); + } + +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChainTest.java b/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChainTest.java index 1af972d56..5c326fc0f 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChainTest.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChainTest.java @@ -4,8 +4,7 @@ import cn.hutool.core.map.MapUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateRuleVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; @@ -13,10 +12,7 @@ import cn.iocoder.yudao.module.bpm.framework.bpm.config.BpmCandidateProcessorCon import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl.BpmTaskAssignLeaderX1Script; import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl.BpmTaskAssignLeaderX2Script; -import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; -import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessorChain; import cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor.BpmCandidateScriptApiSourceInfoProcessor; -import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleServiceImpl; import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.PostApi; @@ -28,7 +24,6 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import org.flowable.engine.delegate.DelegateExecution; import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; @@ -72,7 +67,7 @@ public class BpmCandidateSourceInfoProcessorChainTest extends BaseDbUnitTest { @Test public void testCalculateTaskCandidateUsers_Role() { // 准备参数 - BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(1L, 2L)) + BpmTaskCandidateRuleVO rule = new BpmTaskCandidateRuleVO().setOptions(asSet(1L, 2L)) .setType(BpmTaskAssignRuleTypeEnum.ROLE.getType()); // mock 方法 when(permissionApi.getUserRoleIdListByRoleIds(eq(rule.getOptions()))) @@ -90,7 +85,7 @@ public class BpmCandidateSourceInfoProcessorChainTest extends BaseDbUnitTest { @Test public void testCalculateTaskCandidateUsers_DeptMember() { // 准备参数 - BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(1L, 2L)) + BpmTaskCandidateRuleVO rule = new BpmTaskCandidateRuleVO().setOptions(asSet(1L, 2L)) .setType(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType()); // mock 方法 List users = CollectionUtils.convertList(asSet(11L, 22L), @@ -109,7 +104,7 @@ public class BpmCandidateSourceInfoProcessorChainTest extends BaseDbUnitTest { @Test public void testCalculateTaskCandidateUsers_DeptLeader() { // 准备参数 - BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(1L, 2L)) + BpmTaskCandidateRuleVO rule = new BpmTaskCandidateRuleVO().setOptions(asSet(1L, 2L)) .setType(BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType()); // mock 方法 DeptRespDTO dept1 = randomPojo(DeptRespDTO.class, o -> o.setLeaderUserId(11L)); @@ -128,7 +123,7 @@ public class BpmCandidateSourceInfoProcessorChainTest extends BaseDbUnitTest { @Test public void testCalculateTaskCandidateUsers_Post() { // 准备参数 - BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(1L, 2L)) + BpmTaskCandidateRuleVO rule = new BpmTaskCandidateRuleVO().setOptions(asSet(1L, 2L)) .setType(BpmTaskAssignRuleTypeEnum.POST.getType()); // mock 方法 List users = CollectionUtils.convertList(asSet(11L, 22L), @@ -147,7 +142,7 @@ public class BpmCandidateSourceInfoProcessorChainTest extends BaseDbUnitTest { @Test public void testCalculateTaskCandidateUsers_User() { // 准备参数 - BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(1L, 2L)) + BpmTaskCandidateRuleVO rule = new BpmTaskCandidateRuleVO().setOptions(asSet(1L, 2L)) .setType(BpmTaskAssignRuleTypeEnum.USER.getType()); // mock 方法 mockGetUserMap(asSet(1L, 2L)); @@ -163,7 +158,7 @@ public class BpmCandidateSourceInfoProcessorChainTest extends BaseDbUnitTest { @Test public void testCalculateTaskCandidateUsers_UserGroup() { // 准备参数 - BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(1L, 2L)) + BpmTaskCandidateRuleVO rule = new BpmTaskCandidateRuleVO().setOptions(asSet(1L, 2L)) .setType(BpmTaskAssignRuleTypeEnum.USER_GROUP.getType()); // mock 方法 BpmUserGroupDO userGroup1 = randomPojo(BpmUserGroupDO.class, o -> o.setMemberUserIds(asSet(11L, 12L))); @@ -188,7 +183,7 @@ public class BpmCandidateSourceInfoProcessorChainTest extends BaseDbUnitTest { @Test public void testCalculateTaskCandidateUsers_Script() { // 准备参数 - BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(20L, 21L)) + BpmTaskCandidateRuleVO rule = new BpmTaskCandidateRuleVO().setOptions(asSet(20L, 21L)) .setType(BpmTaskAssignRuleTypeEnum.SCRIPT.getType()); // mock 方法 BpmTaskAssignScript script1 = new BpmTaskAssignScript() { diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceTest.java b/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceTest.java new file mode 100644 index 000000000..42a1d46e8 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceTest.java @@ -0,0 +1,17 @@ +package cn.iocoder.yudao.module.bpm.service.cc; + +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import org.junit.jupiter.api.Test; +import org.springframework.context.annotation.Import; + +import javax.annotation.Resource; + +@Import({BpmProcessInstanceCopyServiceImpl.class}) +class BpmProcessInstanceCopyServiceTest extends BaseDbUnitTest { + @Resource + private BpmProcessInstanceCopyServiceImpl service; + + @Test + void queryById() { + } +} \ No newline at end of file From 1bc472b528a300bc4a3521561eb8aa6541b65d16 Mon Sep 17 00:00:00 2001 From: kyle <573984425@qq.com> Date: Wed, 10 Jan 2024 08:57:46 +0800 Subject: [PATCH 06/27] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E4=BA=BA=E4=BB=A5=E5=8F=8A=E5=88=9B=E5=BB=BA=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/bpm/service/candidate/BpmCandidateSourceInfo.java | 3 +++ .../bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java | 3 +++ .../yudao/module/bpm/service/task/BpmTaskServiceImpl.java | 1 + 3 files changed, 7 insertions(+) diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfo.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfo.java index 5970a012e..52ef13ffd 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfo.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfo.java @@ -33,6 +33,9 @@ public class BpmCandidateSourceInfo { @NotEmpty(message = "不允许空规则") private Set rules; + @Schema(description = "发起抄送的用户") + private String creator; + public void addRule(BpmTaskCandidateRuleVO vo) { assert vo != null; if (rules == null) { diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java index b285d6189..4f074472a 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java @@ -16,6 +16,7 @@ import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -71,6 +72,8 @@ public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopy } copyDO.setStartUserId(FlowableUtils.getStartUserIdFromProcessInstance(processInstance)); copyDO.setName(FlowableUtils.getFlowName(processInstance.getProcessDefinitionId())); + copyDO.setCreator(sourceInfo.getCreator()); + copyDO.setCreateTime(LocalDateTime.now()); List copyList = new ArrayList<>(ccCandidates.size()); for (Long userId : ccCandidates) { BpmProcessInstanceCopyDO copy = BpmProcessInstanceCopyConvert.INSTANCE.copy(copyDO); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java index f58679317..416d31645 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java @@ -249,6 +249,7 @@ public class BpmTaskServiceImpl implements BpmTaskService { sourceInfo.setTaskId(reqVO.getId()); sourceInfo.setProcessInstanceId(instance.getId()); sourceInfo.addRule(reqVO.getCcCandidateRule()); + sourceInfo.setCreator(String.valueOf(userId)); if (!processInstanceCopyService.makeCopy(sourceInfo)) { throw new RuntimeException("抄送任务失败"); } From 8f171ba3d0bd390d5385a385470dcc500d0181bd Mon Sep 17 00:00:00 2001 From: kyle <573984425@qq.com> Date: Mon, 15 Jan 2024 16:31:21 +0800 Subject: [PATCH 07/27] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E6=8A=84?= =?UTF-8?q?=E9=80=81=E4=BA=BA=E7=9B=B8=E5=85=B3=E5=8A=9F=E8=83=BD=E4=BB=A5?= =?UTF-8?q?=E5=8F=8A=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/ruoyi-vue-pro.sql | 9 +++ .../task/BpmProcessInstanceController.java | 21 ++++++ .../BpmProcessInstanceCCMyPageReqVO.java | 30 +++++++++ .../BpmProcessInstanceCCPageItemRespVO.java | 61 +++++++++++++++++ .../instance/BpmProcessInstanceCCReqVO.java | 44 ++++++++++++ .../task/vo/task/BpmTaskApproveReqVO.java | 3 - .../cc/BpmProcessInstanceCopyConvert.java | 26 +++++++ .../cc/BpmProcessInstanceCopyDO.java | 6 +- .../cc/BpmProcessInstanceCopyMapper.java | 12 ++++ .../candidate/BpmCandidateSourceInfo.java | 4 ++ .../BpmCandidateSourceInfoProcessorChain.java | 4 +- .../cc/BpmProcessInstanceCopyService.java | 20 ++++++ .../cc/BpmProcessInstanceCopyServiceImpl.java | 67 +++++++++++++++++-- .../service/cc/BpmProcessInstanceCopyVO.java | 14 ++++ .../bpm/service/task/BpmTaskServiceImpl.java | 12 ---- .../yudao/module/bpm/util/FlowableUtils.java | 50 ++++++++++++-- 16 files changed, 356 insertions(+), 27 deletions(-) create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCMyPageReqVO.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCPageItemRespVO.java create mode 100644 yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCReqVO.java diff --git a/sql/mysql/ruoyi-vue-pro.sql b/sql/mysql/ruoyi-vue-pro.sql index 98acf8be3..a6e1ee548 100644 --- a/sql/mysql/ruoyi-vue-pro.sql +++ b/sql/mysql/ruoyi-vue-pro.sql @@ -2478,6 +2478,15 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2523, '客户限制配置导出', 'crm:customer-limit-config:export', 3, 5, 2518, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-11-18 13:33:53', '', '2023-11-18 13:33:53', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2524, '系统配置', '', 1, 99, 2397, 'config', 'ep:connection', '', '', 0, b'1', b'1', b'1', '1', '2023-11-18 21:58:00', '1', '2023-11-18 21:58:00', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2525, 'WebSocket 测试', '', 2, 7, 2, 'websocket', 'ep:connection', 'infra/webSocket/index', 'InfraWebSocket', 0, b'1', b'1', b'1', '1', '2023-11-23 19:41:55', '1', '2023-11-24 19:22:30', b'0'); +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, + `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, + `updater`, `update_time`, `deleted`) +VALUES (2526, '抄送流程', '', 2, 21, 1200, 'processInstanceCC', 'eye', '/bpm/task/cc/index', + 'BpmCCProcessInstance', 0, true, true, true, 1, '2023-01-13 16:14:00', '1', '2023-01-13 16:14:00', false), + (2527, '抄送流程查询', 'bpm:process-instance-cc:query', 3, 1, 2526, '', '', '', NULL, 0, b'1', b'1', b'1', '1', + '2023-01-13 16:14:00', '1', '2023-01-13 16:14:00', b'0'), + (2528, '抄送流程创建', 'bpm:process-instance-cc:create', 3, 2, 2526, '', '', '', NULL, 0, b'1', b'1', b'1', '1', + '2023-01-13 16:14:00', '1', '2023-01-13 16:14:00', b'0'); COMMIT; -- ---------------------------- diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java index af8e8edcd..aab10348b 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java @@ -2,7 +2,9 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*; +import cn.iocoder.yudao.module.bpm.service.cc.BpmProcessInstanceCopyService; import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Parameter; @@ -26,6 +28,9 @@ public class BpmProcessInstanceController { @Resource private BpmProcessInstanceService processInstanceService; + @Resource + private BpmProcessInstanceCopyService processInstanceCopyService; + @GetMapping("/my-page") @Operation(summary = "获得我的实例分页列表", description = "在【我的流程】菜单中,进行调用") @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')") @@ -56,4 +61,20 @@ public class BpmProcessInstanceController { processInstanceService.cancelProcessInstance(getLoginUserId(), cancelReqVO); return success(true); } + + + @PostMapping("/cc/create") + @Operation(summary = "抄送流程") + @PreAuthorize("@ss.hasPermission('bpm:process-instance-cc:create')") + public CommonResult createProcessInstanceCC(@Valid @RequestBody BpmProcessInstanceCCReqVO createReqVO) { + return success(processInstanceCopyService.ccProcessInstance(SecurityFrameworkUtils.getLoginUserId(), createReqVO)); + } + + @GetMapping("/cc/my-page") + @Operation(summary = "获得抄送流程分页列表") + @PreAuthorize("@ss.hasPermission('bpm:process-instance-cc:query')") + public CommonResult> getProcessInstanceCCPage(@Valid BpmProcessInstanceCCMyPageReqVO pageReqVO) { + return success(processInstanceCopyService.getMyProcessInstanceCCPage(SecurityFrameworkUtils.getLoginUserId(), pageReqVO)); + } + } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCMyPageReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCMyPageReqVO.java new file mode 100644 index 000000000..803616bcb --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCMyPageReqVO.java @@ -0,0 +1,30 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDateTime; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +@Schema(description = "管理后台 - 流程实例抄送的分页 Item Response VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class BpmProcessInstanceCCMyPageReqVO extends PageParam { + + @Schema(description = "流程名称", example = "芋道") + private String name; + + @Schema(description = "流程编号", example = "123456768") + private String processInstanceId; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCPageItemRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCPageItemRespVO.java new file mode 100644 index 000000000..5b2a12e2d --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCPageItemRespVO.java @@ -0,0 +1,61 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - 流程实例抄送的分页 Item Response VO") +@Data +public class BpmProcessInstanceCCPageItemRespVO { + + /** + * 编号 + */ + @Schema(description = "抄送主键") + private Long id; + + /** + * 发起人Id + */ + @Schema(description = "发起人Id") + private Long startUserId; + + @Schema(description = "发起人别名") + private String startUserNickname; + /** + * 表单名 + */ + @Schema(description = "流程实例的名字") + private String name; + /** + * 流程主键 + */ + @Schema(description = "流程实例的主键") + private String processInstanceId; + + @Schema(description = "流程实例的名称") + private String processInstanceName; + /** + * 任务主键 + */ + @Schema(description = "发起抄送的任务编号") + private String taskId; + + @Schema(description = "发起抄送的任务名称") + private String taskName; + /** + * 用户主键 + */ + @Schema(description = "用户编号") + private Long userId; + + @Schema(description = "用户别名") + private String userNickname; + + @Schema(description = "抄送原因") + private String reason; + + @Schema(description = "抄送时间") + private LocalDateTime createTime; +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCReqVO.java new file mode 100644 index 000000000..0e108f524 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCReqVO.java @@ -0,0 +1,44 @@ +package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance; + +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateRuleVO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.Set; + +@Schema(description = "管理后台 - 流程实例的抄送 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class BpmProcessInstanceCCReqVO extends BpmTaskCandidateRuleVO { + + @Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + @NotEmpty(message = "任务编号不能为空") + private String taskKey; + + @Schema(description = "任务名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + @NotEmpty(message = "任务名称不能为空") + private String taskName; + + @Schema(description = "流程实例的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + @NotEmpty(message = "流程实例的编号不能为空") + private String processInstanceKey; + + @Schema(description = "发起流程的用户的编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + @NotNull(message = "发起流程的用户的编号不能为空") + private Long startUserId; + + + @Schema(description = "任务实例名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + @NotEmpty(message = "任务实例名称不能为空") + private String processInstanceName; + + @Schema(description = "抄送原因", requiredMode = Schema.RequiredMode.REQUIRED, example = "请帮忙审查下!") + @NotBlank(message = "抄送原因不能为空") + private String reason; +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java index c9b0e9121..1a79441ce 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskApproveReqVO.java @@ -18,7 +18,4 @@ public class BpmTaskApproveReqVO { @NotEmpty(message = "审批意见不能为空") private String reason; - @Schema(description = "审批时流程抄送人", requiredMode = Schema.RequiredMode.NOT_REQUIRED) - private BpmTaskCandidateRuleVO ccCandidateRule; - } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/cc/BpmProcessInstanceCopyConvert.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/cc/BpmProcessInstanceCopyConvert.java index 3e0a3cd45..07fc0864b 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/cc/BpmProcessInstanceCopyConvert.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/cc/BpmProcessInstanceCopyConvert.java @@ -1,11 +1,15 @@ package cn.iocoder.yudao.module.bpm.convert.cc; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCCPageItemRespVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.cc.BpmProcessInstanceCopyDO; import cn.iocoder.yudao.module.bpm.service.cc.BpmProcessInstanceCopyVO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; import java.util.List; +import java.util.Map; /** * 动态表单 Convert @@ -16,10 +20,32 @@ import java.util.List; public interface BpmProcessInstanceCopyConvert { BpmProcessInstanceCopyConvert INSTANCE = Mappers.getMapper(BpmProcessInstanceCopyConvert.class); + BpmProcessInstanceCopyDO copy(BpmProcessInstanceCopyDO bean); BpmProcessInstanceCopyVO convert(BpmProcessInstanceCopyDO bean); List convertList2(List list); + List convertList(List list); + + default PageResult convertPage(PageResult page + , Map taskMap + , Map processInstaneMap + , Map userMap + ) { + List list = convertList(page.getList()); + for (BpmProcessInstanceCCPageItemRespVO vo:list){ + MapUtils.findAndThen(userMap, vo.getUserId(), + userName -> vo.setUserNickname(userName)); + MapUtils.findAndThen(userMap, vo.getStartUserId(), + userName -> vo.setStartUserNickname(userName)); + MapUtils.findAndThen(taskMap, vo.getTaskId(), + name -> vo.setTaskName(name)); + MapUtils.findAndThen(processInstaneMap, vo.getProcessInstanceId(), + name -> vo.setProcessInstanceName(name)); + } + return new PageResult<>(list, page.getTotal()); + } + } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/cc/BpmProcessInstanceCopyDO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/cc/BpmProcessInstanceCopyDO.java index 4583bc7a7..b8e45e30a 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/cc/BpmProcessInstanceCopyDO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/cc/BpmProcessInstanceCopyDO.java @@ -31,7 +31,7 @@ public class BpmProcessInstanceCopyDO extends BaseDO { */ private Long startUserId; /** - * 表单名 + * 流程名 */ private String name; /** @@ -48,5 +48,9 @@ public class BpmProcessInstanceCopyDO extends BaseDO { */ private Long userId; + /** + * 抄送原因 + */ + private String reason; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/cc/BpmProcessInstanceCopyMapper.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/cc/BpmProcessInstanceCopyMapper.java index c911aa9c5..ba5a4d94a 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/cc/BpmProcessInstanceCopyMapper.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/cc/BpmProcessInstanceCopyMapper.java @@ -1,9 +1,21 @@ package cn.iocoder.yudao.module.bpm.dal.mysql.cc; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCCMyPageReqVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.cc.BpmProcessInstanceCopyDO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; import org.apache.ibatis.annotations.Mapper; @Mapper public interface BpmProcessInstanceCopyMapper extends BaseMapperX { + default PageResult selectPage(Long loginUserId, BpmProcessInstanceCCMyPageReqVO reqVO){ + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(BpmProcessInstanceCopyDO::getUserId, loginUserId) + .eqIfPresent(BpmProcessInstanceCopyDO::getProcessInstanceId, reqVO.getProcessInstanceId()) + .likeIfPresent(BpmProcessInstanceCopyDO::getName, reqVO.getName()) + .betweenIfPresent(BpmProcessInstanceCopyDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(BpmProcessInstanceCopyDO::getId)); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfo.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfo.java index 52ef13ffd..6dda9ebf2 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfo.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfo.java @@ -36,6 +36,10 @@ public class BpmCandidateSourceInfo { @Schema(description = "发起抄送的用户") private String creator; + @Schema(description = "抄送原因", requiredMode = Schema.RequiredMode.REQUIRED, example = "请帮忙审查下!") + @NotEmpty(message = "抄送原因不能为空") + private String reason; + public void addRule(BpmTaskCandidateRuleVO vo) { assert vo != null; if (rules == null) { diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChain.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChain.java index d486b96b3..63b5356ce 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChain.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChain.java @@ -48,7 +48,9 @@ public class BpmCandidateSourceInfoProcessorChain { for (BpmCandidateSourceInfoProcessor processor : processorList) { try { for (BpmTaskCandidateRuleVO vo : sourceInfo.getRules()) { - processor.validRuleOptions(vo.getType(), vo.getOptions()); + if (CollUtil.contains(processor.getSupportedTypes(), vo.getType())) { + processor.validRuleOptions(vo.getType(), vo.getOptions()); + } } } catch (Exception e) { e.printStackTrace(); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyService.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyService.java index 58ee02b8e..20285639d 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyService.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyService.java @@ -1,5 +1,9 @@ package cn.iocoder.yudao.module.bpm.service.cc; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCCMyPageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCCPageItemRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCCReqVO; import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; /** @@ -23,4 +27,20 @@ public interface BpmProcessInstanceCopyService { * @return */ boolean makeCopy(BpmCandidateSourceInfo sourceInfo); + + /** + * 流程实例的抄送 + * @param loginUserId 当前登录用户 + * @param createReqVO 创建的抄送请求 + * @return 是否抄送成功,抄送成功则返回true + */ + boolean ccProcessInstance(Long loginUserId, BpmProcessInstanceCCReqVO createReqVO); + + /** + * 抄送的流程 + * @param loginUserId 登录用户id + * @param pageReqVO 分页请求 + * @return 抄送的分页结果 + */ + PageResult getMyProcessInstanceCCPage(Long loginUserId, BpmProcessInstanceCCMyPageReqVO pageReqVO); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java index 4f074472a..bde73852b 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java @@ -1,25 +1,32 @@ package cn.iocoder.yudao.module.bpm.service.cc; import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCCMyPageReqVO; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCCPageItemRespVO; +import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCCReqVO; import cn.iocoder.yudao.module.bpm.convert.cc.BpmProcessInstanceCopyConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.cc.BpmProcessInstanceCopyDO; import cn.iocoder.yudao.module.bpm.dal.mysql.cc.BpmProcessInstanceCopyMapper; import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessorChain; import cn.iocoder.yudao.module.bpm.service.cc.dto.BpmDelegateExecutionDTO; +import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService; import cn.iocoder.yudao.module.bpm.util.FlowableUtils; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import lombok.extern.slf4j.Slf4j; import org.flowable.engine.RuntimeService; import org.flowable.engine.delegate.DelegateExecution; import org.flowable.engine.runtime.ProcessInstance; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; +import java.util.*; +import java.util.stream.Collectors; @Slf4j @Service @@ -40,6 +47,12 @@ public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopy @Resource private BpmCandidateSourceInfoProcessorChain processorChain; + @Resource + @Lazy // 解决循环依赖 + private BpmTaskService taskService; + @Resource + private AdminUserApi adminUserApi; + @Override public BpmProcessInstanceCopyVO queryById(Long copyId) { BpmProcessInstanceCopyDO bpmProcessInstanceCopyDO = processInstanceCopyMapper.selectById(copyId); @@ -60,7 +73,7 @@ public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopy } else { BpmProcessInstanceCopyDO copyDO = new BpmProcessInstanceCopyDO(); // 调用 - //设置任务id + // 设置任务id copyDO.setTaskId(sourceInfo.getTaskId()); copyDO.setProcessInstanceId(sourceInfo.getProcessInstanceId()); ProcessInstance processInstance = runtimeService.createProcessInstanceQuery() @@ -72,6 +85,7 @@ public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopy } copyDO.setStartUserId(FlowableUtils.getStartUserIdFromProcessInstance(processInstance)); copyDO.setName(FlowableUtils.getFlowName(processInstance.getProcessDefinitionId())); + copyDO.setReason(sourceInfo.getReason()); copyDO.setCreator(sourceInfo.getCreator()); copyDO.setCreateTime(LocalDateTime.now()); List copyList = new ArrayList<>(ccCandidates.size()); @@ -84,9 +98,50 @@ public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopy } } - public List queryByProcessId() { - return null; + @Override + public boolean ccProcessInstance(Long loginUserId, BpmProcessInstanceCCReqVO reqVO) { + // 在能正常审批的情况下抄送流程 + BpmCandidateSourceInfo sourceInfo = new BpmCandidateSourceInfo(); + sourceInfo.setTaskId(reqVO.getTaskKey()); + sourceInfo.setProcessInstanceId(reqVO.getProcessInstanceKey()); + sourceInfo.addRule(reqVO); + sourceInfo.setCreator(String.valueOf(loginUserId)); + sourceInfo.setReason(reqVO.getReason()); + if (!makeCopy(sourceInfo)) { + throw new RuntimeException("抄送任务失败"); + } + return false; } + //获取流程抄送分页 + @Override + public PageResult getMyProcessInstanceCCPage(Long loginUserId, BpmProcessInstanceCCMyPageReqVO pageReqVO) { + // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 + PageResult pageResult = processInstanceCopyMapper.selectPage(loginUserId, pageReqVO); + if (CollUtil.isEmpty(pageResult.getList())) { + return new PageResult<>(pageResult.getTotal()); + } + + Set taskIds = new HashSet<>(); + Set processInstaneIds = new HashSet<>(); + Set userIds = new HashSet<>(); + for (BpmProcessInstanceCopyDO doItem : pageResult.getList()) { + taskIds.add(doItem.getTaskId()); + processInstaneIds.add(doItem.getProcessInstanceId()); + userIds.add(doItem.getStartUserId()); + Long userId = Long.valueOf(doItem.getCreator()); + userIds.add(userId); + doItem.setUserId(userId); + } + + Map taskNameByTaskIds = FlowableUtils.getTaskNameByTaskIds(taskIds); + Map processInstanceNameByTaskIds = FlowableUtils.getProcessInstanceNameByTaskIds(processInstaneIds); + + Map userMap = adminUserApi.getUserList(userIds).stream().collect(Collectors.toMap( + AdminUserRespDTO::getId, AdminUserRespDTO::getNickname)); + + // 转换返回 + return BpmProcessInstanceCopyConvert.INSTANCE.convertPage(pageResult, taskNameByTaskIds, processInstanceNameByTaskIds, userMap); + } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyVO.java index f99d92f89..1cf0bc6b4 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyVO.java @@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.TableId; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import java.time.LocalDateTime; import java.util.Date; @@ -27,6 +28,9 @@ public class BpmProcessInstanceCopyVO { */ @Schema(description = "发起人Id") private Long startUserId; + + @Schema(description = "发起人别名") + private String startUserNickname; /** * 表单名 */ @@ -38,14 +42,24 @@ public class BpmProcessInstanceCopyVO { @Schema(description = "流程实例的主键") private String processInstanceId; + @Schema(description = "流程实例的名字") + private String processInstanceName; + /** * 任务主键 */ @Schema(description = "发起抄送的任务编号") private String taskId; + /** * 用户主键 */ @Schema(description = "用户编号") private Long userId; + + @Schema(description = "用户别名") + private Long userNickname; + + @Schema(description = "抄送时间") + private LocalDateTime createTime; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java index 416d31645..27a4c7763 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java @@ -242,18 +242,6 @@ public class BpmTaskServiceImpl implements BpmTaskService { .setReason(reqVO.getReason())); // 处理加签任务 handleParentTask(task); - - // 在能正常审批的情况下抄送流程 - if (null != reqVO.getCcCandidateRule()) { - BpmCandidateSourceInfo sourceInfo = new BpmCandidateSourceInfo(); - sourceInfo.setTaskId(reqVO.getId()); - sourceInfo.setProcessInstanceId(instance.getId()); - sourceInfo.addRule(reqVO.getCcCandidateRule()); - sourceInfo.setCreator(String.valueOf(userId)); - if (!processInstanceCopyService.makeCopy(sourceInfo)) { - throw new RuntimeException("抄送任务失败"); - } - } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/util/FlowableUtils.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/util/FlowableUtils.java index 8e8764faa..99f2a3761 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/util/FlowableUtils.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/util/FlowableUtils.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.bpm.util; +import cn.hutool.core.collection.CollUtil; import cn.hutool.extra.spring.SpringUtil; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import org.flowable.bpmn.model.BpmnModel; @@ -9,11 +10,12 @@ import org.flowable.bpmn.model.FlowElement; import org.flowable.bpmn.model.FlowNode; import org.flowable.engine.RepositoryService; import org.flowable.engine.RuntimeService; +import org.flowable.engine.TaskService; import org.flowable.engine.repository.ProcessDefinition; import org.flowable.engine.runtime.ProcessInstance; +import org.flowable.task.api.Task; -import java.util.List; -import java.util.Map; +import java.util.*; /** * 流程引擎工具类封装 @@ -47,9 +49,9 @@ public class FlowableUtils { RuntimeService runtimeService = SpringUtil.getBean(RuntimeService.class); RepositoryService repositoryService = SpringUtil.getBean(RepositoryService.class); - String definitionld = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult().getProcessDefinitionId(); //获取bpm(模型)对象 + String definitionld = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult().getProcessDefinitionId(); // 获取bpm(模型)对象 BpmnModel bpmnModel = repositoryService.getBpmnModel(definitionld); - //传节点定义key获取当前节点 + // 传节点定义key获取当前节点 FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(nodeId); return flowNode; } @@ -75,4 +77,44 @@ public class FlowableUtils { return NumberUtils.parseLong(instance.getStartUserId()); } + public static String getTaskNameByTaskId(String taskId) { + TaskService taskService = SpringUtil.getBean(TaskService.class); + Task task = taskService.createTaskQuery().taskId(taskId).singleResult(); + return task.getName(); + } + + public static Map getTaskNameByTaskIds(Collection taskIds) { + TaskService taskService = SpringUtil.getBean(TaskService.class); + List tasks = taskService.createTaskQuery().taskIds(taskIds).list(); + if (CollUtil.isNotEmpty(tasks)) { + Map taskMap = new HashMap<>(tasks.size()); + for (Task task : tasks) { + taskMap.putIfAbsent(task.getId(), task.getName()); + } + return taskMap; + } + return Collections.emptyMap(); + } + + public static String getProcessInstanceNameByTaskId(String processInstanceId) { + RuntimeService runtimeService = SpringUtil.getBean(RuntimeService.class); + ProcessInstance processInstance = runtimeService.createProcessInstanceQuery() + .processInstanceId(processInstanceId) + .singleResult(); + return processInstance.getName(); + } + + public static Map getProcessInstanceNameByTaskIds(Set taskIds) { + RuntimeService runtimeService = SpringUtil.getBean(RuntimeService.class); + List processInstances = runtimeService.createProcessInstanceQuery().processInstanceIds(taskIds).list(); + if (CollUtil.isNotEmpty(processInstances)) { + Map processInstaneMap = new HashMap<>(processInstances.size()); + for (ProcessInstance processInstance : processInstances) { + processInstaneMap.putIfAbsent(processInstance.getId(), processInstance.getName()); + } + return processInstaneMap; + } + return Collections.emptyMap(); + } + } From 9df6cc76e71c498653457498b640da93600e5aad Mon Sep 17 00:00:00 2001 From: kyle <573984425@qq.com> Date: Tue, 16 Jan 2024 11:22:24 +0800 Subject: [PATCH 08/27] =?UTF-8?q?feat:=20=E4=BF=AE=E6=AD=A3=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/candidate/vo/BpmTaskCandidateRuleVO.java | 2 +- .../admin/task/vo/instance/BpmProcessInstanceCCReqVO.java | 6 +++--- .../bpm/service/candidate/BpmCandidateSourceInfo.java | 4 ++-- .../candidate/BpmCandidateSourceInfoProcessorChain.java | 2 +- .../BpmCandidateAdminUserApiSourceInfoProcessor.java | 2 +- .../BpmCandidateDeptApiSourceInfoProcessor.java | 2 +- .../BpmCandidatePostApiSourceInfoProcessor.java | 2 +- .../BpmCandidateRoleApiSourceInfoProcessor.java | 2 +- .../BpmCandidateScriptApiSourceInfoProcessor.java | 2 +- .../BpmCandidateUserGroupApiSourceInfoProcessor.java | 2 +- .../bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java | 2 +- 11 files changed, 14 insertions(+), 14 deletions(-) diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/candidate/vo/BpmTaskCandidateRuleVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/candidate/vo/BpmTaskCandidateRuleVO.java index 86ee2d596..25426f604 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/candidate/vo/BpmTaskCandidateRuleVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/candidate/vo/BpmTaskCandidateRuleVO.java @@ -2,9 +2,9 @@ package cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleBaseVO; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; import lombok.Data; -import javax.validation.constraints.NotNull; import java.util.Set; /** diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCReqVO.java index 0e108f524..c1a73fb24 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCReqVO.java @@ -2,13 +2,13 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance; import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateRuleVO; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; import java.util.Set; @Schema(description = "管理后台 - 流程实例的抄送 Request VO") diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfo.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfo.java index 6dda9ebf2..8582ad9a0 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfo.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfo.java @@ -6,8 +6,8 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; import java.util.HashSet; import java.util.Set; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChain.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChain.java index 63b5356ce..dafc0835a 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChain.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChain.java @@ -10,7 +10,7 @@ import org.flowable.engine.delegate.DelegateExecution; import org.springframework.beans.factory.ObjectProvider; import org.springframework.stereotype.Service; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import java.util.*; @Service diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateAdminUserApiSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateAdminUserApiSourceInfoProcessor.java index 15c89176a..536b3eec2 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateAdminUserApiSourceInfoProcessor.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateAdminUserApiSourceInfoProcessor.java @@ -8,7 +8,7 @@ import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProce import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import org.flowable.engine.delegate.DelegateExecution; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import java.util.Set; public class BpmCandidateAdminUserApiSourceInfoProcessor implements BpmCandidateSourceInfoProcessor { diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateDeptApiSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateDeptApiSourceInfoProcessor.java index 71a7fc87e..6fcfa23fd 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateDeptApiSourceInfoProcessor.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateDeptApiSourceInfoProcessor.java @@ -11,7 +11,7 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import org.flowable.engine.delegate.DelegateExecution; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import java.util.Collections; import java.util.List; import java.util.Objects; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidatePostApiSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidatePostApiSourceInfoProcessor.java index f4a885960..f924d87ef 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidatePostApiSourceInfoProcessor.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidatePostApiSourceInfoProcessor.java @@ -10,7 +10,7 @@ import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import org.flowable.engine.delegate.DelegateExecution; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import java.util.List; import java.util.Set; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateRoleApiSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateRoleApiSourceInfoProcessor.java index 92cda1fd6..f3ba5b92b 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateRoleApiSourceInfoProcessor.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateRoleApiSourceInfoProcessor.java @@ -9,7 +9,7 @@ import cn.iocoder.yudao.module.system.api.permission.PermissionApi; import cn.iocoder.yudao.module.system.api.permission.RoleApi; import org.flowable.engine.delegate.DelegateExecution; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import java.util.Set; public class BpmCandidateRoleApiSourceInfoProcessor implements BpmCandidateSourceInfoProcessor { diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateScriptApiSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateScriptApiSourceInfoProcessor.java index acfcc9844..4bf25694d 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateScriptApiSourceInfoProcessor.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateScriptApiSourceInfoProcessor.java @@ -13,7 +13,7 @@ import cn.iocoder.yudao.module.system.api.dict.DictDataApi; import org.flowable.engine.delegate.DelegateExecution; import org.springframework.beans.factory.ObjectProvider; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import java.util.*; import java.util.stream.Collectors; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateUserGroupApiSourceInfoProcessor.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateUserGroupApiSourceInfoProcessor.java index 42929b413..b0720b0d5 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateUserGroupApiSourceInfoProcessor.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateUserGroupApiSourceInfoProcessor.java @@ -9,7 +9,7 @@ import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProce import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; import org.flowable.engine.delegate.DelegateExecution; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import java.util.HashSet; import java.util.List; import java.util.Set; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java index bde73852b..42cd570bf 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java @@ -23,7 +23,7 @@ import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; -import javax.annotation.Resource; +import jakarta.annotation.Resource; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; From fc2a8f13110f1f46e5c765f5da6e44431d96c21f Mon Sep 17 00:00:00 2001 From: kyle <573984425@qq.com> Date: Tue, 16 Jan 2024 11:50:12 +0800 Subject: [PATCH 09/27] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E4=BE=9D=E8=B5=96=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../candidate/BpmCandidateSourceInfoProcessorChainTest.java | 5 ++--- .../bpm/service/cc/BpmProcessInstanceCopyServiceTest.java | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChainTest.java b/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChainTest.java index 5c326fc0f..38eb7cbea 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChainTest.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChainTest.java @@ -8,7 +8,6 @@ import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidat import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; -import cn.iocoder.yudao.module.bpm.framework.bpm.config.BpmCandidateProcessorConfiguration; import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl.BpmTaskAssignLeaderX1Script; import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl.BpmTaskAssignLeaderX2Script; @@ -22,12 +21,12 @@ import cn.iocoder.yudao.module.system.api.permission.PermissionApi; import cn.iocoder.yudao.module.system.api.permission.RoleApi; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; +import jakarta.annotation.Resource; import org.flowable.engine.delegate.DelegateExecution; import org.junit.jupiter.api.Test; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; -import javax.annotation.Resource; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -40,7 +39,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; -@Import({BpmCandidateSourceInfoProcessorChain.class, BpmCandidateProcessorConfiguration.class, +@Import({BpmCandidateSourceInfoProcessorChain.class, BpmCandidateScriptApiSourceInfoProcessor.class, BpmTaskAssignLeaderX1Script.class, BpmTaskAssignLeaderX2Script.class}) public class BpmCandidateSourceInfoProcessorChainTest extends BaseDbUnitTest { diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceTest.java b/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceTest.java index 42a1d46e8..1f0ced103 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceTest.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceTest.java @@ -1,11 +1,10 @@ package cn.iocoder.yudao.module.bpm.service.cc; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import jakarta.annotation.Resource; import org.junit.jupiter.api.Test; import org.springframework.context.annotation.Import; -import javax.annotation.Resource; - @Import({BpmProcessInstanceCopyServiceImpl.class}) class BpmProcessInstanceCopyServiceTest extends BaseDbUnitTest { @Resource From 6dbc942cdd8274908be3fcce235de479b8b79b39 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Tue, 16 Jan 2024 22:41:37 +0800 Subject: [PATCH 10/27] =?UTF-8?q?=E2=9C=A8=20MALL=EF=BC=9A=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E5=94=AE=E5=90=8E=E7=A1=AE=E8=AE=A4=E9=80=80=E6=AC=BE?= =?UTF-8?q?=E6=97=B6=EF=BC=8C=E7=BC=BA=E5=B0=91=E9=80=80=E6=AC=BE=E6=8F=8F?= =?UTF-8?q?=E8=BF=B0=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/trade/service/aftersale/AfterSaleServiceImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java index 98aaa8b98..379ec86c5 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/AfterSaleServiceImpl.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.service.aftersale; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; @@ -368,7 +369,8 @@ public class AfterSaleServiceImpl implements AfterSaleService { @Override public void afterCommit() { // 创建退款单 - PayRefundCreateReqDTO createReqDTO = AfterSaleConvert.INSTANCE.convert(userIp, afterSale, tradeOrderProperties); + PayRefundCreateReqDTO createReqDTO = AfterSaleConvert.INSTANCE.convert(userIp, afterSale, tradeOrderProperties) + .setReason(StrUtil.format("退款【{}】", afterSale.getSpuName())); Long payRefundId = payRefundApi.createRefund(createReqDTO); // 更新售后单的退款单号 tradeAfterSaleMapper.updateById(new AfterSaleDO().setId(afterSale.getId()).setPayRefundId(payRefundId)); From 3720a648d78dc0bbc70f826eb4ec003058e54cb2 Mon Sep 17 00:00:00 2001 From: kyle <573984425@qq.com> Date: Wed, 17 Jan 2024 09:29:14 +0800 Subject: [PATCH 11/27] =?UTF-8?q?refactor:=20=E6=B7=BB=E5=8A=A0=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E7=BC=BA=E5=B0=91=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BpmProcessInstanceCCMyPageReqVO.java | 2 +- .../BpmProcessInstanceCCPageItemRespVO.java | 20 +++++++------------ .../cc/BpmProcessInstanceCopyConvert.java | 12 +++++------ .../cc/BpmProcessInstanceCopyDO.java | 13 +++++++++++- .../cc/BpmProcessInstanceCopyMapper.java | 3 +-- .../cc/BpmProcessInstanceCopyServiceImpl.java | 7 +++++-- .../service/cc/BpmProcessInstanceCopyVO.java | 14 ++++++++----- .../yudao/module/bpm/util/FlowableUtils.java | 7 ++++++- 8 files changed, 47 insertions(+), 31 deletions(-) diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCMyPageReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCMyPageReqVO.java index 803616bcb..44de17d38 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCMyPageReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCMyPageReqVO.java @@ -18,7 +18,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ public class BpmProcessInstanceCCMyPageReqVO extends PageParam { @Schema(description = "流程名称", example = "芋道") - private String name; + private String processInstanceName; @Schema(description = "流程编号", example = "123456768") private String processInstanceId; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCPageItemRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCPageItemRespVO.java index 5b2a12e2d..2315730ff 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCPageItemRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCPageItemRespVO.java @@ -23,11 +23,7 @@ public class BpmProcessInstanceCCPageItemRespVO { @Schema(description = "发起人别名") private String startUserNickname; - /** - * 表单名 - */ - @Schema(description = "流程实例的名字") - private String name; + /** * 流程主键 */ @@ -44,18 +40,16 @@ public class BpmProcessInstanceCCPageItemRespVO { @Schema(description = "发起抄送的任务名称") private String taskName; - /** - * 用户主键 - */ - @Schema(description = "用户编号") - private Long userId; - - @Schema(description = "用户别名") - private String userNickname; @Schema(description = "抄送原因") private String reason; + @Schema(description = "抄送人") + private String creator; + + @Schema(description = "抄送人别名") + private String creatorNickname; + @Schema(description = "抄送时间") private LocalDateTime createTime; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/cc/BpmProcessInstanceCopyConvert.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/cc/BpmProcessInstanceCopyConvert.java index 07fc0864b..49327a134 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/cc/BpmProcessInstanceCopyConvert.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/cc/BpmProcessInstanceCopyConvert.java @@ -35,15 +35,15 @@ public interface BpmProcessInstanceCopyConvert { , Map userMap ) { List list = convertList(page.getList()); - for (BpmProcessInstanceCCPageItemRespVO vo:list){ - MapUtils.findAndThen(userMap, vo.getUserId(), - userName -> vo.setUserNickname(userName)); + for (BpmProcessInstanceCCPageItemRespVO vo : list) { + MapUtils.findAndThen(userMap, Long.valueOf(vo.getCreator()), + vo::setCreatorNickname); MapUtils.findAndThen(userMap, vo.getStartUserId(), - userName -> vo.setStartUserNickname(userName)); + vo::setStartUserNickname); MapUtils.findAndThen(taskMap, vo.getTaskId(), - name -> vo.setTaskName(name)); + vo::setTaskName); MapUtils.findAndThen(processInstaneMap, vo.getProcessInstanceId(), - name -> vo.setProcessInstanceName(name)); + vo::setProcessInstanceName); } return new PageResult<>(list, page.getTotal()); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/cc/BpmProcessInstanceCopyDO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/cc/BpmProcessInstanceCopyDO.java index b8e45e30a..1735f021e 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/cc/BpmProcessInstanceCopyDO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/cc/BpmProcessInstanceCopyDO.java @@ -33,7 +33,7 @@ public class BpmProcessInstanceCopyDO extends BaseDO { /** * 流程名 */ - private String name; + private String processInstanceName; /** * 流程主键 */ @@ -43,6 +43,12 @@ public class BpmProcessInstanceCopyDO extends BaseDO { * 任务主键 */ private String taskId; + + /** + * 任务名称 + */ + private String taskName; + /** * 用户主键 */ @@ -53,4 +59,9 @@ public class BpmProcessInstanceCopyDO extends BaseDO { */ private String reason; + /** + * 流程分类 + */ + private String processDefinitionCategory; + } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/cc/BpmProcessInstanceCopyMapper.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/cc/BpmProcessInstanceCopyMapper.java index ba5a4d94a..af697f4e7 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/cc/BpmProcessInstanceCopyMapper.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/cc/BpmProcessInstanceCopyMapper.java @@ -5,7 +5,6 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCCMyPageReqVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.cc.BpmProcessInstanceCopyDO; -import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmProcessInstanceExtDO; import org.apache.ibatis.annotations.Mapper; @Mapper @@ -14,7 +13,7 @@ public interface BpmProcessInstanceCopyMapper extends BaseMapperX() .eqIfPresent(BpmProcessInstanceCopyDO::getUserId, loginUserId) .eqIfPresent(BpmProcessInstanceCopyDO::getProcessInstanceId, reqVO.getProcessInstanceId()) - .likeIfPresent(BpmProcessInstanceCopyDO::getName, reqVO.getName()) + .likeIfPresent(BpmProcessInstanceCopyDO::getProcessInstanceName, reqVO.getProcessInstanceName()) .betweenIfPresent(BpmProcessInstanceCopyDO::getCreateTime, reqVO.getCreateTime()) .orderByDesc(BpmProcessInstanceCopyDO::getId)); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java index 42cd570bf..865a6f699 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java @@ -18,6 +18,7 @@ import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import lombok.extern.slf4j.Slf4j; import org.flowable.engine.RuntimeService; import org.flowable.engine.delegate.DelegateExecution; +import org.flowable.engine.repository.ProcessDefinition; import org.flowable.engine.runtime.ProcessInstance; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; @@ -75,6 +76,7 @@ public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopy // 调用 // 设置任务id copyDO.setTaskId(sourceInfo.getTaskId()); + copyDO.setTaskName(FlowableUtils.getTaskNameByTaskId(sourceInfo.getTaskId())); copyDO.setProcessInstanceId(sourceInfo.getProcessInstanceId()); ProcessInstance processInstance = runtimeService.createProcessInstanceQuery() .processInstanceId(sourceInfo.getProcessInstanceId()) @@ -84,7 +86,9 @@ public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopy return false; } copyDO.setStartUserId(FlowableUtils.getStartUserIdFromProcessInstance(processInstance)); - copyDO.setName(FlowableUtils.getFlowName(processInstance.getProcessDefinitionId())); + copyDO.setProcessInstanceName(processInstance.getName()); + ProcessDefinition processDefinition = FlowableUtils.getProcessDefinition(processInstance.getProcessDefinitionId()); + copyDO.setProcessDefinitionCategory(processDefinition.getCategory()); copyDO.setReason(sourceInfo.getReason()); copyDO.setCreator(sourceInfo.getCreator()); copyDO.setCreateTime(LocalDateTime.now()); @@ -131,7 +135,6 @@ public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopy userIds.add(doItem.getStartUserId()); Long userId = Long.valueOf(doItem.getCreator()); userIds.add(userId); - doItem.setUserId(userId); } Map taskNameByTaskIds = FlowableUtils.getTaskNameByTaskIds(taskIds); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyVO.java index 1cf0bc6b4..773335837 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyVO.java @@ -31,11 +31,7 @@ public class BpmProcessInstanceCopyVO { @Schema(description = "发起人别名") private String startUserNickname; - /** - * 表单名 - */ - @Schema(description = "流程实例的名字") - private String name; + /** * 流程主键 */ @@ -51,6 +47,8 @@ public class BpmProcessInstanceCopyVO { @Schema(description = "发起抄送的任务编号") private String taskId; + @Schema(description = "发起抄送的任务名称") + private String taskName; /** * 用户主键 */ @@ -60,6 +58,12 @@ public class BpmProcessInstanceCopyVO { @Schema(description = "用户别名") private Long userNickname; + @Schema(description = "抄送原因") + private String reason; + + @Schema(description = "抄送人") + private String creator; + @Schema(description = "抄送时间") private LocalDateTime createTime; } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/util/FlowableUtils.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/util/FlowableUtils.java index 99f2a3761..94dabcd8e 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/util/FlowableUtils.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/util/FlowableUtils.java @@ -31,12 +31,17 @@ public class FlowableUtils { * @param processDefinitionId * @return */ - public static String getFlowName(String processDefinitionId) { + public static String getProcessDefinitionName(String processDefinitionId) { RepositoryService repositoryService = SpringUtil.getBean(RepositoryService.class); ProcessDefinition processDefinition = repositoryService.getProcessDefinition(processDefinitionId); return processDefinition.getName(); } + public static ProcessDefinition getProcessDefinition(String processDefinitionId) { + RepositoryService repositoryService = SpringUtil.getBean(RepositoryService.class); + return repositoryService.getProcessDefinition(processDefinitionId); + } + /** * 获取节点数据 * From ff9cef6a92c8433ea9043ac34792fa59e151feec Mon Sep 17 00:00:00 2001 From: puhui999 Date: Wed, 17 Jan 2024 12:00:51 +0800 Subject: [PATCH 12/27] =?UTF-8?q?CRM:=20=E5=AE=8C=E5=96=84=E8=B7=9F?= =?UTF-8?q?=E8=BF=9B=EF=BC=8C=E6=96=B0=E5=A2=9E=E8=B7=9F=E8=BF=9B=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E5=A4=84=E7=90=86=E5=99=A8=20handler=20=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E2=9C=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/crm/enums/ErrorCodeConstants.java | 1 + .../admin/contact/CrmContactController.java | 7 +- .../followup/CrmFollowUpRecordController.java | 11 +-- .../service/business/CrmBusinessService.java | 8 ++ .../business/CrmBusinessServiceImpl.java | 13 ++- .../bo/CrmBusinessUpdateFollowUpReqBO.java | 37 ++++++++ .../crm/service/clue/CrmClueService.java | 8 ++ .../crm/service/clue/CrmClueServiceImpl.java | 6 ++ .../clue/bo/CrmClueUpdateFollowUpReqBO.java | 37 ++++++++ .../service/contact/CrmContactService.java | 17 ++++ .../contact/CrmContactServiceImpl.java | 14 ++++ .../bo/CrmContactUpdateFollowUpReqBO.java | 37 ++++++++ .../service/contract/CrmContractService.java | 24 ++++-- .../contract/CrmContractServiceImpl.java | 6 ++ .../bo/CrmContractUpdateFollowUpReqBO.java | 37 ++++++++ .../service/customer/CrmCustomerService.java | 8 ++ .../customer/CrmCustomerServiceImpl.java | 6 ++ .../bo/CrmCustomerUpdateFollowUpReqBO.java | 32 +++++++ .../followup/CrmFollowUpRecordService.java | 18 ++-- .../CrmFollowUpRecordServiceImpl.java | 84 +++++++++++++++---- .../handle/CrmBusinessFollowUpHandler.java | 38 +++++++++ .../handle/CrmClueFollowUpHandler.java | 37 ++++++++ .../handle/CrmContactFollowUpHandler.java | 38 +++++++++ .../handle/CrmContractFollowUpHandler.java | 37 ++++++++ .../handle/CrmCustomerFollowUpHandler.java | 37 ++++++++ .../followup/handle/CrmFollowUpHandler.java | 22 +++++ .../ProductCategoryServiceImplTest.java | 34 ++++---- 27 files changed, 581 insertions(+), 73 deletions(-) create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/bo/CrmBusinessUpdateFollowUpReqBO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/bo/CrmClueUpdateFollowUpReqBO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/bo/CrmContactUpdateFollowUpReqBO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/bo/CrmContractUpdateFollowUpReqBO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/bo/CrmCustomerUpdateFollowUpReqBO.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmBusinessFollowUpHandler.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmClueFollowUpHandler.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmContactFollowUpHandler.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmContractFollowUpHandler.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmCustomerFollowUpHandler.java create mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmFollowUpHandler.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 7df94068e..616c8685c 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 @@ -84,5 +84,6 @@ public interface ErrorCodeConstants { // ========== 跟进记录 1_020_013_000 ========== ErrorCode FOLLOW_UP_RECORD_NOT_EXISTS = new ErrorCode(1_020_013_000, "跟进记录不存在"); + ErrorCode FOLLOW_UP_RECORD_DELETE_DENIED = new ErrorCode(1_020_013_001, "删除跟进记录失败,原因:没有权限"); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java index 4b3e7d1e2..4e2e73e81 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contact/CrmContactController.java @@ -125,11 +125,8 @@ public class CrmContactController { @Operation(summary = "获得联系人的精简列表") @PreAuthorize("@ss.hasPermission('crm:contact:query')") public CommonResult> getSimpleContactList() { - // TODO @puhui999:这种还是搞个 getContactList 方法好点哈; - CrmContactPageReqVO reqVO = new CrmContactPageReqVO(); - reqVO.setPageSize(PAGE_SIZE_NONE); // 不分页 - PageResult pageResult = contactService.getContactPage(reqVO, getLoginUserId()); - return success(convertList(pageResult.getList(), contact -> // 只返回 id、name 字段 + List list = contactService.getSimpleContactList(getLoginUserId()); + return success(convertList(list, contact -> // 只返回 id、name 字段 new CrmContactRespVO().setId(contact.getId()).setName(contact.getName()))); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/CrmFollowUpRecordController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/CrmFollowUpRecordController.java index bf63e4542..399696bf4 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/CrmFollowUpRecordController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/CrmFollowUpRecordController.java @@ -28,6 +28,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.convertMap; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @Tag(name = "管理后台 - 跟进记录") @@ -50,20 +51,12 @@ public class CrmFollowUpRecordController { return success(crmFollowUpRecordService.createFollowUpRecord(createReqVO)); } - @PutMapping("/update") - @Operation(summary = "更新跟进记录") - @PreAuthorize("@ss.hasPermission('crm:follow-up-record:update')") - public CommonResult updateFollowUpRecord(@Valid @RequestBody CrmFollowUpRecordSaveReqVO updateReqVO) { - crmFollowUpRecordService.updateFollowUpRecord(updateReqVO); - return success(true); - } - @DeleteMapping("/delete") @Operation(summary = "删除跟进记录") @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('crm:follow-up-record:delete')") public CommonResult deleteFollowUpRecord(@RequestParam("id") Long id) { - crmFollowUpRecordService.deleteFollowUpRecord(id); + crmFollowUpRecordService.deleteFollowUpRecord(id, getLoginUserId()); return success(true); } 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 c914766b2..8dae99eb8 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 @@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusi import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 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.CrmBusinessUpdateFollowUpReqBO; import jakarta.validation.Valid; import java.util.Collection; @@ -35,6 +36,13 @@ public interface CrmBusinessService { */ void updateBusiness(@Valid CrmBusinessSaveReqVO updateReqVO); + /** + * 更新商机相关跟进信息 + * + * @param updateFollowUpReqBOList 跟进信息 + */ + void updateContactFollowUpBatch(List updateFollowUpReqBOList); + /** * 删除商机 * 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 5d2ed6853..2feee4d69 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 @@ -8,7 +8,6 @@ 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.controller.admin.business.vo.product.CrmBusinessProductSaveReqVO; -import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductSaveReqVO; import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessConvert; import cn.iocoder.yudao.module.crm.convert.businessproduct.CrmBusinessProductConvert; import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; @@ -22,6 +21,7 @@ import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper; import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; 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.CrmBusinessUpdateFollowUpReqBO; import cn.iocoder.yudao.module.crm.service.contact.CrmContactBusinessService; import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; @@ -33,7 +33,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; -import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -95,9 +94,10 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { LogRecordContext.putVariable("business", business); return business.getId(); } + /** * @param businessId 商机id - * @param contactId 联系人id + * @param contactId 联系人id * @throws * @description 联系人与商机的关联 * @author lzxhqs @@ -163,6 +163,11 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { LogRecordContext.putVariable("businessName", oldBusiness.getName()); } + @Override + public void updateContactFollowUpBatch(List updateFollowUpReqBOList) { + businessMapper.updateBatch(BeanUtils.toBean(updateFollowUpReqBOList, CrmBusinessDO.class)); + } + @Override @Transactional(rollbackFor = Exception.class) @LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_DELETE_SUB_TYPE, bizNo = "{{#id}}", @@ -191,7 +196,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { */ private void validateContractExists(Long businessId) { CrmContractDO contract = contractMapper.selectByBizId(businessId); - if(contract != null) { + if (contract != null) { throw exception(BUSINESS_CONTRACT_EXISTS); } } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/bo/CrmBusinessUpdateFollowUpReqBO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/bo/CrmBusinessUpdateFollowUpReqBO.java new file mode 100644 index 000000000..edb4eec1a --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/bo/CrmBusinessUpdateFollowUpReqBO.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.crm.service.business.bo; + +import com.mzt.logapi.starter.annotation.DiffLogField; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 商机跟进信息 Update Req BO + * + * @author HUIHUI + */ +@Data +public class CrmBusinessUpdateFollowUpReqBO { + + @Schema(description = "商机编号", example = "3167") + @NotNull(message = "商机编号不能为空") + private Long id; + + @Schema(description = "最后跟进时间") + @DiffLogField(name = "最后跟进时间") + @NotNull(message = "最后跟进时间不能为空") + private LocalDateTime contactLastTime; + + @Schema(description = "下次联系时间") + @DiffLogField(name = "下次联系时间") + @NotNull(message = "下次联系时间不能为空") + private LocalDateTime contactNextTime; + + @Schema(description = "最后更进内容") + @DiffLogField(name = "最后更进内容") + @NotNull(message = "最后更进内容不能为空") + private String contactLastContent; + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueService.java index fcda32ff3..47ece94e2 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueService.java @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueSaveReqVO; import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueTransferReqVO; import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueTransformReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO; +import cn.iocoder.yudao.module.crm.service.clue.bo.CrmClueUpdateFollowUpReqBO; import jakarta.validation.Valid; import java.util.Collection; @@ -33,6 +34,13 @@ public interface CrmClueService { */ void updateClue(@Valid CrmClueSaveReqVO updateReqVO); + /** + * 更新线索相关的跟进信息 + * + * @param clueUpdateFollowUpReqBO 信息 + */ + void updateClueFollowUp(CrmClueUpdateFollowUpReqBO clueUpdateFollowUpReqBO); + /** * 删除线索 * diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java index f096b15f7..649914ed2 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java @@ -16,6 +16,7 @@ import cn.iocoder.yudao.module.crm.dal.mysql.clue.CrmClueMapper; import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; 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.clue.bo.CrmClueUpdateFollowUpReqBO; import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; @@ -82,6 +83,11 @@ public class CrmClueServiceImpl implements CrmClueService { clueMapper.updateById(updateObj); } + @Override + public void updateClueFollowUp(CrmClueUpdateFollowUpReqBO clueUpdateFollowUpReqBO) { + clueMapper.updateById(BeanUtils.toBean(clueUpdateFollowUpReqBO, CrmClueDO.class)); + } + @Override @CrmPermission(bizType = CrmBizTypeEnum.CRM_LEADS, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) public void deleteClue(Long id) { diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/bo/CrmClueUpdateFollowUpReqBO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/bo/CrmClueUpdateFollowUpReqBO.java new file mode 100644 index 000000000..36bc287f9 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/bo/CrmClueUpdateFollowUpReqBO.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.crm.service.clue.bo; + +import com.mzt.logapi.starter.annotation.DiffLogField; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 线索跟进信息 Update Req BO + * + * @author HUIHUI + */ +@Data +public class CrmClueUpdateFollowUpReqBO { + + @Schema(description = "线索编号", example = "3167") + @NotNull(message = "线索编号不能为空") + private Long id; + + @Schema(description = "最后跟进时间") + @DiffLogField(name = "最后跟进时间") + @NotNull(message = "最后跟进时间不能为空") + private LocalDateTime contactLastTime; + + @Schema(description = "下次联系时间") + @DiffLogField(name = "下次联系时间") + @NotNull(message = "下次联系时间不能为空") + private LocalDateTime contactNextTime; + + @Schema(description = "最后更进内容") + @DiffLogField(name = "最后更进内容") + @NotNull(message = "最后更进内容不能为空") + private String contactLastContent; + +} 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 36e0b1898..7cb86bc56 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 @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactSaveReq import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactTransferReqVO; 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.contact.bo.CrmContactUpdateFollowUpReqBO; import jakarta.validation.Valid; import java.util.Collection; @@ -57,6 +58,14 @@ public interface CrmContactService { */ void updateOwnerUserIdByCustomerId(Long customerId, Long ownerUserId); + /** + * 更新联系人相关跟进信息 + * + * @param updateFollowUpReqBOList 跟进信息 + */ + void updateContactFollowUpBatch(List updateFollowUpReqBOList); + + /** * 获得联系人 * @@ -89,6 +98,14 @@ public interface CrmContactService { */ List getContactList(); + /** + * 获取联系人列表(校验权限) + * + * @param userId 用户编号 + * @return 联系人列表 + */ + List getSimpleContactList(Long userId); + /** * 获得联系人分页 * 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 ee9c7f556..7b6f83e04 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 @@ -15,6 +15,7 @@ import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; 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.CrmBusinessService; +import cn.iocoder.yudao.module.crm.service.contact.bo.CrmContactUpdateFollowUpReqBO; 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.permission.CrmPermissionService; @@ -32,6 +33,7 @@ import java.util.Collection; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE; import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS; @@ -192,6 +194,11 @@ public class CrmContactServiceImpl implements CrmContactService { contactMapper.updateOwnerUserIdByCustomerId(customerId, ownerUserId); } + @Override + public void updateContactFollowUpBatch(List updateFollowUpReqBOList) { + contactMapper.updateBatch(BeanUtils.toBean(updateFollowUpReqBOList, CrmContactDO.class)); + } + //======================= 查询相关 ======================= @Override @@ -221,6 +228,13 @@ public class CrmContactServiceImpl implements CrmContactService { return contactMapper.selectList(); } + @Override + public List getSimpleContactList(Long userId) { + CrmContactPageReqVO reqVO = new CrmContactPageReqVO(); + reqVO.setPageSize(PAGE_SIZE_NONE); // 不分页 + return contactMapper.selectPage(reqVO, userId).getList(); + } + @Override public PageResult getContactPage(CrmContactPageReqVO pageReqVO, Long userId) { return contactMapper.selectPage(pageReqVO, userId); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/bo/CrmContactUpdateFollowUpReqBO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/bo/CrmContactUpdateFollowUpReqBO.java new file mode 100644 index 000000000..2b2cd9a1d --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/bo/CrmContactUpdateFollowUpReqBO.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.crm.service.contact.bo; + +import com.mzt.logapi.starter.annotation.DiffLogField; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 联系人跟进信息 Update Req BO + * + * @author HUIHUI + */ +@Data +public class CrmContactUpdateFollowUpReqBO { + + @Schema(description = "联系人编号", example = "3167") + @NotNull(message = "联系人编号不能为空") + private Long id; + + @Schema(description = "最后跟进时间") + @DiffLogField(name = "最后跟进时间") + @NotNull(message = "最后跟进时间不能为空") + private LocalDateTime contactLastTime; + + @Schema(description = "下次联系时间") + @DiffLogField(name = "下次联系时间") + @NotNull(message = "下次联系时间不能为空") + private LocalDateTime contactNextTime; + + @Schema(description = "最后更进内容") + @DiffLogField(name = "最后更进内容") + @NotNull(message = "最后更进内容不能为空") + private String contactLastContent; + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java index d4a1a34ba..26a9256f2 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractSaveR import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; +import cn.iocoder.yudao.module.crm.service.contract.bo.CrmContractUpdateFollowUpReqBO; import jakarta.validation.Valid; import java.util.Collection; @@ -41,6 +42,21 @@ public interface CrmContractService { */ void deleteContract(Long id); + /** + * 合同转移 + * + * @param reqVO 请求 + * @param userId 用户编号 + */ + void transferContract(CrmContractTransferReqVO reqVO, Long userId); + + /** + * 更新合同相关的更进信息 + * + * @param contractUpdateFollowUpReqBO 信息 + */ + void updateContractFollowUp(CrmContractUpdateFollowUpReqBO contractUpdateFollowUpReqBO); + /** * 获得合同 * @@ -78,14 +94,6 @@ public interface CrmContractService { */ PageResult getContractPageByCustomerId(CrmContractPageReqVO pageReqVO); - /** - * 合同转移 - * - * @param reqVO 请求 - * @param userId 用户编号 - */ - void transferContract(CrmContractTransferReqVO reqVO, Long userId); - /** * 查询属于某个联系人的合同数量 * 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 161b105c6..b9142dd35 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 @@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper; import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; 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.contract.bo.CrmContractUpdateFollowUpReqBO; import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO; import com.mzt.logapi.context.LogRecordContext; @@ -135,6 +136,11 @@ public class CrmContractServiceImpl implements CrmContractService { LogRecordContext.putVariable("contract", contract); } + @Override + public void updateContractFollowUp(CrmContractUpdateFollowUpReqBO contractUpdateFollowUpReqBO) { + contractMapper.updateById(BeanUtils.toBean(contractUpdateFollowUpReqBO, CrmContractDO.class)); + } + //======================= 查询相关 ======================= @Override diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/bo/CrmContractUpdateFollowUpReqBO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/bo/CrmContractUpdateFollowUpReqBO.java new file mode 100644 index 000000000..4091a5634 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/bo/CrmContractUpdateFollowUpReqBO.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.crm.service.contract.bo; + +import com.mzt.logapi.starter.annotation.DiffLogField; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 合同跟进信息 Update Req BO + * + * @author HUIHUI + */ +@Data +public class CrmContractUpdateFollowUpReqBO { + + @Schema(description = "合同编号", example = "3167") + @NotNull(message = "合同编号不能为空") + private Long id; + + @Schema(description = "最后跟进时间") + @DiffLogField(name = "最后跟进时间") + @NotNull(message = "最后跟进时间不能为空") + private LocalDateTime contactLastTime; + + @Schema(description = "下次联系时间") + @DiffLogField(name = "下次联系时间") + @NotNull(message = "下次联系时间不能为空") + private LocalDateTime contactNextTime; + + @Schema(description = "最后更进内容") + @DiffLogField(name = "最后更进内容") + @NotNull(message = "最后更进内容不能为空") + private String contactLastContent; + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerService.java index 12df6c8ba..d40b08118 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerService.java @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageR import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerSaveReqVO; import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerTransferReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; +import cn.iocoder.yudao.module.crm.service.customer.bo.CrmCustomerUpdateFollowUpReqBO; import jakarta.validation.Valid; import java.util.Collection; @@ -90,6 +91,13 @@ public interface CrmCustomerService { */ void lockCustomer(@Valid CrmCustomerLockReqVO lockReqVO, Long userId); + /** + * 更新客户相关更进信息 + * + * @param customerUpdateFollowUpReqBO 请求 + */ + void updateCustomerFollowUp(CrmCustomerUpdateFollowUpReqBO customerUpdateFollowUpReqBO); + // ==================== 公海相关操作 ==================== /** diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java index fcb174a83..1a9f39bb5 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java @@ -21,6 +21,7 @@ import cn.iocoder.yudao.module.crm.framework.permission.core.util.CrmPermissionU import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService; 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.bo.CrmCustomerUpdateFollowUpReqBO; 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; @@ -203,6 +204,11 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { LogRecordContext.putVariable("customer", customer); } + @Override + public void updateCustomerFollowUp(CrmCustomerUpdateFollowUpReqBO customerUpdateFollowUpReqBO) { + customerMapper.updateById(BeanUtils.toBean(customerUpdateFollowUpReqBO, CrmCustomerDO.class)); + } + // ==================== 公海相关操作 ==================== @Override diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/bo/CrmCustomerUpdateFollowUpReqBO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/bo/CrmCustomerUpdateFollowUpReqBO.java new file mode 100644 index 000000000..f5e0302e5 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/bo/CrmCustomerUpdateFollowUpReqBO.java @@ -0,0 +1,32 @@ +package cn.iocoder.yudao.module.crm.service.customer.bo; + +import com.mzt.logapi.starter.annotation.DiffLogField; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 跟进信息 Update Req BO + * + * @author HUIHUI + */ +@Data +public class CrmCustomerUpdateFollowUpReqBO { + + @Schema(description = "主键", example = "3167") + private Long id; + + @Schema(description = "最后跟进时间") + @DiffLogField(name = "最后跟进时间") + private LocalDateTime contactLastTime; + + @Schema(description = "下次联系时间") + @DiffLogField(name = "下次联系时间") + private LocalDateTime contactNextTime; + + @Schema(description = "最后更进内容") + @DiffLogField(name = "最后更进内容") + private String contactLastContent; + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordService.java index 35fdf9e52..c0fb69f25 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordService.java @@ -14,7 +14,7 @@ import jakarta.validation.Valid; public interface CrmFollowUpRecordService { /** - * 创建跟进记录 + * 创建跟进记录 (数据权限基于 bizType、 bizId) * * @param createReqVO 创建信息 * @return 编号 @@ -22,18 +22,12 @@ public interface CrmFollowUpRecordService { Long createFollowUpRecord(@Valid CrmFollowUpRecordSaveReqVO createReqVO); /** - * 更新跟进记录 + * 删除跟进记录 (数据权限基于 bizType、 bizId) * - * @param updateReqVO 更新信息 + * @param id 编号 + * @param userId 用户编号 */ - void updateFollowUpRecord(@Valid CrmFollowUpRecordSaveReqVO updateReqVO); - - /** - * 删除跟进记录 - * - * @param id 编号 - */ - void deleteFollowUpRecord(Long id); + void deleteFollowUpRecord(Long id, Long userId); /** * 获得跟进记录 @@ -44,7 +38,7 @@ public interface CrmFollowUpRecordService { CrmFollowUpRecordDO getFollowUpRecord(Long id); /** - * 获得跟进记录分页 + * 获得跟进记录分页 (数据权限基于 bizType、 bizId) * * @param pageReqVO 分页查询 * @return 跟进记录分页 diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java index 213128954..6eae29ddb 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java @@ -1,16 +1,33 @@ package cn.iocoder.yudao.module.crm.service.followup; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjUtil; 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.followup.vo.CrmFollowUpRecordPageReqVO; import cn.iocoder.yudao.module.crm.controller.admin.followup.vo.CrmFollowUpRecordSaveReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.followup.CrmFollowUpRecordDO; +import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO; import cn.iocoder.yudao.module.crm.dal.mysql.followup.CrmFollowUpRecordMapper; +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.CrmBusinessService; +import cn.iocoder.yudao.module.crm.service.business.bo.CrmBusinessUpdateFollowUpReqBO; +import cn.iocoder.yudao.module.crm.service.contact.CrmContactService; +import cn.iocoder.yudao.module.crm.service.contact.bo.CrmContactUpdateFollowUpReqBO; +import cn.iocoder.yudao.module.crm.service.followup.handle.CrmFollowUpHandler; +import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; +import java.time.LocalDateTime; +import java.util.List; + import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.anyMatch; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; +import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.FOLLOW_UP_RECORD_DELETE_DENIED; import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.FOLLOW_UP_RECORD_NOT_EXISTS; /** @@ -25,39 +42,69 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService { @Resource private CrmFollowUpRecordMapper crmFollowUpRecordMapper; - // TODO @puhui999:数据权限 + @Resource + private CrmPermissionService permissionService; + @Resource + private List followUpHandlers; + @Resource + private CrmBusinessService businessService; + @Resource + private CrmContactService contactService; + @Override + @CrmPermission(bizTypeValue = "#createReqVO.bizType", bizId = "#createReqVO.bizId", level = CrmPermissionLevelEnum.WRITE) public Long createFollowUpRecord(CrmFollowUpRecordSaveReqVO createReqVO) { + // 创建更进记录 CrmFollowUpRecordDO followUpRecord = BeanUtils.toBean(createReqVO, CrmFollowUpRecordDO.class); crmFollowUpRecordMapper.insert(followUpRecord); - // TODO @puhui999:需要更新 bizId 对应的记录; - // TODO @puhui999:需要更新 businessIds、contactIds 对应的记录; + + LocalDateTime now = LocalDateTime.now(); + // 更新 bizId 对应的记录; + followUpHandlers.forEach(handler -> handler.execute(followUpRecord, now)); + // 更新 contactIds 对应的记录 + if (CollUtil.isNotEmpty(createReqVO.getContactIds())) { + contactService.updateContactFollowUpBatch(convertList(createReqVO.getContactIds(), contactId -> { + CrmContactUpdateFollowUpReqBO crmContactUpdateFollowUpReqBO = new CrmContactUpdateFollowUpReqBO(); + crmContactUpdateFollowUpReqBO.setId(contactId).setContactNextTime(followUpRecord.getNextTime()) + .setContactLastTime(now).setContactLastContent(followUpRecord.getContent()); + return crmContactUpdateFollowUpReqBO; + })); + } + // 需要更新 businessIds、contactIds 对应的记录 + if (CollUtil.isNotEmpty(createReqVO.getBusinessIds())) { + businessService.updateContactFollowUpBatch(convertList(createReqVO.getBusinessIds(), businessId -> { + CrmBusinessUpdateFollowUpReqBO crmBusinessUpdateFollowUpReqBO = new CrmBusinessUpdateFollowUpReqBO(); + crmBusinessUpdateFollowUpReqBO.setId(businessId).setContactNextTime(followUpRecord.getNextTime()) + .setContactLastTime(now).setContactLastContent(followUpRecord.getContent()); + return crmBusinessUpdateFollowUpReqBO; + })); + } return followUpRecord.getId(); } - // TODO @puhui999:不能编辑~~~ @Override - public void updateFollowUpRecord(CrmFollowUpRecordSaveReqVO updateReqVO) { + public void deleteFollowUpRecord(Long id, Long userId) { // 校验存在 - validateFollowUpRecordExists(updateReqVO.getId()); - // 更新 - CrmFollowUpRecordDO updateObj = BeanUtils.toBean(updateReqVO, CrmFollowUpRecordDO.class); - crmFollowUpRecordMapper.updateById(updateObj); - } + CrmFollowUpRecordDO followUpRecord = validateFollowUpRecordExists(id); + // 校验权限 + List permissionList = permissionService.getPermissionListByBiz( + followUpRecord.getBizType(), followUpRecord.getBizId()); + boolean condition = anyMatch(permissionList, permission -> + ObjUtil.equal(permission.getUserId(), userId) && ObjUtil.equal(permission.getLevel(), CrmPermissionLevelEnum.OWNER.getLevel())); + if (!condition) { + throw exception(FOLLOW_UP_RECORD_DELETE_DENIED); + } - // TODO @puhui999:数据权限 - @Override - public void deleteFollowUpRecord(Long id) { - // 校验存在 - validateFollowUpRecordExists(id); // 删除 crmFollowUpRecordMapper.deleteById(id); } - private void validateFollowUpRecordExists(Long id) { - if (crmFollowUpRecordMapper.selectById(id) == null) { + private CrmFollowUpRecordDO validateFollowUpRecordExists(Long id) { + CrmFollowUpRecordDO followUpRecord = crmFollowUpRecordMapper.selectById(id); + if (followUpRecord == null) { throw exception(FOLLOW_UP_RECORD_NOT_EXISTS); } + return followUpRecord; } @Override @@ -65,8 +112,9 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService { return crmFollowUpRecordMapper.selectById(id); } - // TODO @puhui999:数据权限 + @Override + @CrmPermission(bizTypeValue = "#pageReqVO.bizType", bizId = "#pageReqVO.bizId", level = CrmPermissionLevelEnum.READ) public PageResult getFollowUpRecordPage(CrmFollowUpRecordPageReqVO pageReqVO) { return crmFollowUpRecordMapper.selectPage(pageReqVO); } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmBusinessFollowUpHandler.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmBusinessFollowUpHandler.java new file mode 100644 index 000000000..ffba7fb7e --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmBusinessFollowUpHandler.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.crm.service.followup.handle; + +import cn.hutool.core.util.ObjUtil; +import cn.iocoder.yudao.module.crm.dal.dataobject.followup.CrmFollowUpRecordDO; +import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; +import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService; +import cn.iocoder.yudao.module.crm.service.business.bo.CrmBusinessUpdateFollowUpReqBO; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.Collections; + +/** + * CRM 商机的 {@link CrmFollowUpHandler} 实现类 + * + * @author HUIHUI + */ +@Component +public class CrmBusinessFollowUpHandler implements CrmFollowUpHandler { + + @Resource + private CrmBusinessService businessService; + + @Override + public void execute(CrmFollowUpRecordDO followUpRecord, LocalDateTime now) { + if (ObjUtil.notEqual(CrmBizTypeEnum.CRM_BUSINESS.getType(), followUpRecord.getBizType())) { + return; + } + + // 更新商机跟进信息 + CrmBusinessUpdateFollowUpReqBO businessUpdateFollowUpReqBO = new CrmBusinessUpdateFollowUpReqBO(); + businessUpdateFollowUpReqBO.setId(followUpRecord.getBizId()).setContactNextTime(followUpRecord.getNextTime()) + .setContactLastTime(now).setContactLastContent(followUpRecord.getContent()); + businessService.updateContactFollowUpBatch(Collections.singletonList(businessUpdateFollowUpReqBO)); + } + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmClueFollowUpHandler.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmClueFollowUpHandler.java new file mode 100644 index 000000000..ade2b2aaa --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmClueFollowUpHandler.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.crm.service.followup.handle; + +import cn.hutool.core.util.ObjUtil; +import cn.iocoder.yudao.module.crm.dal.dataobject.followup.CrmFollowUpRecordDO; +import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; +import cn.iocoder.yudao.module.crm.service.clue.CrmClueService; +import cn.iocoder.yudao.module.crm.service.clue.bo.CrmClueUpdateFollowUpReqBO; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; + +/** + * CRM 线索的 {@link CrmFollowUpHandler} 实现类 + * + * @author HUIHUI + */ +@Component +public class CrmClueFollowUpHandler implements CrmFollowUpHandler { + + @Resource + private CrmClueService clueService; + + @Override + public void execute(CrmFollowUpRecordDO followUpRecord, LocalDateTime now) { + if (ObjUtil.notEqual(CrmBizTypeEnum.CRM_LEADS.getType(), followUpRecord.getBizType())) { + return; + } + + // 更新线索跟进信息 + CrmClueUpdateFollowUpReqBO clueUpdateFollowUpReqBO = new CrmClueUpdateFollowUpReqBO(); + clueUpdateFollowUpReqBO.setId(followUpRecord.getBizId()).setContactNextTime(followUpRecord.getNextTime()) + .setContactLastTime(now).setContactLastContent(followUpRecord.getContent()); + clueService.updateClueFollowUp(clueUpdateFollowUpReqBO); + } + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmContactFollowUpHandler.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmContactFollowUpHandler.java new file mode 100644 index 000000000..f38942111 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmContactFollowUpHandler.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.crm.service.followup.handle; + +import cn.hutool.core.util.ObjUtil; +import cn.iocoder.yudao.module.crm.dal.dataobject.followup.CrmFollowUpRecordDO; +import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; +import cn.iocoder.yudao.module.crm.service.contact.CrmContactService; +import cn.iocoder.yudao.module.crm.service.contact.bo.CrmContactUpdateFollowUpReqBO; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.Collections; + +/** + * CRM 联系人的 {@link CrmFollowUpHandler} 实现类 + * + * @author HUIHUI + */ +@Component +public class CrmContactFollowUpHandler implements CrmFollowUpHandler { + + @Resource + private CrmContactService contactService; + + @Override + public void execute(CrmFollowUpRecordDO followUpRecord, LocalDateTime now) { + if (ObjUtil.notEqual(CrmBizTypeEnum.CRM_CONTACT.getType(), followUpRecord.getBizType())) { + return; + } + + // 更新联系人跟进信息 + CrmContactUpdateFollowUpReqBO contactUpdateFollowUpReqBO = new CrmContactUpdateFollowUpReqBO(); + contactUpdateFollowUpReqBO.setId(followUpRecord.getBizId()).setContactNextTime(followUpRecord.getNextTime()) + .setContactLastTime(now).setContactLastContent(followUpRecord.getContent()); + contactService.updateContactFollowUpBatch(Collections.singletonList(contactUpdateFollowUpReqBO)); + } + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmContractFollowUpHandler.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmContractFollowUpHandler.java new file mode 100644 index 000000000..269015fd0 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmContractFollowUpHandler.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.crm.service.followup.handle; + +import cn.hutool.core.util.ObjUtil; +import cn.iocoder.yudao.module.crm.dal.dataobject.followup.CrmFollowUpRecordDO; +import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; +import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; +import cn.iocoder.yudao.module.crm.service.contract.bo.CrmContractUpdateFollowUpReqBO; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; + +/** + * CRM 合同的 {@link CrmFollowUpHandler} 实现类 + * + * @author HUIHUI + */ +@Component +public class CrmContractFollowUpHandler implements CrmFollowUpHandler { + + @Resource + private CrmContractService contractService; + + @Override + public void execute(CrmFollowUpRecordDO followUpRecord, LocalDateTime now) { + if (ObjUtil.notEqual(CrmBizTypeEnum.CRM_CONTRACT.getType(), followUpRecord.getBizType())) { + return; + } + + // 更新合同跟进信息 + CrmContractUpdateFollowUpReqBO contractUpdateFollowUpReqBO = new CrmContractUpdateFollowUpReqBO(); + contractUpdateFollowUpReqBO.setId(followUpRecord.getBizId()).setContactNextTime(followUpRecord.getNextTime()) + .setContactLastTime(now).setContactLastContent(followUpRecord.getContent()); + contractService.updateContractFollowUp(contractUpdateFollowUpReqBO); + } + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmCustomerFollowUpHandler.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmCustomerFollowUpHandler.java new file mode 100644 index 000000000..0e0931555 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmCustomerFollowUpHandler.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.crm.service.followup.handle; + +import cn.hutool.core.util.ObjUtil; +import cn.iocoder.yudao.module.crm.dal.dataobject.followup.CrmFollowUpRecordDO; +import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; +import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; +import cn.iocoder.yudao.module.crm.service.customer.bo.CrmCustomerUpdateFollowUpReqBO; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; + +/** + * CRM 客户的 {@link CrmFollowUpHandler} 实现类 + * + * @author HUIHUI + */ +@Component +public class CrmCustomerFollowUpHandler implements CrmFollowUpHandler { + + @Resource + private CrmCustomerService customerService; + + @Override + public void execute(CrmFollowUpRecordDO followUpRecord, LocalDateTime now) { + if (ObjUtil.notEqual(CrmBizTypeEnum.CRM_CUSTOMER.getType(), followUpRecord.getBizType())) { + return; + } + + // 更新客户跟进信息 + CrmCustomerUpdateFollowUpReqBO customerUpdateFollowUpReqBO = new CrmCustomerUpdateFollowUpReqBO(); + customerUpdateFollowUpReqBO.setId(followUpRecord.getBizId()).setContactNextTime(followUpRecord.getNextTime()) + .setContactLastTime(now).setContactLastContent(followUpRecord.getContent()); + customerService.updateCustomerFollowUp(customerUpdateFollowUpReqBO); + } + +} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmFollowUpHandler.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmFollowUpHandler.java new file mode 100644 index 000000000..7df667727 --- /dev/null +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmFollowUpHandler.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.crm.service.followup.handle; + +import cn.iocoder.yudao.module.crm.dal.dataobject.followup.CrmFollowUpRecordDO; + +import java.time.LocalDateTime; + +/** + * CRM 跟进信息处理器 handler 接口 + * + * @author HUIHUI + */ +public interface CrmFollowUpHandler { + + /** + * 执行更新 + * + * @param followUpRecord 跟进记录 + * @param now 跟进时间 + */ + void execute(CrmFollowUpRecordDO followUpRecord, LocalDateTime now); + +} diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java index 7c674e7d3..64785762e 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/category/ProductCategoryServiceImplTest.java @@ -2,16 +2,15 @@ package cn.iocoder.yudao.module.product.service.category; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryCreateReqVO; import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategoryListReqVO; import cn.iocoder.yudao.module.product.controller.admin.category.vo.ProductCategorySaveReqVO; import cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO; import cn.iocoder.yudao.module.product.dal.mysql.category.ProductCategoryMapper; +import jakarta.annotation.Resource; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.context.annotation.Import; -import jakarta.annotation.Resource; import java.util.List; import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; @@ -21,7 +20,8 @@ import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; import static cn.iocoder.yudao.module.product.dal.dataobject.category.ProductCategoryDO.PARENT_ID_NULL; import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.CATEGORY_NOT_EXISTS; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; /** * {@link ProductCategoryServiceImpl} 的单元测试类 @@ -41,22 +41,22 @@ public class ProductCategoryServiceImplTest extends BaseDbUnitTest { @Test public void testCreateCategory_success() { // 准备参数 - ProductCategoryCreateReqVO reqVO = randomPojo(ProductCategoryCreateReqVO.class); + //ProductCategoryCreateReqVO reqVO = randomPojo(ProductCategoryCreateReqVO.class); // mock 父类 - ProductCategoryDO parentProductCategory = randomPojo(ProductCategoryDO.class, o -> { - reqVO.setParentId(o.getId()); - o.setParentId(PARENT_ID_NULL); - }); - productCategoryMapper.insert(parentProductCategory); - - // 调用 - Long categoryId = productCategoryService.createCategory(reqVO); - // 断言 - assertNotNull(categoryId); - // 校验记录的属性是否正确 - ProductCategoryDO category = productCategoryMapper.selectById(categoryId); - assertPojoEquals(reqVO, category); + //ProductCategoryDO parentProductCategory = randomPojo(ProductCategoryDO.class, o -> { + // reqVO.setParentId(o.getId()); + // o.setParentId(PARENT_ID_NULL); + //}); + //productCategoryMapper.insert(parentProductCategory); + // + //// 调用 + //Long categoryId = productCategoryService.createCategory(reqVO); + //// 断言 + //assertNotNull(categoryId); + //// 校验记录的属性是否正确 + //ProductCategoryDO category = productCategoryMapper.selectById(categoryId); + //assertPojoEquals(reqVO, category); } @Test From 7b36eb888e84465147085b9e93b550ab358f39c9 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Wed, 17 Jan 2024 12:11:39 +0800 Subject: [PATCH 13/27] =?UTF-8?q?CRM-=E5=90=88=E5=90=8C=EF=BC=9ARespVO=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=AF=BC=E5=87=BA=E6=B3=A8=E8=A7=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/contract/vo/CrmContractRespVO.java | 35 ++++++++++++++++++- .../crm/service/clue/CrmClueServiceImpl.java | 2 +- .../customer/CrmCustomerServiceImpl.java | 3 +- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractRespVO.java index 9a1ae58f3..1164f4a0c 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractRespVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/contract/vo/CrmContractRespVO.java @@ -1,83 +1,116 @@ package cn.iocoder.yudao.module.crm.controller.admin.contract.vo; +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDateTime; -// TODO @puhui999:导出注解哈 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + @Schema(description = "管理后台 - CRM 合同 Response VO") @Data +@ExcelIgnoreUnannotated public class CrmContractRespVO { @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") + @ExcelProperty("合同编号") private Long id; @Schema(description = "合同名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五") + @ExcelProperty("合同名称") private String name; @Schema(description = "客户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "18336") + @ExcelProperty("客户编号") private Long customerId; @Schema(description = "商机编号", example = "10864") + @ExcelProperty("商机编号") private Long businessId; @Schema(description = "工作流编号", example = "1043") + @ExcelProperty("工作流编号") private Long processInstanceId; @Schema(description = "下单日期", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("下单日期") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime orderDate; @Schema(description = "负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17144") + @ExcelProperty("负责人的用户编号") private Long ownerUserId; // TODO @芋艿:未来应该支持自动生成; @Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20230101") + @ExcelProperty("合同编号") private String no; @Schema(description = "开始时间") + @ExcelProperty("开始时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime startTime; @Schema(description = "结束时间") + @ExcelProperty("结束时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime endTime; @Schema(description = "合同金额", example = "5617") + @ExcelProperty("合同金额") private Integer price; @Schema(description = "整单折扣") + @ExcelProperty("整单折扣") private Integer discountPercent; @Schema(description = "产品总金额", example = "19510") + @ExcelProperty("产品总金额") private Integer productPrice; @Schema(description = "联系人编号", example = "18546") + @ExcelProperty("联系人编号") private Long contactId; @Schema(description = "公司签约人", example = "14036") + @ExcelProperty("公司签约人") private Long signUserId; @Schema(description = "最后跟进时间") + @ExcelProperty("最后跟进时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime contactLastTime; @Schema(description = "备注", example = "你猜") + @ExcelProperty("备注") private String remark; @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime createTime; @Schema(description = "创建人", example = "25682") + @ExcelProperty("创建人") private String creator; @Schema(description = "创建人名字", example = "test") + @ExcelProperty("创建人名字") private String creatorName; @Schema(description = "客户名字", example = "test") + @ExcelProperty("客户名字") private String customerName; @Schema(description = "负责人", example = "test") + @ExcelProperty("负责人") private String ownerUserName; @Schema(description = "审批状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") + @ExcelProperty("审批状态") private Integer auditStatus; } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java index 649914ed2..4a6ff9575 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java @@ -165,7 +165,7 @@ public class CrmClueServiceImpl implements CrmClueService { // 1. 创建客户 CrmCustomerSaveReqVO customerSaveReqVO = BeanUtils.toBean(clue, CrmCustomerSaveReqVO.class).setId(null); Long customerId = customerService.createCustomer(customerSaveReqVO, userId); - // TODO @puhui999:如果有跟进记录,需要一起转过去; + // TODO @puhui999:如果有跟进记录,需要一起转过去;提问:艿艿这里是复制线索所有的跟进吗?还是直接把线索相关的跟进 bizType、bizId 全改为关联客户? // 2. 更新线索 clueMapper.updateById(new CrmClueDO().setId(clue.getId()) .setTransformStatus(Boolean.TRUE).setCustomerId(customerId)); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java index 1a9f39bb5..a27a43e87 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java @@ -235,8 +235,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { // 3. 删除负责人数据权限 permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), customer.getId(), CrmPermissionLevelEnum.OWNER.getLevel()); - // TODO @puhui999:联系人的负责人,也要设置为 null;这块和领取是对应的;因为领取后,负责人也要关联过来; - // 提问:那是不是可以这样理解客户所有联系人的负责人默认为客户的负责人,然后添加客户团队成员时才存在“同时分配给”的操作? + // 联系人的负责人,也要设置为 null;这块和领取是对应的;因为领取后,负责人也要关联过来; contactService.updateOwnerUserIdByCustomerId(customer.getId(), null); // 记录操作日志上下文 From dd0a2b73e8bced407c0ff829b3cf241ac4b182b0 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 17 Jan 2024 19:45:57 +0800 Subject: [PATCH 14/27] =?UTF-8?q?=E2=9C=A8=20MALL=EF=BC=9A=E6=B8=85?= =?UTF-8?q?=E7=90=86=E5=A4=9A=E4=BD=99=E7=9A=84=20decorate=20=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../enums/decorate/DecorateComponentEnum.java | 61 ------------------- .../DiyPageEnum.java} | 6 +- .../CombinationRecordController.java | 3 +- .../decorate/DecorateComponentController.http | 18 ------ .../decorate/DecorateComponentController.java | 50 --------------- .../decorate/vo/DecorateComponentRespVO.java | 19 ------ .../vo/DecorateComponentSaveReqVO.java | 31 ---------- .../app/decorate/AppDecorateController.java | 43 ------------- .../vo/AppDecorateComponentRespVO.java | 16 ----- .../app/diy/AppDiyTemplateController.java | 8 +-- .../decorate/DecorateComponentConvert.java | 23 ------- .../decorate/DecorateComponentDO.java | 52 ---------------- .../decorate/DecorateComponentMapper.java | 28 --------- .../decorate/DecorateComponentService.java | 31 ---------- .../DecorateComponentServiceImpl.java | 40 ------------ .../DecorateComponentServiceImplTest.java | 36 ----------- 16 files changed, 9 insertions(+), 456 deletions(-) delete mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/decorate/DecorateComponentEnum.java rename yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/{decorate/DecoratePageEnum.java => diy/DiyPageEnum.java} (77%) delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/decorate/DecorateComponentController.http delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/decorate/DecorateComponentController.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/decorate/vo/DecorateComponentRespVO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/decorate/vo/DecorateComponentSaveReqVO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/decorate/AppDecorateController.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/decorate/vo/AppDecorateComponentRespVO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/decorate/DecorateComponentConvert.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/decorate/DecorateComponentDO.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/decorate/DecorateComponentMapper.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/decorate/DecorateComponentService.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/decorate/DecorateComponentServiceImpl.java delete mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/decorate/DecorateComponentServiceImplTest.java diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/decorate/DecorateComponentEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/decorate/DecorateComponentEnum.java deleted file mode 100644 index 45bc1fe4d..000000000 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/decorate/DecorateComponentEnum.java +++ /dev/null @@ -1,61 +0,0 @@ -package cn.iocoder.yudao.module.promotion.enums.decorate; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -/** - * 页面组件枚举 - * - * @author jason - */ -@Getter -@AllArgsConstructor -@SuppressWarnings("JavadocLinkAsPlainText") -public enum DecorateComponentEnum { - - /** - * 格式:[{ - * "name": "标题" - * "picUrl": "https://www.iocoder.cn/xxx.png", - * "url": "/pages/users/index" - * }] - * - * 最多 10 个 - */ - MENU("menu", "菜单"), - /** - * 格式:[{ - * "name": "标题" - * "url": "/pages/users/index" - * }] - */ - ROLLING_NEWS("scrolling-news", "滚动新闻"), - /** - * 格式:[{ - * "picUrl": "https://www.iocoder.cn/xxx.png", - * "url": "/pages/users/index" - * }] - */ - SLIDE_SHOW("slide-show", "轮播图"), - /** - * 格式:[{ - * "name": "标题" - * "type": "类型", // best、hot、new、benefit、good - * "tag": "标签" // 例如说:多买多省 - * }] - * - * 最多 4 个 - */ - PRODUCT_RECOMMEND("product-recommend", "商品推荐"); - - /** - * 页面组件代码 - */ - private final String code; - - /** - * 页面组件说明 - */ - private final String desc; - -} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/decorate/DecoratePageEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/diy/DiyPageEnum.java similarity index 77% rename from yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/decorate/DecoratePageEnum.java rename to yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/diy/DiyPageEnum.java index d773c2040..fa00adaad 100644 --- a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/decorate/DecoratePageEnum.java +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/diy/DiyPageEnum.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.promotion.enums.decorate; +package cn.iocoder.yudao.module.promotion.enums.diy; import cn.iocoder.yudao.framework.common.core.IntArrayValuable; import lombok.AllArgsConstructor; @@ -13,13 +13,13 @@ import java.util.Arrays; */ @AllArgsConstructor @Getter -public enum DecoratePageEnum implements IntArrayValuable { +public enum DiyPageEnum implements IntArrayValuable { INDEX(1, "首页"), MY(2, "我的"), ; - private static final int[] ARRAYS = Arrays.stream(values()).mapToInt(DecoratePageEnum::getPage).toArray(); + private static final int[] ARRAYS = Arrays.stream(values()).mapToInt(DiyPageEnum::getPage).toArray(); /** * 页面编号 diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/CombinationRecordController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/CombinationRecordController.java index b72215572..ed93f2fb8 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/CombinationRecordController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/combination/CombinationRecordController.java @@ -43,7 +43,8 @@ public class CombinationRecordController { @GetMapping("/page") @Operation(summary = "获得拼团记录分页") @PreAuthorize("@ss.hasPermission('promotion:combination-record:query')") - public CommonResult> getBargainRecordPage(@Valid CombinationRecordReqPageVO pageVO) { + public CommonResult> getCombinationRecordPage( + @Valid CombinationRecordReqPageVO pageVO) { PageResult recordPage = combinationRecordService.getCombinationRecordPage(pageVO); // 拼接数据 List activities = combinationActivityService.getCombinationActivityListByIds( diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/decorate/DecorateComponentController.http b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/decorate/DecorateComponentController.http deleted file mode 100644 index 79975c590..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/decorate/DecorateComponentController.http +++ /dev/null @@ -1,18 +0,0 @@ -### /promotion/decorate/save 保存页面装修组件 -POST {{baseUrl}}/promotion/decorate/save -Content-Type: application/json -Authorization: Bearer {{token}} -tenant-id: {{adminTenentId}} - -{ - "page": 1, - "code": "slide-show", - "status": 0, - "value": "null" -} - -### /promotion/decorate/list 获取指定页面的组件列表 -GET {{baseUrl}}/promotion/decorate/list?page=1 -Content-Type: application/json -Authorization: Bearer {{token}} -tenant-id: {{adminTenentId}} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/decorate/DecorateComponentController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/decorate/DecorateComponentController.java deleted file mode 100644 index 1a6ee6475..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/decorate/DecorateComponentController.java +++ /dev/null @@ -1,50 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.decorate; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.promotion.controller.admin.decorate.vo.DecorateComponentRespVO; -import cn.iocoder.yudao.module.promotion.controller.admin.decorate.vo.DecorateComponentSaveReqVO; -import cn.iocoder.yudao.module.promotion.convert.decorate.DecorateComponentConvert; -import cn.iocoder.yudao.module.promotion.enums.decorate.DecoratePageEnum; -import cn.iocoder.yudao.module.promotion.service.decorate.DecorateComponentService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import jakarta.annotation.Resource; -import jakarta.validation.Valid; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -@Tag(name = "管理后台 - 店铺页面装修") -@RestController -@RequestMapping("/promotion/decorate") -@Validated -public class DecorateComponentController { - - @Resource - private DecorateComponentService decorateComponentService; - - @PostMapping("/save") - @Operation(summary = "保存页面装修组件") - @PreAuthorize("@ss.hasPermission('promotion:decorate:save')") - public CommonResult saveDecorateComponent(@Valid @RequestBody DecorateComponentSaveReqVO reqVO) { - decorateComponentService.saveDecorateComponent(reqVO); - return success(true); - } - - @GetMapping("/list") - @Operation(summary = "获取指定页面的组件列表") - @Parameter(name = "page", description = "页面 id", required = true) - @PreAuthorize("@ss.hasPermission('promotion:decorate:query')") - public CommonResult> getDecorateComponentListByPage( - @RequestParam("page") @InEnum(DecoratePageEnum.class) Integer page) { - return success(DecorateComponentConvert.INSTANCE.convertList02( - decorateComponentService.getDecorateComponentListByPage(page, null))); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/decorate/vo/DecorateComponentRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/decorate/vo/DecorateComponentRespVO.java deleted file mode 100644 index 6996d58e8..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/decorate/vo/DecorateComponentRespVO.java +++ /dev/null @@ -1,19 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.decorate.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -@Schema(description = "管理后台 - 页面装修 Resp VO") -@Data -public class DecorateComponentRespVO { - - @Schema(description = "组件编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "nav-menu") - private String code; - - @Schema(description = "组件的内容配置项", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "TODO") - private String value; - - @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer status; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/decorate/vo/DecorateComponentSaveReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/decorate/vo/DecorateComponentSaveReqVO.java deleted file mode 100644 index c081ac80c..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/decorate/vo/DecorateComponentSaveReqVO.java +++ /dev/null @@ -1,31 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.admin.decorate.vo; - -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.promotion.enums.decorate.DecoratePageEnum; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import jakarta.validation.constraints.NotEmpty; -import jakarta.validation.constraints.NotNull; - -@Schema(description = "管理后台 - 页面装修的保存 Request VO ") -@Data -public class DecorateComponentSaveReqVO { - - @Schema(description = "页面 id ", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - @NotNull(message = "页面 id 不能为空") - @InEnum(DecoratePageEnum.class) - private Integer page; - - @Schema(description = "组件编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "nav-menu") - @NotEmpty(message = "组件编码不能为空") - private String code; - - @Schema(description = "组件对应值, json 字符串, 含内容配置,具体数据", requiredMode = Schema.RequiredMode.REQUIRED) - @NotEmpty(message = "组件值为空") - private String value; - - @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") - private Integer status; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/decorate/AppDecorateController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/decorate/AppDecorateController.java deleted file mode 100644 index 6f5b1ec68..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/decorate/AppDecorateController.java +++ /dev/null @@ -1,43 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.app.decorate; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import cn.iocoder.yudao.module.promotion.controller.app.decorate.vo.AppDecorateComponentRespVO; -import cn.iocoder.yudao.module.promotion.convert.decorate.DecorateComponentConvert; -import cn.iocoder.yudao.module.promotion.enums.decorate.DecoratePageEnum; -import cn.iocoder.yudao.module.promotion.service.decorate.DecorateComponentService; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import jakarta.annotation.Resource; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -@Tag(name = "用户 APP - 店铺装修") -@RestController -@RequestMapping("/promotion/decorate") -@Validated -@Deprecated // 废弃 -public class AppDecorateController { - - @Resource - private DecorateComponentService decorateComponentService; - - @GetMapping("/list") - @Operation(summary = "获取指定页面的组件列表") - @Parameter(name = "page", description = "页面编号", required = true) - public CommonResult> getDecorateComponentListByPage( - @RequestParam("page") @InEnum(DecoratePageEnum.class) Integer page) { - return success(DecorateComponentConvert.INSTANCE.convertList( - decorateComponentService.getDecorateComponentListByPage(page, CommonStatusEnum.ENABLE.getStatus()))); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/decorate/vo/AppDecorateComponentRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/decorate/vo/AppDecorateComponentRespVO.java deleted file mode 100644 index 8926db26e..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/decorate/vo/AppDecorateComponentRespVO.java +++ /dev/null @@ -1,16 +0,0 @@ -package cn.iocoder.yudao.module.promotion.controller.app.decorate.vo; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -@Schema(description = "用户 App - 页面组件 Resp VO") -@Data -public class AppDecorateComponentRespVO { - - @Schema(description = "组件编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "nav-menu") - private String code; - - @Schema(description = "组件的内容配置项", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "TODO") - private String value; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/diy/AppDiyTemplateController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/diy/AppDiyTemplateController.java index 6e4ee2501..e8babd15d 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/diy/AppDiyTemplateController.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/diy/AppDiyTemplateController.java @@ -5,19 +5,19 @@ import cn.iocoder.yudao.module.promotion.controller.app.diy.vo.AppDiyTemplatePro import cn.iocoder.yudao.module.promotion.convert.diy.DiyTemplateConvert; import cn.iocoder.yudao.module.promotion.dal.dataobject.diy.DiyPageDO; import cn.iocoder.yudao.module.promotion.dal.dataobject.diy.DiyTemplateDO; -import cn.iocoder.yudao.module.promotion.enums.decorate.DecoratePageEnum; +import cn.iocoder.yudao.module.promotion.enums.diy.DiyPageEnum; import cn.iocoder.yudao.module.promotion.service.diy.DiyPageService; import cn.iocoder.yudao.module.promotion.service.diy.DiyTemplateService; 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 org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import jakarta.annotation.Resource; import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -56,8 +56,8 @@ public class AppDiyTemplateController { } // 查询模板下的页面 List pages = diyPageService.getDiyPageByTemplateId(diyTemplate.getId()); - String home = findFirst(pages, page -> DecoratePageEnum.INDEX.getName().equals(page.getName()), DiyPageDO::getProperty); - String user = findFirst(pages, page -> DecoratePageEnum.MY.getName().equals(page.getName()), DiyPageDO::getProperty); + String home = findFirst(pages, page -> DiyPageEnum.INDEX.getName().equals(page.getName()), DiyPageDO::getProperty); + String user = findFirst(pages, page -> DiyPageEnum.MY.getName().equals(page.getName()), DiyPageDO::getProperty); // 拼接返回 return DiyTemplateConvert.INSTANCE.convertPropertyVo2(diyTemplate, home, user); } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/decorate/DecorateComponentConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/decorate/DecorateComponentConvert.java deleted file mode 100644 index df6613b97..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/decorate/DecorateComponentConvert.java +++ /dev/null @@ -1,23 +0,0 @@ -package cn.iocoder.yudao.module.promotion.convert.decorate; - -import cn.iocoder.yudao.module.promotion.controller.admin.decorate.vo.DecorateComponentRespVO; -import cn.iocoder.yudao.module.promotion.controller.admin.decorate.vo.DecorateComponentSaveReqVO; -import cn.iocoder.yudao.module.promotion.controller.app.decorate.vo.AppDecorateComponentRespVO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.decorate.DecorateComponentDO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -import java.util.List; - -@Mapper -public interface DecorateComponentConvert { - - DecorateComponentConvert INSTANCE = Mappers.getMapper(DecorateComponentConvert.class); - - List convertList02(List list); - - DecorateComponentDO convert(DecorateComponentSaveReqVO bean); - - List convertList(List list); - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/decorate/DecorateComponentDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/decorate/DecorateComponentDO.java deleted file mode 100644 index 876431772..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/decorate/DecorateComponentDO.java +++ /dev/null @@ -1,52 +0,0 @@ -package cn.iocoder.yudao.module.promotion.dal.dataobject.decorate; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.promotion.enums.decorate.DecoratePageEnum; -import cn.iocoder.yudao.module.promotion.enums.decorate.DecorateComponentEnum; -import com.baomidou.mybatisplus.annotation.*; - -import lombok.Data; - -/** - * 页面装修组件 DO, 一个页面由多个组件构成 - * - * @author jason - */ -@TableName(value ="promotion_decorate_component") -@KeySequence("promotion_decorate_component_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -public class DecorateComponentDO extends BaseDO { - - /** - * 编号 - */ - @TableId - private Long id; - - /** - * 所属页面 id - * - * 枚举 {@link DecoratePageEnum#getPage()} - */ - private Integer page; - - /** - * 组件编码 - * 枚举 {@link DecorateComponentEnum#getCode()} - */ - private String code; - - /** - * 组件值:json 格式。包含配置和数据 - */ - private String value; - - /** - * 状态 - * - * 枚举 {@link CommonStatusEnum} - */ - private Integer status; - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/decorate/DecorateComponentMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/decorate/DecorateComponentMapper.java deleted file mode 100644 index 38b448e8a..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/decorate/DecorateComponentMapper.java +++ /dev/null @@ -1,28 +0,0 @@ -package cn.iocoder.yudao.module.promotion.dal.mysql.decorate; - -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.promotion.dal.dataobject.decorate.DecorateComponentDO; -import org.apache.ibatis.annotations.Mapper; - -import java.util.List; - -@Mapper -public interface DecorateComponentMapper extends BaseMapperX { - - default List selectListByPageAndStatus(Integer page, Integer status) { - return selectList(new LambdaQueryWrapperX() - .eq(DecorateComponentDO::getPage, page) - .eqIfPresent(DecorateComponentDO::getStatus, status)); - } - - default DecorateComponentDO selectByPageAndCode(Integer page, String code) { - return selectOne(DecorateComponentDO::getPage, page, - DecorateComponentDO::getCode, code); - } - -} - - - - diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/decorate/DecorateComponentService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/decorate/DecorateComponentService.java deleted file mode 100644 index 82f0b0f5b..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/decorate/DecorateComponentService.java +++ /dev/null @@ -1,31 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.decorate; - -import cn.iocoder.yudao.module.promotion.controller.admin.decorate.vo.DecorateComponentSaveReqVO; -import cn.iocoder.yudao.module.promotion.dal.dataobject.decorate.DecorateComponentDO; -import cn.iocoder.yudao.module.promotion.enums.decorate.DecoratePageEnum; - -import java.util.List; - -/** - * 装修组件 Service 接口 - * - * @author jason - */ -public interface DecorateComponentService { - - /** - * 保存页面的组件信息 - * - * @param reqVO 请求 VO - */ - void saveDecorateComponent(DecorateComponentSaveReqVO reqVO); - - /** - * 根据页面 id,获取页面的组件信息 - * - * @param page 页面编号 {@link DecoratePageEnum#getPage()} - * @param status 状态 - */ - List getDecorateComponentListByPage(Integer page, Integer status); - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/decorate/DecorateComponentServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/decorate/DecorateComponentServiceImpl.java deleted file mode 100644 index 46353a1ee..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/decorate/DecorateComponentServiceImpl.java +++ /dev/null @@ -1,40 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.decorate; - -import cn.iocoder.yudao.module.promotion.controller.admin.decorate.vo.DecorateComponentSaveReqVO; -import cn.iocoder.yudao.module.promotion.convert.decorate.DecorateComponentConvert; -import cn.iocoder.yudao.module.promotion.dal.dataobject.decorate.DecorateComponentDO; -import cn.iocoder.yudao.module.promotion.dal.mysql.decorate.DecorateComponentMapper; -import org.springframework.stereotype.Service; - -import jakarta.annotation.Resource; -import java.util.List; - -/** - * 装修组件 Service 实现 - * - * @author jason - */ -@Service -public class DecorateComponentServiceImpl implements DecorateComponentService { - - @Resource - private DecorateComponentMapper decorateComponentMapper; - - @Override - public void saveDecorateComponent(DecorateComponentSaveReqVO reqVO) { - // 1. 如果存在,则进行更新 - DecorateComponentDO dbComponent = decorateComponentMapper.selectByPageAndCode(reqVO.getPage(), reqVO.getCode()); - if (dbComponent != null) { - decorateComponentMapper.updateById(DecorateComponentConvert.INSTANCE.convert(reqVO).setId(dbComponent.getId())); - return; - } - // 2. 不存在,则进行新增 - decorateComponentMapper.insert(DecorateComponentConvert.INSTANCE.convert(reqVO)); - } - - @Override - public List getDecorateComponentListByPage(Integer page, Integer status) { - return decorateComponentMapper.selectListByPageAndStatus(page, status); - } - -} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/decorate/DecorateComponentServiceImplTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/decorate/DecorateComponentServiceImplTest.java deleted file mode 100644 index 95c542b67..000000000 --- a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/decorate/DecorateComponentServiceImplTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package cn.iocoder.yudao.module.promotion.service.decorate; - -import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; -import cn.iocoder.yudao.module.promotion.dal.mysql.decorate.DecorateComponentMapper; -import org.junit.jupiter.api.BeforeEach; -import org.mockito.InjectMocks; -import org.mockito.Mock; - -// TODO @芋艿:后续 review 下 -/** - * @author jason - */ -public class DecorateComponentServiceImplTest extends BaseMockitoUnitTest { - - @InjectMocks - private DecorateComponentServiceImpl decoratePageService; - - @Mock - private DecorateComponentMapper decorateComponentMapper; - - @BeforeEach - public void init(){ - - } - -// @Test -// void testResp(){ -// List list = new ArrayList<>(1); -// DecorateComponentDO decorateDO = new DecorateComponentDO() -// .setPage(INDEX.getPage()).setValue("") -// .setCode(ROLLING_NEWS.getCode()).setId(1L); -// list.add(decorateDO); -// //mock 方法 -// Mockito.when(decorateComponentMapper.selectListByPageAndStatus(eq(1))).thenReturn(list); -// } -} From 4c200eda921c33c1653107a81142ecf603627ef7 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 18 Jan 2024 00:00:42 +0800 Subject: [PATCH 15/27] =?UTF-8?q?=E2=9C=A8=20MALL=EF=BC=9A=E6=B8=85?= =?UTF-8?q?=E7=90=86=E5=A4=9A=E4=BD=99=E7=9A=84=20MemberStatisticsDO=20?= =?UTF-8?q?=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dataobject/bargain/BargainRecordDO.java | 2 +- .../dataobject/member/MemberStatisticsDO.java | 70 ------------------- 2 files changed, 1 insertion(+), 71 deletions(-) delete mode 100644 yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/dal/dataobject/member/MemberStatisticsDO.java diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/bargain/BargainRecordDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/bargain/BargainRecordDO.java index ff46cb665..e5f574dd6 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/bargain/BargainRecordDO.java +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/bargain/BargainRecordDO.java @@ -63,7 +63,7 @@ public class BargainRecordDO extends BaseDO { * * 砍价成功的条件是:(2 选 1) * 1. 砍价到 {@link BargainActivityDO#getBargainMinPrice()} 底价 - * 2. 助力人数到达 {@link BargainActivityDO#getUserSize()} 人 + * 2. 助力人数到达 {@link BargainActivityDO#getHelpMaxCount()} 人 * * 枚举 {@link BargainRecordStatusEnum} */ diff --git a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/dal/dataobject/member/MemberStatisticsDO.java b/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/dal/dataobject/member/MemberStatisticsDO.java deleted file mode 100644 index af980b5c1..000000000 --- a/yudao-module-mall/yudao-module-statistics-biz/src/main/java/cn/iocoder/yudao/module/statistics/dal/dataobject/member/MemberStatisticsDO.java +++ /dev/null @@ -1,70 +0,0 @@ -package cn.iocoder.yudao.module.statistics.dal.dataobject.member; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -import java.time.LocalDateTime; - -/** - * 会员统计 DO - *

- * 以天为维度,统计全部的数据 - * - * @author 芋道源码 - */ -@TableName("member_statistics") -@KeySequence("member_statistics_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class MemberStatisticsDO extends BaseDO { - - /** - * 编号,主键自增 - */ - @TableId - private Long id; - - /** - * 统计日期 - */ - private LocalDateTime time; - - /** - * 注册用户数量 - */ - private Integer userRegisterCount; - /** - * 访问用户数量(UV) - */ - private Integer userVisitCount; - /** - * 访问页面数量(PV) - */ - private Integer pageVisitCount; - - /** - * 充值用户数量 - */ - private Integer rechargeUserCount; - - /** - * 创建订单用户数 - */ - private Integer orderCreateUserCount; - /** - * 支付订单用户数 - */ - private Integer orderPayUserCount; - /** - * 总支付金额,单位:分 - */ - private Integer orderPayPrice; - -} From 867d8bc3cd390312bd7f2abbc44eb8f7312de20f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?jay=E6=B5=85=E8=93=9D?= <565215951@qq.com> Date: Thu, 18 Jan 2024 03:43:47 +0000 Subject: [PATCH 16/27] =?UTF-8?q?update=20sql/mysql/ruoyi-vue-pro.sql.=20?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93=E7=BC=BA=E5=B0=91trade:order:query?= =?UTF-8?q?=20=E5=92=8C=20trade:order:update=E6=9D=83=E9=99=90=EF=BC=8C?= =?UTF-8?q?=E4=BC=9A=E5=AF=BC=E8=87=B4=E8=AE=A2=E5=8D=95=E7=9A=84=E5=8F=91?= =?UTF-8?q?=E8=B4=A7=E5=92=8C=E6=9B=B4=E5=A4=9A=E6=8C=89=E9=92=AE=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E6=98=BE=E7=A4=BA=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: jay浅蓝 <565215951@qq.com> --- sql/mysql/ruoyi-vue-pro.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/sql/mysql/ruoyi-vue-pro.sql b/sql/mysql/ruoyi-vue-pro.sql index 98acf8be3..3a0a91228 100644 --- a/sql/mysql/ruoyi-vue-pro.sql +++ b/sql/mysql/ruoyi-vue-pro.sql @@ -2370,6 +2370,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2369, '拼团记录', 'promotion:combination-record:query', 2, 2, 2303, 'record', 'ep:avatar', 'mall/promotion/combination/record/index.vue', 'PromotionCombinationRecord', 0, b'1', b'1', b'1', '1', '2023-10-08 07:10:22', '1', '2023-10-08 07:34:11', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2374, '会员统计', '', 2, 2, 2358, 'member', 'ep:avatar', 'statistics/member/index', 'MemberStatistics', 0, b'1', b'1', b'1', '', '2023-10-11 04:39:24', '1', '2023-10-11 12:50:22', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2375, '会员统计查询', 'statistics:member:query', 3, 1, 2374, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-11 04:39:24', '', '2023-10-11 04:39:24', b'0'); +--此处缺少trade:order:query 和 trade:order:update权限,会导致订单的发货和更多按钮无法显示。 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2376, '订单核销', 'trade:order:pick-up', 3, 10, 2076, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-10-14 17:11:58', '1', '2023-10-14 17:11:58', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2377, '文章分类', '', 2, 0, 2387, 'article/category', 'fa:certificate', 'mall/promotion/article/category/index', 'ArticleCategory', 0, b'1', b'1', b'1', '', '2023-10-16 01:26:18', '1', '2023-10-16 09:38:26', b'0'); INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2378, '分类查询', 'promotion:article-category:query', 3, 1, 2377, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-16 01:26:18', '', '2023-10-16 01:26:18', b'0'); From ca552825168c74734088ed4694faff6d347f9d4b Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 18 Jan 2024 12:06:14 +0800 Subject: [PATCH 17/27] =?UTF-8?q?=20CRM=EF=BC=9A=E5=95=86=E6=9C=BA=20code?= =?UTF-8?q?=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/optinal/crm_20240114.sql | 34 +------------------ .../crm/enums/business/CrmBizEndStatus.java | 5 ++- yudao-module-crm/yudao-module-crm-biz/pom.xml | 5 --- .../CrmBusinessStatusTypeController.java | 20 ++++------- .../vo/business/CrmBusinessSaveReqVO.java | 14 ++++---- .../product/CrmBusinessProductPageReqVO.java | 5 +-- .../vo/product/CrmBusinessProductRespVO.java | 3 -- .../product/CrmBusinessProductSaveReqVO.java | 15 ++++---- .../vo/status/CrmBusinessStatusSaveReqVO.java | 4 +-- .../type/CrmBusinessStatusTypeSaveReqVO.java | 2 +- .../CrmBusinessProductConvert.java | 1 + .../CrmBusinessStatusTypeConvert.java | 5 +-- .../dataobject/business/CrmBusinessDO.java | 9 +++-- .../business/CrmBusinessProductDO.java | 12 +++++-- .../business/CrmBusinessStatusDO.java | 4 +-- .../business/CrmBusinessStatusTypeDO.java | 2 +- .../business/CrmBusinessProductMapper.java | 6 ++-- .../business/CrmBusinessStatusTypeMapper.java | 2 ++ .../dal/mysql/contract/CrmContractMapper.java | 2 +- .../business/CrmBusinessServiceImpl.java | 8 +++++ 20 files changed, 60 insertions(+), 98 deletions(-) diff --git a/sql/mysql/optinal/crm_20240114.sql b/sql/mysql/optinal/crm_20240114.sql index 24f25d4ef..50e462c81 100644 --- a/sql/mysql/optinal/crm_20240114.sql +++ b/sql/mysql/optinal/crm_20240114.sql @@ -20,36 +20,4 @@ CREATE TABLE `crm_business_product` ( `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint(0) NOT NULL DEFAULT 1 COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 29 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '商机产品关联表' ROW_FORMAT = Dynamic; - --- ---------------------------- --- Table structure for crm_business_status --- ---------------------------- -DROP TABLE IF EXISTS `crm_business_status`; -CREATE TABLE `crm_business_status` ( - `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键ID', - `type_id` bigint(0) NOT NULL COMMENT '状态类型编号', - `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '状态名', - `percent` bigint(0) NULL DEFAULT NULL COMMENT '赢单率', - `sort` int(0) NULL DEFAULT NULL COMMENT '排序', - `tenant_id` bigint(0) NOT NULL DEFAULT 0 COMMENT '租户编号', - PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '商机状态' ROW_FORMAT = Dynamic; - --- ---------------------------- --- Table structure for crm_business_status_type --- ---------------------------- -DROP TABLE IF EXISTS `crm_business_status_type`; -CREATE TABLE `crm_business_status_type` ( - `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键ID', - `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '状态类型名', - `dept_ids` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '使用的部门编号', - `status` int(0) NOT NULL DEFAULT 1 COMMENT '开启状态', - `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', - `create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', - `update_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - `tenant_id` bigint(0) NOT NULL DEFAULT 0 COMMENT '租户编号', - PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '商机状态类型' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 29 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '商机产品关联表' ROW_FORMAT = Dynamic; \ No newline at end of file diff --git a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/business/CrmBizEndStatus.java b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/business/CrmBizEndStatus.java index f84610e8d..55548dbff 100644 --- a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/business/CrmBizEndStatus.java +++ b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/business/CrmBizEndStatus.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.crm.enums.business; -import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.core.IntArrayValuable; import lombok.Getter; @@ -8,6 +7,7 @@ import lombok.RequiredArgsConstructor; import java.util.Arrays; +// TODO @lzxhqs:1)title、description、create 可以删除,非标准的 javadoc 注释哈,然后可以在类上加下这个类的注释;2)CrmBizEndStatus 改成 CrmBusinessEndStatus,非必要不缩写哈,可阅读比较重要 /** * @author lzxhqs * @version 1.0 @@ -18,12 +18,14 @@ import java.util.Arrays; @RequiredArgsConstructor @Getter public enum CrmBizEndStatus implements IntArrayValuable { + WIN(1, "赢单"), LOSE(2, "输单"), INVALID(3, "无效"); public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmBizEndStatus::getStatus).toArray(); + // TODO @lzxhqs:这里的方法,建议放到 49 行之后;一般类里是,静态变量,普通变量;静态方法;普通方法 public static boolean isWin(Integer status) { return ObjectUtil.equal(WIN.getStatus(), status); } @@ -49,4 +51,5 @@ public enum CrmBizEndStatus implements IntArrayValuable { public int[] array() { return ARRAYS; } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/pom.xml b/yudao-module-crm/yudao-module-crm-biz/pom.xml index 1d74efbef..9e1a9e152 100644 --- a/yudao-module-crm/yudao-module-crm-biz/pom.xml +++ b/yudao-module-crm/yudao-module-crm-biz/pom.xml @@ -22,11 +22,6 @@ yudao-module-system-api ${revision} - - cn.iocoder.boot - yudao-module-system-biz - ${revision} - cn.iocoder.boot yudao-module-crm-api 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 index 9f2e3fbf1..231f66683 100644 --- 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 @@ -25,19 +25,17 @@ 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 jakarta.annotation.Resource; -import jakarta.servlet.http.HttpServletResponse; -import jakarta.validation.Valid; import java.io.IOException; import java.util.Collection; import java.util.List; -import java.util.Objects; import java.util.Set; -import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; @@ -86,13 +84,13 @@ public class CrmBusinessStatusTypeController { @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('crm:business-status-type:query')") public CommonResult getBusinessStatusType(@RequestParam("id") Long id) { - CrmBusinessStatusTypeDO businessStatusType = businessStatusTypeService.getBusinessStatusType(id); + CrmBusinessStatusTypeDO statusType = businessStatusTypeService.getBusinessStatusType(id); // 处理状态回显 - // TODO @ljlleo:可以使用 CollectionUtils.convertSet 替代常用的 stream 操作,更简洁一点;下面几个也是哈; + // TODO @lzxhqs:可以在 businessStatusService 加个 getBusinessStatusListByTypeId 方法,直接返回 List 哈,常用的,尽量封装个简单易懂的方法,不用追求绝对通用哈; CrmBusinessStatusQueryVO queryVO = new CrmBusinessStatusQueryVO(); queryVO.setTypeId(id); List statusList = businessStatusService.selectList(queryVO); - return success(CrmBusinessStatusTypeConvert.INSTANCE.convert(businessStatusType, statusList)); + return success(CrmBusinessStatusTypeConvert.INSTANCE.convert(statusType, statusList)); } @GetMapping("/page") @@ -101,12 +99,6 @@ public class CrmBusinessStatusTypeController { public CommonResult> getBusinessStatusTypePage(@Valid CrmBusinessStatusTypePageReqVO pageReqVO) { PageResult pageResult = businessStatusTypeService.getBusinessStatusTypePage(pageReqVO); // 处理部门回显 - // TODO @ljlleo:可以使用 CollectionUtils.convertSet 替代常用的 stream 操作,更简洁一点;下面几个也是哈; -// Set deptIds = pageResult.getList().stream() -// .map(CrmBusinessStatusTypeDO::getDeptIds) -// .filter(Objects::nonNull) -// .flatMap(Collection::stream) -// .collect(Collectors.toSet()); Set deptIds = CollectionUtils.convertSetByFlatMap(pageResult.getList(), CrmBusinessStatusTypeDO::getDeptIds,Collection::stream); List deptList = deptApi.getDeptList(deptIds); return success(CrmBusinessStatusTypeConvert.INSTANCE.convertPage(pageResult, deptList)); 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 b615211a2..672450c4a 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 @@ -17,7 +17,6 @@ import java.util.List; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -// TODO @ljileo:DiffLogField function 完善一下 @Schema(description = "管理后台 - CRM 商机创建/更新 Request VO") @Data public class CrmBusinessSaveReqVO { @@ -59,7 +58,7 @@ public class CrmBusinessSaveReqVO { @DiffLogField(name = "商机金额") private Integer price; - // TODO @ljileo:折扣使用 Integer 类型,存储时,默认 * 100;展示的时候,前端需要 / 100;避免精度丢失问题 + // TODO @lzxhqs:折扣使用 Integer 类型,存储时,默认 * 100;展示的时候,前端需要 / 100;避免精度丢失问题 @Schema(description = "整单折扣") @DiffLogField(name = "整单折扣") private Integer discountPercent; @@ -71,17 +70,16 @@ public class CrmBusinessSaveReqVO { @Schema(description = "备注", example = "随便") @DiffLogField(name = "备注") private String remark; - // TODO @ljileo:修改的时候,应该可以传递添加的产品; - @Schema(description = "联系人编号", example = "110") - @NotNull(message = "联系人编号不能为空") - private Long contactId; - @Schema(description = "1赢单2输单3无效", example = "1") + @Schema(description = "结束状态", example = "1") @InEnum(CrmBizEndStatus.class) private Integer endStatus; - @Schema(description = "商机产品列表", example = "") + // TODO @lzxhqs:不设置默认 new ArrayList<>();一般 pojo 不设置默认值哈 + @Schema(description = "商机产品列表") private List products = new ArrayList<>(); + @Schema(description = "联系人编号", example = "110") + private Long contactId; // 使用场景,在【联系人详情】添加商机时,如果需要关联两者,需要传递 contactId 字段 } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductPageReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductPageReqVO.java index fcf406b5d..4804768a5 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductPageReqVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductPageReqVO.java @@ -6,10 +6,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; - -/** - * @author lzxhqs - */ +// TODO @lzxhqs:这个类,如果没用到,可以考虑删除哈 @Schema(description = "管理后台 - 商机产品分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductRespVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductRespVO.java index 4d24bd3c5..d4996816f 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductRespVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductRespVO.java @@ -4,9 +4,6 @@ import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -/** - * @author lzxhqs - */ @Schema(description = "管理后台 - 商机产品关联 Response VO") @Data @ExcelIgnoreUnannotated diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductSaveReqVO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductSaveReqVO.java index ddcc603c9..286f1a256 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductSaveReqVO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductSaveReqVO.java @@ -6,9 +6,6 @@ import lombok.Data; import java.math.BigDecimal; -/** - * @author lzxhqs - */ @Schema(description = "管理后台 - CRM 商机产品关联表 创建/更新 Request VO") @Data public class CrmBusinessProductSaveReqVO { @@ -16,12 +13,14 @@ public class CrmBusinessProductSaveReqVO { @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "32129") private Long id; - @Schema(description = "商机ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") - @NotNull(message = "商机ID不能为空") + // TODO @lzxhqs:这个字段,应该是 Long 类型 + @Schema(description = "商机编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") + @NotNull(message = "商机编号不能为空") private Integer businessId; - @Schema(description = "产品ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") - @NotNull(message = "产品ID不能为空") + // TODO @lzxhqs:这个字段,应该是 Long 类型 + @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") + @NotNull(message = "产品编号不能为空") private Integer productId; @Schema(description = "产品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") @@ -44,7 +43,9 @@ public class CrmBusinessProductSaveReqVO { @NotNull(message = "小计(折扣后价格)不能为空") private BigDecimal subtotal; + // TODO @lzxhqs:字符串,用 @NotEmpty,因为要考虑 "" 前端搞了这个玩意 @Schema(description = "单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320") @NotNull(message = "单位不能为空") private String unit; + } 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 c5ecf52d6..3327b09f7 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 @@ -21,11 +21,11 @@ public class CrmBusinessStatusSaveReqVO { @NotEmpty(message = "状态名不能为空") private String name; - // TODO @lilleo:percent 应该是 Integer; + // TODO @lzxhqs::percent 应该是 Integer; @Schema(description = "赢单率") private String percent; - // TODO @lilleo:这个是不是不用前端新增和修改的时候传递,交给顺序计算出来,存储起来就好了; + // TODO @lzxhqs:这个是不是不用前端新增和修改的时候传递,交给顺序计算出来,存储起来就好了; @Schema(description = "排序") 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/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 index 3d61bed1d..23dc7742d 100644 --- 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 @@ -19,10 +19,10 @@ public class CrmBusinessStatusTypeSaveReqVO { @NotEmpty(message = "状态类型名不能为空") private String name; + // TODO @lzxhqs: VO 里面,我们不使用默认值哈。这里 Lists.newArrayList() 看看怎么去掉。上面 deptIds 也是类似噢 @Schema(description = "使用的部门编号", requiredMode = Schema.RequiredMode.REQUIRED) private List deptIds = Lists.newArrayList(); - // TODO @ljlleo VO 里面,我们不使用默认值哈。这里 Lists.newArrayList() 看看怎么去掉。上面 deptIds 也是类似噢 @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/businessproduct/CrmBusinessProductConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessproduct/CrmBusinessProductConvert.java index c3b84d31f..2fcd54d84 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessproduct/CrmBusinessProductConvert.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessproduct/CrmBusinessProductConvert.java @@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; +// TODO @lzxhqs:看看是不是用 BeanUtils 替代了 /** * @author lzxhqs * @version 1.0 diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessstatustype/CrmBusinessStatusTypeConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessstatustype/CrmBusinessStatusTypeConvert.java index 301feb0d7..be203b580 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessstatustype/CrmBusinessStatusTypeConvert.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/businessstatustype/CrmBusinessStatusTypeConvert.java @@ -14,6 +14,7 @@ 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 * @@ -24,7 +25,6 @@ public interface CrmBusinessStatusTypeConvert { CrmBusinessStatusTypeConvert INSTANCE = Mappers.getMapper(CrmBusinessStatusTypeConvert.class); - CrmBusinessStatusTypeRespVO convert(CrmBusinessStatusTypeDO bean); PageResult convertPage(PageResult page); @@ -38,9 +38,6 @@ public interface CrmBusinessStatusTypeConvert { } default CrmBusinessStatusTypeRespVO convert(CrmBusinessStatusTypeDO bean, List statusList) { - // TODO @ljlleo 可以链式赋值,简化成一行; -// CrmBusinessStatusTypeRespVO result = convert(bean); -// result.setStatusList(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 68b5f087b..e11ec5935 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 @@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.crm.dal.dataobject.business; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; -import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; +import cn.iocoder.yudao.module.crm.enums.business.CrmBizEndStatus; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -80,9 +80,9 @@ public class CrmBusinessDO extends BaseDO { */ private String remark; /** - * 1赢单2输单3无效 + * 结束状态 * - * TODO @lijie:搞个枚举; + * 枚举 {@link CrmBizEndStatus} */ private Integer endStatus; /** @@ -96,7 +96,7 @@ public class CrmBusinessDO extends BaseDO { /** * 跟进状态 * - * TODO @lijie:目前就是 Boolean;是否跟进 + * TODO @lzxhqs:目前就是 Boolean;是否跟进 */ private Integer followUpStatus; @@ -104,7 +104,6 @@ public class CrmBusinessDO extends BaseDO { * 负责人的用户编号 * * 关联 AdminUserDO 的 id 字段 - * {@link AdminUserDO#getId()} */ private Long ownerUserId; 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 3f146c3b3..4558684e9 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 @@ -31,17 +31,20 @@ public class CrmBusinessProductDO extends BaseDO { private Long id; /** - * 商机ID + * 商机编号 + * * 关联 {@link CrmBusinessDO#getId()} */ private Long businessId; /** - * 产品ID - * 关联{@link CrmProductDO#getId()} + * 产品编号 + * + * 关联 {@link CrmProductDO#getId()} */ private Long productId; + // TODO @lzxhqs:改成 Integer,单位:分。目前整体倾向放大 100 倍哈 /** * 产品单价 */ @@ -52,16 +55,19 @@ public class CrmBusinessProductDO extends BaseDO { */ private BigDecimal salesPrice; + // TODO @lzxhqs:改成 count /** * 数量 */ private BigDecimal num; + // TODO @lzxhqs:改成 discountPercent /** * 折扣 */ private BigDecimal discount; + // TODO @lzxhqs:改成 totalPrice;总计价格,和现有项目风格一致; /** * 小计(折扣后价格) */ diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessStatusDO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessStatusDO.java index 40c99936b..17ce4f88c 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessStatusDO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessStatusDO.java @@ -35,9 +35,7 @@ public class CrmBusinessStatusDO { */ private String name; /** - * 赢单率 - * - * TODO 这里是不是改成 Integer 存储,百分比 * 100 ; + * 赢单率,百分比 */ private Integer percent; /** 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 75f0094a1..aa9f86251 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 @@ -44,7 +44,7 @@ public class CrmBusinessStatusTypeDO extends BaseDO { * 开启状态 * * TODO 改成 Integer,关联 CommonStatus - * {@link CommonStatusEnum} + * 枚举 {@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/CrmBusinessProductMapper.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessProductMapper.java index 37a193f1f..5750491d8 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessProductMapper.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessProductMapper.java @@ -6,16 +6,16 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO; import org.apache.ibatis.annotations.Mapper; /** - * 商机产品 Mapper + * 商机产品 Mapper // TODO @lzxhqs:类注释,和作者之间要有一个空行 * @author lzxhqs */ @Mapper public interface CrmBusinessProductMapper extends BaseMapperX { - default void deleteByBusinessId(Long id) { + default void deleteByBusinessId(Long id) { // TODO @lzxhqs:第一个方法,和类之间最好空一行; delete(CrmBusinessProductDO::getBusinessId, id); } - default CrmBusinessProductDO selectByBusinessId(Long id) { + default CrmBusinessProductDO selectByBusinessId(Long id) { // TODO @lzxhqs:id 最好改成 businessId,上面也是;这样一看更容易懂 return selectOne(CrmBusinessProductDO::getBusinessId, id); } } 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 9b90549a1..410ebf050 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 @@ -29,6 +29,7 @@ public interface CrmBusinessStatusTypeMapper extends BaseMapperX { default Long selectCountByContactId(Long contactId) { return selectCount(CrmContractDO::getContactId, contactId); } - default CrmContractDO selectByBizId(Long businessId) { + default CrmContractDO selectByBizId(Long businessId) { // TODO @lzxhqs:1)方法和方法之间要有空行;2)selectCountByBusinessId,一个是应该求数量,一个是不要缩写 BizId 可读性; return selectOne(CrmContractDO::getBusinessId, 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 2feee4d69..a4d08f315 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 @@ -57,9 +57,11 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { @Resource private CrmBusinessProductMapper businessProductMapper; + // TODO @lzxhqs:不直接调用这个 mapper,要调用对方的 service;每个业务独立收敛 @Resource private CrmContractMapper contractMapper; + // TODO @lzxhqs:不直接调用这个 mapper,要调用对方的 service;每个业务独立收敛 @Resource private CrmContactBusinessMapper contactBusinessMapper; @Resource @@ -78,7 +80,9 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { .setOwnerUserId(userId); businessMapper.insert(business); // TODO 商机待定:插入商机与产品的关联表;校验商品存在 + // TODO lzxhqs:新增时,是不是不用调用这个方法哈; verifyCrmBusinessProduct(business.getId()); + // TODO @lzxhqs:用 CollUtils.isNotEmpty; if (!createReqVO.getProducts().isEmpty()) { createBusinessProducts(createReqVO.getProducts(), business.getId()); } @@ -95,6 +99,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { return business.getId(); } + // TODO @lzxhqs:CrmContactBusinessService 调用这个;这样逻辑才能收敛哈; /** * @param businessId 商机id * @param contactId 联系人id @@ -110,12 +115,14 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { } + // TODO @lzxhqs:这个方法注释格式不对;删除@description,然后把 插入商机产品关联表 作为方法注释; /** * @param products 产品集合 * @description 插入商机产品关联表 * @author lzxhqs */ private void createBusinessProducts(List products, Long businessId) { + // TODO @lzxhqs:可以用 CollectionUtils.convertList; List list = new ArrayList<>(); for (CrmBusinessProductSaveReqVO product : products) { CrmBusinessProductDO businessProductDO = CrmBusinessProductConvert.INSTANCE.convert(product); @@ -152,6 +159,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { CrmBusinessDO updateObj = BeanUtils.toBean(updateReqVO, CrmBusinessDO.class); businessMapper.updateById(updateObj); // TODO 商机待定:插入商机与产品的关联表;校验商品存在 + // TODO @lzxhqs:更新时,可以调用 CollectionUtils 的 diffList,尽量避免这种先删除再插入;而是新增的插入、变更的更新,没的删除;不然这个表每次更新,会多好多数据; verifyCrmBusinessProduct(updateReqVO.getId()); if (!updateReqVO.getProducts().isEmpty()) { createBusinessProducts(updateReqVO.getProducts(), updateReqVO.getId()); From 6624a93a84f9b90ebdfc5e2d13f16cdff7e5d6aa Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 18 Jan 2024 12:17:12 +0800 Subject: [PATCH 18/27] =?UTF-8?q?=20CRM=EF=BC=9A=E8=B7=9F=E8=BF=9B?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=20code=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/followup/CrmFollowUpRecordController.java | 10 +++++----- .../business/bo/CrmBusinessUpdateFollowUpReqBO.java | 1 + .../service/clue/bo/CrmClueUpdateFollowUpReqBO.java | 1 + .../module/crm/service/contact/CrmContactService.java | 1 - .../contact/bo/CrmContactUpdateFollowUpReqBO.java | 1 + .../contract/bo/CrmContractUpdateFollowUpReqBO.java | 1 + .../crm/service/customer/CrmCustomerServiceImpl.java | 7 ++++--- .../customer/bo/CrmCustomerUpdateFollowUpReqBO.java | 1 + .../service/followup/CrmFollowUpRecordServiceImpl.java | 7 ++++--- .../service/followup/handle/CrmFollowUpHandler.java | 1 + 10 files changed, 19 insertions(+), 12 deletions(-) diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/CrmFollowUpRecordController.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/CrmFollowUpRecordController.java index 399696bf4..735f2e887 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/CrmFollowUpRecordController.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/followup/CrmFollowUpRecordController.java @@ -38,7 +38,7 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti public class CrmFollowUpRecordController { @Resource - private CrmFollowUpRecordService crmFollowUpRecordService; + private CrmFollowUpRecordService followUpRecordService; @Resource private CrmContactService contactService; @Resource @@ -48,7 +48,7 @@ public class CrmFollowUpRecordController { @Operation(summary = "创建跟进记录") @PreAuthorize("@ss.hasPermission('crm:follow-up-record:create')") public CommonResult createFollowUpRecord(@Valid @RequestBody CrmFollowUpRecordSaveReqVO createReqVO) { - return success(crmFollowUpRecordService.createFollowUpRecord(createReqVO)); + return success(followUpRecordService.createFollowUpRecord(createReqVO)); } @DeleteMapping("/delete") @@ -56,7 +56,7 @@ public class CrmFollowUpRecordController { @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('crm:follow-up-record:delete')") public CommonResult deleteFollowUpRecord(@RequestParam("id") Long id) { - crmFollowUpRecordService.deleteFollowUpRecord(id, getLoginUserId()); + followUpRecordService.deleteFollowUpRecord(id, getLoginUserId()); return success(true); } @@ -65,7 +65,7 @@ public class CrmFollowUpRecordController { @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('crm:follow-up-record:query')") public CommonResult getFollowUpRecord(@RequestParam("id") Long id) { - CrmFollowUpRecordDO followUpRecord = crmFollowUpRecordService.getFollowUpRecord(id); + CrmFollowUpRecordDO followUpRecord = followUpRecordService.getFollowUpRecord(id); return success(BeanUtils.toBean(followUpRecord, CrmFollowUpRecordRespVO.class)); } @@ -73,7 +73,7 @@ public class CrmFollowUpRecordController { @Operation(summary = "获得跟进记录分页") @PreAuthorize("@ss.hasPermission('crm:follow-up-record:query')") public CommonResult> getFollowUpRecordPage(@Valid CrmFollowUpRecordPageReqVO pageReqVO) { - PageResult pageResult = crmFollowUpRecordService.getFollowUpRecordPage(pageReqVO); + PageResult pageResult = followUpRecordService.getFollowUpRecordPage(pageReqVO); /// 拼接数据 Map contactMap = convertMap(contactService.getContactList( convertSetByFlatMap(pageResult.getList(), item -> item.getContactIds().stream())), CrmContactDO::getId); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/bo/CrmBusinessUpdateFollowUpReqBO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/bo/CrmBusinessUpdateFollowUpReqBO.java index edb4eec1a..ccf8d0a0a 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/bo/CrmBusinessUpdateFollowUpReqBO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/bo/CrmBusinessUpdateFollowUpReqBO.java @@ -7,6 +7,7 @@ import lombok.Data; import java.time.LocalDateTime; +// TODO @puhui999:是不是搞个通用的 ReqBO 就好了 /** * 商机跟进信息 Update Req BO * diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/bo/CrmClueUpdateFollowUpReqBO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/bo/CrmClueUpdateFollowUpReqBO.java index 36bc287f9..d4697acc2 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/bo/CrmClueUpdateFollowUpReqBO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/bo/CrmClueUpdateFollowUpReqBO.java @@ -7,6 +7,7 @@ import lombok.Data; import java.time.LocalDateTime; +// TODO @puhui999:是不是搞个通用的 ReqBO 就好了 /** * 线索跟进信息 Update Req BO * 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 7cb86bc56..5962db9a8 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 @@ -65,7 +65,6 @@ public interface CrmContactService { */ void updateContactFollowUpBatch(List updateFollowUpReqBOList); - /** * 获得联系人 * diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/bo/CrmContactUpdateFollowUpReqBO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/bo/CrmContactUpdateFollowUpReqBO.java index 2b2cd9a1d..40604353e 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/bo/CrmContactUpdateFollowUpReqBO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/bo/CrmContactUpdateFollowUpReqBO.java @@ -7,6 +7,7 @@ import lombok.Data; import java.time.LocalDateTime; +// TODO @puhui999:是不是搞个通用的 ReqBO 就好了 /** * 联系人跟进信息 Update Req BO * diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/bo/CrmContractUpdateFollowUpReqBO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/bo/CrmContractUpdateFollowUpReqBO.java index 4091a5634..57c1f5f50 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/bo/CrmContractUpdateFollowUpReqBO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/bo/CrmContractUpdateFollowUpReqBO.java @@ -7,6 +7,7 @@ import lombok.Data; import java.time.LocalDateTime; +// TODO @puhui999:是不是搞个通用的 ReqBO 就好了 /** * 合同跟进信息 Update Req BO * diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java index a27a43e87..a88b230e3 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java @@ -227,15 +227,16 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { // 1.3. 校验客户是否锁定 validateCustomerIsLocked(customer, true); - // 2. 设置负责人为 NULL + // 2.1 设置负责人为 NULL int updateOwnerUserIncr = customerMapper.updateOwnerUserIdById(customer.getId(), null); if (updateOwnerUserIncr == 0) { throw exception(CUSTOMER_UPDATE_OWNER_USER_FAIL); } - // 3. 删除负责人数据权限 + // 2.2 删除负责人数据权限 permissionService.deletePermission(CrmBizTypeEnum.CRM_CUSTOMER.getType(), customer.getId(), CrmPermissionLevelEnum.OWNER.getLevel()); - // 联系人的负责人,也要设置为 null;这块和领取是对应的;因为领取后,负责人也要关联过来; + + // 3. 联系人的负责人,也要设置为 null。因为:因为领取后,负责人也要关联过来,这块和 receiveCustomer 是对应的 contactService.updateOwnerUserIdByCustomerId(customer.getId(), null); // 记录操作日志上下文 diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/bo/CrmCustomerUpdateFollowUpReqBO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/bo/CrmCustomerUpdateFollowUpReqBO.java index f5e0302e5..2ba7fbb05 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/bo/CrmCustomerUpdateFollowUpReqBO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/bo/CrmCustomerUpdateFollowUpReqBO.java @@ -6,6 +6,7 @@ import lombok.Data; import java.time.LocalDateTime; +// TODO @puhui999:是不是搞个通用的 ReqBO 就好了 /** * 跟进信息 Update Req BO * diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java index 6eae29ddb..f1c98e7d7 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java @@ -59,10 +59,11 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService { crmFollowUpRecordMapper.insert(followUpRecord); LocalDateTime now = LocalDateTime.now(); - // 更新 bizId 对应的记录; + // 2. 更新 bizId 对应的记录; followUpHandlers.forEach(handler -> handler.execute(followUpRecord, now)); - // 更新 contactIds 对应的记录 + // 3.1 更新 contactIds 对应的记录 if (CollUtil.isNotEmpty(createReqVO.getContactIds())) { + // TODO @puhui999:可以用链式设置哈 contactService.updateContactFollowUpBatch(convertList(createReqVO.getContactIds(), contactId -> { CrmContactUpdateFollowUpReqBO crmContactUpdateFollowUpReqBO = new CrmContactUpdateFollowUpReqBO(); crmContactUpdateFollowUpReqBO.setId(contactId).setContactNextTime(followUpRecord.getNextTime()) @@ -70,7 +71,7 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService { return crmContactUpdateFollowUpReqBO; })); } - // 需要更新 businessIds、contactIds 对应的记录 + // 3.2 需要更新 businessIds、contactIds 对应的记录 if (CollUtil.isNotEmpty(createReqVO.getBusinessIds())) { businessService.updateContactFollowUpBatch(convertList(createReqVO.getBusinessIds(), businessId -> { CrmBusinessUpdateFollowUpReqBO crmBusinessUpdateFollowUpReqBO = new CrmBusinessUpdateFollowUpReqBO(); diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmFollowUpHandler.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmFollowUpHandler.java index 7df667727..82bcec835 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmFollowUpHandler.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmFollowUpHandler.java @@ -11,6 +11,7 @@ import java.time.LocalDateTime; */ public interface CrmFollowUpHandler { + // TODO @puhui999:需要考虑,下次联系时间为空; /** * 执行更新 * From ee1870802f84f4d9d94f0238ed0a87580d94c5f8 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 18 Jan 2024 19:07:01 +0800 Subject: [PATCH 19/27] =?UTF-8?q?=20BPM=EF=BC=9A=E6=8A=84=E9=80=81?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E7=9A=84=20code=20review?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../task/BpmProcessInstanceController.java | 18 +++++----- .../BpmProcessInstanceCCMyPageReqVO.java | 3 +- .../BpmProcessInstanceCCPageItemRespVO.java | 2 ++ .../instance/BpmProcessInstanceCCReqVO.java | 9 +++-- .../cc/BpmProcessInstanceCopyConvert.java | 14 ++++++-- .../cc/BpmProcessInstanceCopyDO.java | 14 +++++--- .../cc/BpmProcessInstanceCopyMapper.java | 2 +- .../BpmCandidateProcessorConfiguration.java | 3 +- .../cc/BpmProcessInstanceCopyService.java | 15 ++++++--- .../cc/BpmProcessInstanceCopyServiceImpl.java | 33 ++++++++++++++----- .../service/cc/BpmProcessInstanceCopyVO.java | 4 +-- .../yudao/module/bpm/util/FlowableUtils.java | 2 ++ .../controller/admin/ip/AreaController.java | 4 +-- .../socail/vo/user/SocialUserBindReqVO.java | 3 -- .../controller/app/ip/AppAreaController.java | 4 +-- .../module/system/convert/ip/AreaConvert.java | 28 ---------------- 16 files changed, 84 insertions(+), 74 deletions(-) delete mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/ip/AreaConvert.java diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java index aab10348b..0cba2b35f 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java @@ -2,20 +2,18 @@ package cn.iocoder.yudao.module.bpm.controller.admin.task; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*; import cn.iocoder.yudao.module.bpm.service.cc.BpmProcessInstanceCopyService; import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Parameter; 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 jakarta.annotation.Resource; -import jakarta.validation.Valid; - import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @@ -62,19 +60,21 @@ public class BpmProcessInstanceController { return success(true); } + // TODO @kyle:抄送要不单独 controller? @PostMapping("/cc/create") @Operation(summary = "抄送流程") @PreAuthorize("@ss.hasPermission('bpm:process-instance-cc:create')") public CommonResult createProcessInstanceCC(@Valid @RequestBody BpmProcessInstanceCCReqVO createReqVO) { - return success(processInstanceCopyService.ccProcessInstance(SecurityFrameworkUtils.getLoginUserId(), createReqVO)); + return success(processInstanceCopyService.ccProcessInstance(getLoginUserId(), createReqVO)); } @GetMapping("/cc/my-page") @Operation(summary = "获得抄送流程分页列表") @PreAuthorize("@ss.hasPermission('bpm:process-instance-cc:query')") - public CommonResult> getProcessInstanceCCPage(@Valid BpmProcessInstanceCCMyPageReqVO pageReqVO) { - return success(processInstanceCopyService.getMyProcessInstanceCCPage(SecurityFrameworkUtils.getLoginUserId(), pageReqVO)); + public CommonResult> getProcessInstanceCCPage( + @Valid BpmProcessInstanceCCMyPageReqVO pageReqVO) { + return success(processInstanceCopyService.getMyProcessInstanceCCPage(getLoginUserId(), pageReqVO)); } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCMyPageReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCMyPageReqVO.java index 44de17d38..928ea8d97 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCMyPageReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCMyPageReqVO.java @@ -11,7 +11,8 @@ import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(description = "管理后台 - 流程实例抄送的分页 Item Response VO") +// TODO @kyle:建议改成 BpmProcessInstanceCopyMyPageReqVO;cc 缩写不容易理解,所以改成 copy,虽然会长一点,但是可读性更重要; +@Schema(description = "管理后台 - 流程实例抄送的分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCPageItemRespVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCPageItemRespVO.java index 2315730ff..176350c24 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCPageItemRespVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCPageItemRespVO.java @@ -9,6 +9,7 @@ import java.time.LocalDateTime; @Data public class BpmProcessInstanceCCPageItemRespVO { + // TODO @kyle:如果已经写了 swagger 注解,可以不用写 java 注释哈; /** * 编号 */ @@ -52,4 +53,5 @@ public class BpmProcessInstanceCCPageItemRespVO { @Schema(description = "抄送时间") private LocalDateTime createTime; + } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCReqVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCReqVO.java index c1a73fb24..a07fd1514 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCReqVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessInstanceCCReqVO.java @@ -9,8 +9,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; -import java.util.Set; - +// TODO @kyle:这个 VO 可以改成 BpmProcessInstanceCopyCreateReqVO @Schema(description = "管理后台 - 流程实例的抄送 Request VO") @Data @EqualsAndHashCode(callSuper = true) @@ -33,7 +32,6 @@ public class BpmProcessInstanceCCReqVO extends BpmTaskCandidateRuleVO { @NotNull(message = "发起流程的用户的编号不能为空") private Long startUserId; - @Schema(description = "任务实例名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") @NotEmpty(message = "任务实例名称不能为空") private String processInstanceName; @@ -41,4 +39,9 @@ public class BpmProcessInstanceCCReqVO extends BpmTaskCandidateRuleVO { @Schema(description = "抄送原因", requiredMode = Schema.RequiredMode.REQUIRED, example = "请帮忙审查下!") @NotBlank(message = "抄送原因不能为空") private String reason; + + // TODO @kyle:看了下字段有点多,尽量不传递可推导的字段; + // 需要传递:taskId(任务编号)、reason、userIds(被抄送的人) + // 不需要传递:taskKey、taskName、processInstanceKey、startUserId、processInstanceName 因为这些可以后端查询到 + } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/cc/BpmProcessInstanceCopyConvert.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/cc/BpmProcessInstanceCopyConvert.java index 49327a134..3be0c131f 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/cc/BpmProcessInstanceCopyConvert.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/cc/BpmProcessInstanceCopyConvert.java @@ -11,6 +11,7 @@ import org.mapstruct.factory.Mappers; import java.util.List; import java.util.Map; +// TODO kyle:类注释不太对 /** * 动态表单 Convert * @@ -21,14 +22,14 @@ public interface BpmProcessInstanceCopyConvert { BpmProcessInstanceCopyConvert INSTANCE = Mappers.getMapper(BpmProcessInstanceCopyConvert.class); + // TODO @kyle:可以使用 BeanUtils copy 替代这些简单的哈; BpmProcessInstanceCopyDO copy(BpmProcessInstanceCopyDO bean); BpmProcessInstanceCopyVO convert(BpmProcessInstanceCopyDO bean); - List convertList2(List list); - List convertList(List list); + // TODO @kyle:/* taskId */ 这种注释一般不用写,可以一眼看明白的;避免变量看着略微不清晰哈 default PageResult convertPage(PageResult page , Map taskMap , Map processInstaneMap @@ -45,6 +46,15 @@ public interface BpmProcessInstanceCopyConvert { MapUtils.findAndThen(processInstaneMap, vo.getProcessInstanceId(), vo::setProcessInstanceName); } + // TODO @kyle:可以精简成下面的哈; +// List list2 = BeanUtils.toBean(page.getList(), +// BpmProcessInstanceCCPageItemRespVO.class, +// copy -> { +// MapUtils.findAndThen(userMap, Long.valueOf(copy.getCreator()), copy::setCreatorNickname); +// MapUtils.findAndThen(userMap, copy.getStartUserId(), copy::setStartUserNickname); +// MapUtils.findAndThen(taskMap, copy.getTaskId(), copy::setTaskName); +// MapUtils.findAndThen(processInstaneMap, copy.getProcessInstanceId(), copy::setProcessInstanceName); +// }); return new PageResult<>(list, page.getTotal()); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/cc/BpmProcessInstanceCopyDO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/cc/BpmProcessInstanceCopyDO.java index 1735f021e..3bd287409 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/cc/BpmProcessInstanceCopyDO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/cc/BpmProcessInstanceCopyDO.java @@ -6,10 +6,10 @@ import com.baomidou.mybatisplus.annotation.TableName; import lombok.*; /** - * 流程抄送对象 + * 流程抄送 DO * * @author kyle - * @date 2022-05-19 + * @date 2022-05-19 TODO @kyle:@date 不是标准 java doc,可以使用 @since 替代,然后日期是不是不对 */ @TableName(value = "bpm_process_instance_copy", autoResultMap = true) @Data @@ -26,8 +26,9 @@ public class BpmProcessInstanceCopyDO extends BaseDO { @TableId private Long id; + // TODO @kyle:字段如果是关联或者冗余,要写下注释。以 processInstanceId 举例子。 /** - * 发起人Id + * 发起人 Id */ private Long startUserId; /** @@ -35,7 +36,9 @@ public class BpmProcessInstanceCopyDO extends BaseDO { */ private String processInstanceName; /** - * 流程主键 + * 流程实例的编号 + * + * 关联 ProcessInstance 的 id 属性 */ private String processInstanceId; @@ -50,7 +53,7 @@ public class BpmProcessInstanceCopyDO extends BaseDO { private String taskName; /** - * 用户主键 + * 用户编号 */ private Long userId; @@ -59,6 +62,7 @@ public class BpmProcessInstanceCopyDO extends BaseDO { */ private String reason; + // TODO @kyle:这个字段,可以用 category 简化点 /** * 流程分类 */ diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/cc/BpmProcessInstanceCopyMapper.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/cc/BpmProcessInstanceCopyMapper.java index af697f4e7..3b8848428 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/cc/BpmProcessInstanceCopyMapper.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/cc/BpmProcessInstanceCopyMapper.java @@ -8,7 +8,7 @@ import cn.iocoder.yudao.module.bpm.dal.dataobject.cc.BpmProcessInstanceCopyDO; import org.apache.ibatis.annotations.Mapper; @Mapper -public interface BpmProcessInstanceCopyMapper extends BaseMapperX { +public interface BpmProcessInstanceCopyMapper extends BaseMapperX { // TODO @kyle:方法和类之间要空行下; default PageResult selectPage(Long loginUserId, BpmProcessInstanceCCMyPageReqVO reqVO){ return selectPage(reqVO, new LambdaQueryWrapperX() .eqIfPresent(BpmProcessInstanceCopyDO::getUserId, loginUserId) diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmCandidateProcessorConfiguration.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmCandidateProcessorConfiguration.java index 293a935d6..cff03488b 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmCandidateProcessorConfiguration.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmCandidateProcessorConfiguration.java @@ -6,8 +6,7 @@ import org.springframework.beans.factory.ObjectProvider; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import java.util.List; - +// TODO @芋艿:Candidate 相关还在完善中,用户可以暂时忽略,仅 yudao 开发的同学需要关注~计划是把 Candidate 和 Assign 融合成一套 /** * BPM 通用的 Configuration 配置类,提供给 Activiti 和 Flowable * @author kyle diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyService.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyService.java index 20285639d..799656fde 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyService.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyService.java @@ -6,6 +6,8 @@ import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessI import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceCCReqVO; import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; +// TODO @kyle:这个 Service 要不挪到 task 包下;保持统一,task 下有流程、任务、抄送等; +// TODO @kyle:中文和英文之间,有个空格,会更清晰点;例如说;流程抄送 Service 接口;中文写作习惯~ /** * 流程抄送Service接口 * @@ -13,6 +15,7 @@ import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; */ public interface BpmProcessInstanceCopyService { + // TODO @kyle:无用的方法,可以去掉哈;另外,考虑到避免过多的 VO,这里就可以返回 BpmProcessInstanceCopyDO /** * 查询流程抄送 * @@ -21,6 +24,7 @@ public interface BpmProcessInstanceCopyService { */ BpmProcessInstanceCopyVO queryById(Long copyId); + // TODO 芋艿:这块要 review 下;思考下~~ /** * 抄送 * @param sourceInfo 抄送源信息,方便抄送处理 @@ -28,13 +32,15 @@ public interface BpmProcessInstanceCopyService { */ boolean makeCopy(BpmCandidateSourceInfo sourceInfo); + // TODO @kyle:可以方法名改成 createProcessInstanceCopy;现在项目一般新增都用 create 为主; /** * 流程实例的抄送 - * @param loginUserId 当前登录用户 + * + * @param userId 当前登录用户 * @param createReqVO 创建的抄送请求 - * @return 是否抄送成功,抄送成功则返回true + * @return 是否抄送成功,抄送成功则返回true TODO @kyle:这里可以不用返回哈;目前一般是失败,就抛出业务异常; */ - boolean ccProcessInstance(Long loginUserId, BpmProcessInstanceCCReqVO createReqVO); + boolean ccProcessInstance(Long userId, BpmProcessInstanceCCReqVO createReqVO); /** * 抄送的流程 @@ -42,5 +48,6 @@ public interface BpmProcessInstanceCopyService { * @param pageReqVO 分页请求 * @return 抄送的分页结果 */ - PageResult getMyProcessInstanceCCPage(Long loginUserId, BpmProcessInstanceCCMyPageReqVO pageReqVO); + PageResult getMyProcessInstanceCCPage(Long loginUserId, + BpmProcessInstanceCCMyPageReqVO pageReqVO); } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java index 865a6f699..edc5f7f0a 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyServiceImpl.java @@ -11,10 +11,12 @@ import cn.iocoder.yudao.module.bpm.dal.mysql.cc.BpmProcessInstanceCopyMapper; import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessorChain; import cn.iocoder.yudao.module.bpm.service.cc.dto.BpmDelegateExecutionDTO; +import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService; import cn.iocoder.yudao.module.bpm.util.FlowableUtils; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; +import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.flowable.engine.RuntimeService; import org.flowable.engine.delegate.DelegateExecution; @@ -24,33 +26,37 @@ import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; -import jakarta.annotation.Resource; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; -@Slf4j +// TODO @kyle:类注释要写下 +@Slf4j // TODO @kyle:按照 @Service、@Validated、@Slf4j,从重要到不重要的顺序; @Service @Validated public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopyService { - @Resource + @Resource // TODO @kyle:第一个变量,和类之间要有空行; private BpmProcessInstanceCopyMapper processInstanceCopyMapper; /** - * 和flowable有关的,查询流程名用的 + * 和flowable有关的,查询流程名用的 TODO @kyle:可以不写哈注释; */ @Resource private RuntimeService runtimeService; /** - * 找抄送人用的 + * 找抄送人用的 TODO @kyle:可以不写哈注释; */ @Resource private BpmCandidateSourceInfoProcessorChain processorChain; + // TODO @kyle:多余的变量,可以去掉哈 @Resource @Lazy // 解决循环依赖 - private BpmTaskService taskService; + private BpmTaskService bpmTaskService; + @Resource + @Lazy // 解决循环依赖 + private BpmProcessInstanceService bpmProcessInstanceService; @Resource private AdminUserApi adminUserApi; @@ -60,6 +66,10 @@ public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopy return BpmProcessInstanceCopyConvert.INSTANCE.convert(bpmProcessInstanceCopyDO); } + // TODO @kyle:makeCopy 和 ccProcessInstance 的调用关系,感受上反了; + // makeCopy 有点像基于规则,查找抄送人,然后创建; + // ccProcessInstance 是已经有了抄送人,然后创建; + // 建议的改造:独立基于 processInstanceCopyMapper 做 insert @Override public boolean makeCopy(BpmCandidateSourceInfo sourceInfo) { if (null == sourceInfo) { @@ -103,13 +113,13 @@ public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopy } @Override - public boolean ccProcessInstance(Long loginUserId, BpmProcessInstanceCCReqVO reqVO) { + public boolean ccProcessInstance(Long userId, BpmProcessInstanceCCReqVO reqVO) { // 在能正常审批的情况下抄送流程 BpmCandidateSourceInfo sourceInfo = new BpmCandidateSourceInfo(); sourceInfo.setTaskId(reqVO.getTaskKey()); sourceInfo.setProcessInstanceId(reqVO.getProcessInstanceKey()); sourceInfo.addRule(reqVO); - sourceInfo.setCreator(String.valueOf(loginUserId)); + sourceInfo.setCreator(String.valueOf(userId)); sourceInfo.setReason(reqVO.getReason()); if (!makeCopy(sourceInfo)) { throw new RuntimeException("抄送任务失败"); @@ -117,15 +127,20 @@ public class BpmProcessInstanceCopyServiceImpl implements BpmProcessInstanceCopy return false; } - //获取流程抄送分页 + //获取流程抄送分页 TODO @kyle:接口已经注释,这里不用注释了哈; @Override public PageResult getMyProcessInstanceCCPage(Long loginUserId, BpmProcessInstanceCCMyPageReqVO pageReqVO) { // 通过 BpmProcessInstanceExtDO 表,先查询到对应的分页 + // TODO @kyle:一般读逻辑,Service 返回 PageResult 即可。关联数据的查询和拼接,交给 Controller;目的是:保证 Service 聚焦写逻辑,清晰简洁; PageResult pageResult = processInstanceCopyMapper.selectPage(loginUserId, pageReqVO); if (CollUtil.isEmpty(pageResult.getList())) { return new PageResult<>(pageResult.getTotal()); } + // TODO @kyle:这种可以简洁点;参考如下 +// Map processInstanceMap = bpmProcessInstanceService.getProcessInstanceMap( +// convertSet(pageResult.getList(), BpmProcessInstanceCopyDO::getProcessInstanceId)); + Set taskIds = new HashSet<>(); Set processInstaneIds = new HashSet<>(); Set userIds = new HashSet<>(); diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyVO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyVO.java index 773335837..881ec6fd3 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyVO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/cc/BpmProcessInstanceCopyVO.java @@ -1,13 +1,11 @@ package cn.iocoder.yudao.module.bpm.service.cc; -import com.baomidou.mybatisplus.annotation.TableId; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.time.LocalDateTime; -import java.util.Date; - +// TODO @kyle:看看是不是要删除 /** * 流程抄送视图对象 wf_copy * diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/util/FlowableUtils.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/util/FlowableUtils.java index 94dabcd8e..0217ea382 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/util/FlowableUtils.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/util/FlowableUtils.java @@ -88,6 +88,7 @@ public class FlowableUtils { return task.getName(); } + // TODO @kyle:Utils 里不做查询;可以封装到 bpmTaskService 里 public static Map getTaskNameByTaskIds(Collection taskIds) { TaskService taskService = SpringUtil.getBean(TaskService.class); List tasks = taskService.createTaskQuery().taskIds(taskIds).list(); @@ -109,6 +110,7 @@ public class FlowableUtils { return processInstance.getName(); } + // TODO @kyle:Utils 里不做查询;可以封装到 bpmTaskService 里 public static Map getProcessInstanceNameByTaskIds(Set taskIds) { RuntimeService runtimeService = SpringUtil.getBean(RuntimeService.class); List processInstances = runtimeService.createProcessInstanceQuery().processInstanceIds(taskIds).list(); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java index 2d5c766fd..b2f95d69f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/ip/AreaController.java @@ -2,11 +2,11 @@ package cn.iocoder.yudao.module.system.controller.admin.ip; import cn.hutool.core.lang.Assert; import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.ip.core.Area; import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; import cn.iocoder.yudao.framework.ip.core.utils.IPUtils; import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeRespVO; -import cn.iocoder.yudao.module.system.convert.ip.AreaConvert; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; @@ -31,7 +31,7 @@ public class AreaController { public CommonResult> getAreaTree() { Area area = AreaUtils.getArea(Area.ID_CHINA); Assert.notNull(area, "获取不到中国"); - return success(AreaConvert.INSTANCE.convertList(area.getChildren())); + return success(BeanUtils.toBean(area.getChildren(), AreaNodeRespVO.class)); } @GetMapping("/get-by-ip") diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/vo/user/SocialUserBindReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/vo/user/SocialUserBindReqVO.java index 815f367fa..5ed0042a8 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/vo/user/SocialUserBindReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/socail/vo/user/SocialUserBindReqVO.java @@ -31,7 +31,4 @@ public class SocialUserBindReqVO { @NotEmpty(message = "state 不能为空") private String state; - public Integer getType() { - return type; - } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/ip/AppAreaController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/ip/AppAreaController.java index 98260a34d..54b0e87db 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/ip/AppAreaController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/ip/AppAreaController.java @@ -2,10 +2,10 @@ package cn.iocoder.yudao.module.system.controller.app.ip; import cn.hutool.core.lang.Assert; import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.ip.core.Area; import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; import cn.iocoder.yudao.module.system.controller.app.ip.vo.AppAreaNodeRespVO; -import cn.iocoder.yudao.module.system.convert.ip.AreaConvert; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.validation.annotation.Validated; @@ -28,7 +28,7 @@ public class AppAreaController { public CommonResult> getAreaTree() { Area area = AreaUtils.getArea(Area.ID_CHINA); Assert.notNull(area, "获取不到中国"); - return success(AreaConvert.INSTANCE.convertList3(area.getChildren())); + return success(BeanUtils.toBean(area.getChildren(), AppAreaNodeRespVO.class)); } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/ip/AreaConvert.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/ip/AreaConvert.java deleted file mode 100644 index 6ba76ef92..000000000 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/ip/AreaConvert.java +++ /dev/null @@ -1,28 +0,0 @@ -package cn.iocoder.yudao.module.system.convert.ip; - -import cn.iocoder.yudao.framework.ip.core.Area; -import cn.iocoder.yudao.module.system.controller.admin.ip.vo.AreaNodeRespVO; -import cn.iocoder.yudao.module.system.controller.app.ip.vo.AppAreaNodeRespVO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -import java.util.List; - -@Mapper -public interface AreaConvert { - - AreaConvert INSTANCE = Mappers.getMapper(AreaConvert.class); - - List convertList(List list); - - List convertList3(List list); - - /** - * 缺少单个转换 - * @param value - * @return - */ - AreaNodeRespVO map(Area value); - - AppAreaNodeRespVO map3(Area value); -} From fea84deca0f0e0fa9da99b0dc65de3fb932b011e Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 18 Jan 2024 23:58:44 +0800 Subject: [PATCH 20/27] =?UTF-8?q?=E2=9C=A8=20Pay=EF=BC=9Acode=20review=20?= =?UTF-8?q?=E6=94=AF=E4=BB=98=E8=BD=AC=E8=B4=A6=E7=9A=84=E9=83=A8=E5=88=86?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/{ => optinal}/Ureport.sql | 0 sql/mysql/optinal/crm.sql | 14 - sql/mysql/optinal/crm_20240114.sql | 23 -- sql/mysql/optinal/mall.sql | 0 sql/mysql/optinal/pay_wallet.sql | 256 ------------------ sql/mysql/optinal/product_browse_history.sql | 22 -- .../service/group/MemberGroupService.java | 2 - .../point/MemberPointRecordService.java | 1 - .../dataobject/demo/PayDemoTransferDO.java | 1 + .../dataobject/transfer/PayTransferDO.java | 1 + 10 files changed, 2 insertions(+), 318 deletions(-) rename sql/mysql/{ => optinal}/Ureport.sql (100%) delete mode 100644 sql/mysql/optinal/crm.sql delete mode 100644 sql/mysql/optinal/crm_20240114.sql delete mode 100644 sql/mysql/optinal/mall.sql delete mode 100644 sql/mysql/optinal/pay_wallet.sql delete mode 100644 sql/mysql/optinal/product_browse_history.sql diff --git a/sql/mysql/Ureport.sql b/sql/mysql/optinal/Ureport.sql similarity index 100% rename from sql/mysql/Ureport.sql rename to sql/mysql/optinal/Ureport.sql diff --git a/sql/mysql/optinal/crm.sql b/sql/mysql/optinal/crm.sql deleted file mode 100644 index 77ec46d97..000000000 --- a/sql/mysql/optinal/crm.sql +++ /dev/null @@ -1,14 +0,0 @@ --- `ruoyi-vue-pro`.crm_contact_business_link definition - -CREATE TABLE `crm_contact_business` ( - `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', - `contact_id` int(11) DEFAULT NULL COMMENT '联系人id', - `business_id` int(11) DEFAULT NULL COMMENT '商机id', - `creator` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '创建者', - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `updater` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '更新者', - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - `tenant_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '租户编号', - PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='联系人商机关联表'; \ No newline at end of file diff --git a/sql/mysql/optinal/crm_20240114.sql b/sql/mysql/optinal/crm_20240114.sql deleted file mode 100644 index 50e462c81..000000000 --- a/sql/mysql/optinal/crm_20240114.sql +++ /dev/null @@ -1,23 +0,0 @@ - --- ---------------------------- --- Table structure for crm_business_product --- ---------------------------- -DROP TABLE IF EXISTS `crm_business_product`; -CREATE TABLE `crm_business_product` ( - `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键', - `business_id` bigint(0) NOT NULL COMMENT '商机ID', - `product_id` bigint(0) NOT NULL COMMENT '产品ID', - `price` decimal(18, 2) NOT NULL COMMENT '产品单价', - `sales_price` decimal(18, 2) NULL DEFAULT NULL COMMENT '销售价格', - `num` int(0) NULL DEFAULT NULL COMMENT '数量', - `discount` decimal(10, 2) NULL DEFAULT NULL COMMENT '折扣', - `subtotal` decimal(18, 2) NULL DEFAULT NULL COMMENT '小计(折扣后价格)', - `unit` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '单位', - `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', - `create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', - `update_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - `tenant_id` bigint(0) NOT NULL DEFAULT 1 COMMENT '租户编号', - PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 29 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '商机产品关联表' ROW_FORMAT = Dynamic; \ No newline at end of file diff --git a/sql/mysql/optinal/mall.sql b/sql/mysql/optinal/mall.sql deleted file mode 100644 index e69de29bb..000000000 diff --git a/sql/mysql/optinal/pay_wallet.sql b/sql/mysql/optinal/pay_wallet.sql deleted file mode 100644 index 1e9f1d255..000000000 --- a/sql/mysql/optinal/pay_wallet.sql +++ /dev/null @@ -1,256 +0,0 @@ --- ---------------------------- --- 转账单表 --- ---------------------------- -DROP TABLE IF EXISTS `pay_transfer`; -CREATE TABLE `pay_transfer` -( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号', - `no` varchar(64) NOT NULL COMMENT '转账单号', - `app_id` bigint NOT NULL COMMENT '应用编号', - `channel_id` bigint NOT NULL COMMENT '转账渠道编号', - `channel_code` varchar(32) NOT NULL COMMENT '转账渠道编码', - `merchant_transfer_id` varchar(64) NOT NULL COMMENT '商户转账单编号', - `type` int NOT NULL COMMENT '类型', - `status` tinyint NOT NULL COMMENT '转账状态', - `success_time` datetime NULL COMMENT '转账成功时间', - `price` int NOT NULL COMMENT '转账金额,单位:分', - `subject` varchar(512) NOT NULL COMMENT '转账标题', - `user_name` varchar(64) NULL COMMENT '收款人姓名', - `alipay_logon_id` varchar(64) NULL COMMENT '支付宝登录号', - `openid` varchar(64) NULL COMMENT '微信 openId', - `notify_url` varchar(1024) NOT NULL COMMENT '异步通知商户地址', - `user_ip` varchar(50) NOT NULL COMMENT '用户 IP', - `channel_extras` varchar(512) NULL DEFAULT NULL COMMENT '渠道的额外参数', - `channel_transfer_no` varchar(64) NULL DEFAULT NULL COMMENT '渠道转账单号', - `channel_error_code` varchar(128) NULL DEFAULT NULL COMMENT '调用渠道的错误码', - `channel_error_msg` varchar(256) NULL DEFAULT NULL COMMENT '调用渠道的错误提示', - `channel_notify_data` varchar(4096) NULL DEFAULT NULL COMMENT '渠道的同步/异步通知的内容', - `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', - PRIMARY KEY (`id`) USING BTREE -) ENGINE=InnoDB COMMENT='转账单表'; - --- ---------------------------- --- Table structure for pay_demo_transfer --- ---------------------------- -DROP TABLE IF EXISTS `pay_demo_transfer`; -CREATE TABLE `pay_demo_transfer` ( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '订单编号', - `app_id` bigint NOT NULL COMMENT '应用编号', - `type` int NOT NULL COMMENT '转账类型', - `price` int NOT NULL COMMENT '转账金额,单位:分', - `user_name` varchar(64) NULL COMMENT '收款人姓名', - `alipay_logon_id` varchar(64) NULL COMMENT '支付宝登录号', - `openid` varchar(64) NULL COMMENT '微信 openId', - `transfer_status` tinyint NOT NULL DEFAULT 0 COMMENT '转账状态', - `pay_transfer_id` bigint NULL DEFAULT NULL COMMENT '转账订单编号', - `pay_channel_code` varchar(16) NULL DEFAULT NULL COMMENT '转账支付成功渠道', - `transfer_time` datetime NULL DEFAULT NULL COMMENT '转账支付时间', - `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT '' COMMENT '创建者', - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT '' COMMENT '更新者', - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', - PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB COMMENT = '示例业务转账订单'; - - --- ALTER TABLE `pay_channel` --- MODIFY COLUMN `config` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '支付渠道配置' AFTER `app_id`; - --- ---------------------------- --- 充值套餐表 --- ---------------------------- -DROP TABLE IF EXISTS `pay_wallet_recharge_package`; -CREATE TABLE `pay_wallet_recharge_package` -( - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号', - `name` varchar(64) NOT NULL COMMENT '套餐名', - `pay_price` int NOT NULL COMMENT '支付金额', - `bonus_price` int NOT NULL COMMENT '赠送金额', - `status` tinyint NOT NULL COMMENT '状态', - `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT '' COMMENT '创建者', - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', - PRIMARY KEY (`id`) USING BTREE -) ENGINE=InnoDB COMMENT='充值套餐表'; - --- ---------------------------- --- Table structure for pay_wallet_recharge --- ---------------------------- -DROP TABLE IF EXISTS `pay_wallet_recharge`; -CREATE TABLE `pay_wallet_recharge` ( - `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '编号', - `wallet_id` bigint(0) NOT NULL COMMENT '会员钱包 id', - `total_price` int(0) NOT NULL COMMENT '用户实际到账余额,例如充 100 送 20,则该值是 120', - `pay_price` int(0) NOT NULL COMMENT '实际支付金额', - `bonus_price` int(0) NOT NULL COMMENT '钱包赠送金额', - `package_id` bigint(0) DEFAULT NULL COMMENT '充值套餐编号', - `pay_status` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否已支付:[0:未支付 1:已经支付过]', - `pay_order_id` bigint(0) DEFAULT NULL COMMENT '支付订单编号', - `pay_channel_code` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '支付成功的支付渠道', - `pay_time` datetime(0) DEFAULT NULL COMMENT '订单支付时间', - `pay_refund_id` bigint(0) DEFAULT NULL COMMENT '支付退款单编号', - `refund_total_price` int(0) NOT NULL DEFAULT 0 COMMENT '退款金额,包含赠送金额', - `refund_pay_price` int(0) NOT NULL DEFAULT 0 COMMENT '退款支付金额', - `refund_bonus_price` int(0) NOT NULL DEFAULT 0 COMMENT '退款钱包赠送金额', - `refund_time` datetime(0) DEFAULT NULL COMMENT '退款时间', - `refund_status` int(0) NOT NULL DEFAULT 0 COMMENT '退款状态', - `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '创建者', - `create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '更新者', - `update_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间', - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', - `tenant_id` bigint(0) NOT NULL DEFAULT 0 COMMENT '租户编号', - PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员钱包充值' ROW_FORMAT = Dynamic; - --- 钱包充值套餐,钱包余额菜单脚本 - -INSERT INTO system_menu( - name, permission, type, sort, parent_id, - path, icon, component, status, component_name -) -VALUES ( - '钱包管理', '', 1, 5, 1117, - 'wallet', 'ep:caret-right', '', 0, '' - ); -SELECT @parentId1 := LAST_INSERT_ID(); - -INSERT INTO system_menu( - name, permission, type, sort, parent_id, - path, icon, component, status, component_name -) -VALUES ( - '充值套餐', '', 2, 2, @parentId1, - 'wallet-recharge-package', 'fa:leaf', 'pay/wallet/rechargePackage/index', 0, 'WalletRechargePackage' - ); -SELECT @parentId := LAST_INSERT_ID(); - --- 按钮 SQL -INSERT INTO system_menu( - name, permission, type, sort, parent_id, - path, icon, component, status -) -VALUES ( - '钱包充值套餐查询', 'pay:wallet-recharge-package:query', 3, 1, @parentId, - '', '', '', 0 - ); -INSERT INTO system_menu( - name, permission, type, sort, parent_id, - path, icon, component, status -) -VALUES ( - '钱包充值套餐创建', 'pay:wallet-recharge-package:create', 3, 2, @parentId, - '', '', '', 0 - ); -INSERT INTO system_menu( - name, permission, type, sort, parent_id, - path, icon, component, status -) -VALUES ( - '钱包充值套餐更新', 'pay:wallet-recharge-package:update', 3, 3, @parentId, - '', '', '', 0 - ); -INSERT INTO system_menu( - name, permission, type, sort, parent_id, - path, icon, component, status -) -VALUES ( - '钱包充值套餐删除', 'pay:wallet-recharge-package:delete', 3, 4, @parentId, - '', '', '', 0 - ); - -INSERT INTO system_menu( - name, permission, type, sort, parent_id, - path, icon, component, status, component_name -) -VALUES ( - '钱包余额', '', 2, 1, @parentId1, - 'wallet-balance', 'fa:leaf', 'pay/wallet/balance/index', 0, 'WalletBalance' - ); - -SELECT @parentId := LAST_INSERT_ID(); - --- 按钮 SQL -INSERT INTO system_menu( - name, permission, type, sort, parent_id, - path, icon, component, status -) -VALUES ( - '钱包余额查询', 'pay:wallet:query', 3, 1, @parentId, - '', '', '', 0 - ); - --- 支付实战和转账实战数据库脚本 - -update system_menu set deleted = 1 where id = 2161; - -INSERT INTO system_menu( - name, permission, type, sort, parent_id, - path, icon, component, status, component_name -) -VALUES ( - '接入示例', '', 1, 99, 1117, - 'demo', 'ep:caret-right', '', 0, '' - ); - -SELECT @parentId1 := LAST_INSERT_ID(); - -INSERT INTO system_menu( - name, permission, type, sort, parent_id, - path, icon, component, status, component_name -) -VALUES ( - '支付实战', '', 2, 1, @parentId1, - 'demo-order', 'fa:leaf', 'pay/demo/order/index', 0, NULL - ); - -INSERT INTO system_menu( - name, permission, type, sort, parent_id, - path, icon, component, status, component_name -) -VALUES ( - '转账实战', '', 2, 1, @parentId1, - 'demo-transfer', 'fa:leaf', 'pay/demo/transfer/index', 0, NULL - ); - --- 转账状态和转账类型数据字典 -INSERT INTO `system_dict_type`(`name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES ('支付转账类型', 'pay_transfer_type', 0, '', '1', '2023-10-28 16:27:18', '1', '2023-10-28 16:27:18', b'0', '1970-01-01 00:00:00'); -INSERT INTO `system_dict_type`(`name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES ('转账订单状态', 'pay_transfer_status', 0, '', '1', '2023-10-28 16:18:32', '1', '2023-10-28 16:18:32', b'0', '1970-01-01 00:00:00'); - -INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4, '钱包余额', '4', 'pay_transfer_type', 0, 'info', '', '', '1', '2023-10-28 16:28:37', '1', '2023-10-28 16:28:37', b'0'); -INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3, '银行卡', '3', 'pay_transfer_type', 0, 'default', '', '', '1', '2023-10-28 16:28:21', '1', '2023-10-28 16:28:21', b'0'); -INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2, '微信余额', '2', 'pay_transfer_type', 0, 'info', '', '', '1', '2023-10-28 16:28:07', '1', '2023-10-28 16:28:07', b'0'); -INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '支付宝余额', '1', 'pay_transfer_type', 0, 'default', '', '', '1', '2023-10-28 16:27:44', '1', '2023-10-28 16:27:44', b'0'); -INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (4, '转账失败', '30', 'pay_transfer_status', 0, 'warning', '', '', '1', '2023-10-28 16:24:16', '1', '2023-10-28 16:24:16', b'0'); -INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (3, '转账成功', '20', 'pay_transfer_status', 0, 'success', '', '', '1', '2023-10-28 16:23:50', '1', '2023-10-28 16:23:50', b'0'); -INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2, '转账进行中', '10', 'pay_transfer_status', 0, 'info', '', '', '1', '2023-10-28 16:23:12', '1', '2023-10-28 16:23:12', b'0'); -INSERT INTO `system_dict_data`(`sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1, '等待转账', '0', 'pay_transfer_status', 0, 'default', '', '', '1', '2023-10-28 16:21:43', '1', '2023-10-28 16:23:22', b'0'); - --- 转账订单菜单脚本 - -INSERT INTO system_menu( - name, permission, type, sort, parent_id, - path, icon, component, status, component_name -) -VALUES ( - '转账订单', '', 2, 3, 1117, - 'transfer', 'ep:credit-card', 'pay/transfer/index', 0, 'PayTransfer' - ); - --- 转账通知脚本 - -ALTER TABLE `pay_app` - ADD COLUMN `transfer_notify_url` varchar(1024) NOT NULL COMMENT '转账结果的回调地址' AFTER `refund_notify_url`; -ALTER TABLE `pay_notify_task` - MODIFY COLUMN `merchant_order_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT '商户订单编号' AFTER `status`, - ADD COLUMN `merchant_transfer_id` varchar(64) COMMENT '商户转账单编号' AFTER `merchant_order_id`; \ No newline at end of file diff --git a/sql/mysql/optinal/product_browse_history.sql b/sql/mysql/optinal/product_browse_history.sql deleted file mode 100644 index 8925f7c9e..000000000 --- a/sql/mysql/optinal/product_browse_history.sql +++ /dev/null @@ -1,22 +0,0 @@ -CREATE TABLE product_browse_history -( - id bigint AUTO_INCREMENT COMMENT '记录编号' - PRIMARY KEY, - user_id bigint NOT NULL COMMENT '用户编号', - spu_id bigint NOT NULL COMMENT '商品 SPU 编号', - user_deleted bit DEFAULT b'0' NOT NULL COMMENT '用户是否删除', - creator varchar(64) DEFAULT '' NULL COMMENT '创建者', - create_time datetime DEFAULT CURRENT_TIMESTAMP NOT NULL COMMENT '创建时间', - updater varchar(64) DEFAULT '' NULL COMMENT '更新者', - update_time datetime DEFAULT CURRENT_TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - deleted bit DEFAULT b'0' NOT NULL COMMENT '是否删除', - tenant_id bigint DEFAULT 0 NOT NULL COMMENT '租户编号' -) - COMMENT '商品浏览记录表'; - -CREATE INDEX idx_spuId - ON product_browse_history (spu_id); - -CREATE INDEX idx_userId - ON product_browse_history (user_id); - diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/group/MemberGroupService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/group/MemberGroupService.java index aab428f2f..54419bdde 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/group/MemberGroupService.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/group/MemberGroupService.java @@ -64,7 +64,6 @@ public interface MemberGroupService { */ PageResult getGroupPage(MemberGroupPageReqVO pageReqVO); - /** * 获得指定状态的用户分组列表 * @@ -73,7 +72,6 @@ public interface MemberGroupService { */ List getGroupListByStatus(Integer status); - /** * 获得开启状态的用户分组列表 * diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointRecordService.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointRecordService.java index 26d18a852..7e660d5d6 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointRecordService.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointRecordService.java @@ -1,6 +1,5 @@ package cn.iocoder.yudao.module.member.service.point; -import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.member.controller.admin.point.vo.recrod.MemberPointRecordPageReqVO; import cn.iocoder.yudao.module.member.controller.app.point.vo.AppMemberPointRecordPageReqVO; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoTransferDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoTransferDO.java index 621cafc3a..f465d0be6 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoTransferDO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoTransferDO.java @@ -10,6 +10,7 @@ import lombok.Data; import java.time.LocalDateTime; +// TODO 芋艿:需要详细 review /** * 示例转账订单 * diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java index 0bae028f4..8f3563ffb 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java @@ -16,6 +16,7 @@ import lombok.Data; import java.time.LocalDateTime; import java.util.Map; +// TODO 芋艿:需要详细 review /** * 转账单 DO * From ba4f9207e20bf6555e307acb9a0f8e67527ec6f3 Mon Sep 17 00:00:00 2001 From: min Date: Sat, 20 Jan 2024 13:55:05 +0800 Subject: [PATCH 21/27] =?UTF-8?q?CRM=EF=BC=9A=E3=80=90=E7=BA=BF=E7=B4=A2?= =?UTF-8?q?=E3=80=91=E4=BD=BF=E7=94=A8=E5=B7=A5=E5=85=B7=E7=B1=BB=E6=9B=BF?= =?UTF-8?q?=E6=8D=A2stream=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../crm/service/clue/CrmClueServiceImpl.java | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java index 4a6ff9575..506424697 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java @@ -3,7 +3,9 @@ package cn.iocoder.yudao.module.crm.service.clue; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; 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.clue.vo.CrmCluePageReqVO; import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueSaveReqVO; @@ -25,11 +27,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; -import java.util.Collection; -import java.util.List; -import java.util.Objects; -import java.util.Set; -import java.util.stream.Collectors; +import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; @@ -145,19 +143,16 @@ public class CrmClueServiceImpl implements CrmClueService { List clues = getClueList(clueIds, userId); if (CollUtil.isEmpty(clues) || ObjectUtil.notEqual(clues.size(), clueIds.size())) { clueIds.removeAll(convertSet(clues, CrmClueDO::getId)); - // TODO @min:可以使用 StrUtil.join(",", clueIds) 简化这种常见操作 - throw exception(CLUE_ANY_CLUE_NOT_EXISTS, clueIds.stream().map(String::valueOf).collect(Collectors.joining(","))); + throw exception(CLUE_ANY_CLUE_NOT_EXISTS, StrUtil.join(",", clueIds)); } // 过滤出未转化的客户 - // TODO @min:1)存在已经转化的,直接提示哈。避免操作的用户,以为都转化成功了;2)常见的过滤逻辑,可以使用 CollectionUtils.filterList() - List unTransformClues = clues.stream() - .filter(clue -> ObjectUtil.notEqual(Boolean.TRUE, clue.getTransformStatus())).toList(); - // 传入的线索中包含已经转化的情况,抛出业务异常 + List unTransformClues = CollectionUtils.filterList(clues, + clue -> ObjectUtil.notEqual(Boolean.TRUE, clue.getTransformStatus())); + // 存在已经转化的,直接提示哈。避免操作的用户,以为都转化成功了 if (ObjectUtil.notEqual(clues.size(), unTransformClues.size())) { - // TODO @min:可以使用 StrUtil.join(",", clueIds) 简化这种常见操作 clueIds.removeAll(convertSet(unTransformClues, CrmClueDO::getId)); - throw exception(CLUE_ANY_CLUE_ALREADY_TRANSLATED, clueIds.stream().map(String::valueOf).collect(Collectors.joining(","))); + throw exception(CLUE_ANY_CLUE_ALREADY_TRANSLATED, StrUtil.join(",", clueIds)); } // 遍历线索(未转化的线索),创建对应的客户 From 7914423c66b8f1960d7c4bbf014e9db5399c2fb7 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Sat, 20 Jan 2024 14:56:31 +0800 Subject: [PATCH 22/27] =?UTF-8?q?CRM:=20=E5=AE=8C=E5=96=84=E8=B7=9F?= =?UTF-8?q?=E8=BF=9B=20TODO?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../convert/business/CrmBusinessConvert.java | 9 ++ .../convert/contact/CrmContactConvert.java | 8 ++ .../service/business/CrmBusinessService.java | 4 +- .../business/CrmBusinessServiceImpl.java | 6 +- .../bo/CrmBusinessUpdateFollowUpReqBO.java | 38 ------- .../crm/service/clue/CrmClueService.java | 4 +- .../crm/service/clue/CrmClueServiceImpl.java | 6 +- .../service/contact/CrmContactService.java | 4 +- .../contact/CrmContactServiceImpl.java | 6 +- .../bo/CrmContactUpdateFollowUpReqBO.java | 38 ------- .../service/contract/CrmContractService.java | 4 +- .../contract/CrmContractServiceImpl.java | 6 +- .../bo/CrmContractUpdateFollowUpReqBO.java | 38 ------- .../service/customer/CrmCustomerService.java | 4 +- .../customer/CrmCustomerServiceImpl.java | 6 +- .../bo/CrmCustomerUpdateFollowUpReqBO.java | 33 ------ .../CrmFollowUpRecordServiceImpl.java | 104 ++++++++++++++---- .../bo/CrmUpdateFollowUpReqBO.java} | 15 ++- .../handle/CrmBusinessFollowUpHandler.java | 38 ------- .../handle/CrmClueFollowUpHandler.java | 37 ------- .../handle/CrmContactFollowUpHandler.java | 38 ------- .../handle/CrmContractFollowUpHandler.java | 37 ------- .../handle/CrmCustomerFollowUpHandler.java | 37 ------- .../followup/handle/CrmFollowUpHandler.java | 23 ---- .../comment/ProductCommentConvert.java | 4 + .../ProductCommentServiceImplTest.java | 11 +- 26 files changed, 143 insertions(+), 415 deletions(-) delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/bo/CrmBusinessUpdateFollowUpReqBO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/bo/CrmContactUpdateFollowUpReqBO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/bo/CrmContractUpdateFollowUpReqBO.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/bo/CrmCustomerUpdateFollowUpReqBO.java rename yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/{clue/bo/CrmClueUpdateFollowUpReqBO.java => followup/bo/CrmUpdateFollowUpReqBO.java} (67%) delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmBusinessFollowUpHandler.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmClueFollowUpHandler.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmContactFollowUpHandler.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmContractFollowUpHandler.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmCustomerFollowUpHandler.java delete mode 100644 yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmFollowUpHandler.java 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 63c8ab7d6..56bba541e 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,6 +1,7 @@ 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; @@ -8,6 +9,7 @@ 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; import org.mapstruct.Mapping; @@ -45,4 +47,11 @@ public interface CrmBusinessConvert { return voPageResult; } + @Mapping(target = "id", source = "reqBO.bizId") + CrmBusinessDO convert(CrmUpdateFollowUpReqBO reqBO); + + default List convertList(List updateFollowUpReqBOList) { + return CollectionUtils.convertList(updateFollowUpReqBOList, INSTANCE::convert); + } + } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/CrmContactConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/CrmContactConvert.java index 363fd4f60..1d32331bb 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/CrmContactConvert.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/CrmContactConvert.java @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactRespVO; import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactTransferReqVO; 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.followup.bo.CrmUpdateFollowUpReqBO; import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO; import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; import org.mapstruct.Mapper; @@ -66,4 +67,11 @@ public interface CrmContactConvert { findAndThen(userMap, Long.parseLong(contactRespVO.getCreator()), user -> contactRespVO.setCreatorName(user.getNickname())); } + @Mapping(target = "id", source = "reqBO.bizId") + CrmContactDO convert(CrmUpdateFollowUpReqBO reqBO); + + default List convertList(List updateFollowUpReqBOList) { + return CollectionUtils.convertList(updateFollowUpReqBOList, INSTANCE::convert); + } + } 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 8dae99eb8..fde5551c1 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 @@ -7,7 +7,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusi import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO; 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.CrmBusinessUpdateFollowUpReqBO; +import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO; import jakarta.validation.Valid; import java.util.Collection; @@ -41,7 +41,7 @@ public interface CrmBusinessService { * * @param updateFollowUpReqBOList 跟进信息 */ - void updateContactFollowUpBatch(List updateFollowUpReqBOList); + void updateBusinessFollowUpBatch(List updateFollowUpReqBOList); /** * 删除商机 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 a4d08f315..58c0851b5 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 @@ -21,8 +21,8 @@ import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper; import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; 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.CrmBusinessUpdateFollowUpReqBO; import cn.iocoder.yudao.module.crm.service.contact.CrmContactBusinessService; +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 com.mzt.logapi.context.LogRecordContext; @@ -172,8 +172,8 @@ public class CrmBusinessServiceImpl implements CrmBusinessService { } @Override - public void updateContactFollowUpBatch(List updateFollowUpReqBOList) { - businessMapper.updateBatch(BeanUtils.toBean(updateFollowUpReqBOList, CrmBusinessDO.class)); + public void updateBusinessFollowUpBatch(List updateFollowUpReqBOList) { + businessMapper.updateBatch(CrmBusinessConvert.INSTANCE.convertList(updateFollowUpReqBOList)); } @Override diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/bo/CrmBusinessUpdateFollowUpReqBO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/bo/CrmBusinessUpdateFollowUpReqBO.java deleted file mode 100644 index ccf8d0a0a..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/bo/CrmBusinessUpdateFollowUpReqBO.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.business.bo; - -import com.mzt.logapi.starter.annotation.DiffLogField; -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotNull; -import lombok.Data; - -import java.time.LocalDateTime; - -// TODO @puhui999:是不是搞个通用的 ReqBO 就好了 -/** - * 商机跟进信息 Update Req BO - * - * @author HUIHUI - */ -@Data -public class CrmBusinessUpdateFollowUpReqBO { - - @Schema(description = "商机编号", example = "3167") - @NotNull(message = "商机编号不能为空") - private Long id; - - @Schema(description = "最后跟进时间") - @DiffLogField(name = "最后跟进时间") - @NotNull(message = "最后跟进时间不能为空") - private LocalDateTime contactLastTime; - - @Schema(description = "下次联系时间") - @DiffLogField(name = "下次联系时间") - @NotNull(message = "下次联系时间不能为空") - private LocalDateTime contactNextTime; - - @Schema(description = "最后更进内容") - @DiffLogField(name = "最后更进内容") - @NotNull(message = "最后更进内容不能为空") - private String contactLastContent; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueService.java index 47ece94e2..6efffa96a 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueService.java @@ -6,7 +6,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueSaveReqVO; import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueTransferReqVO; import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueTransformReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO; -import cn.iocoder.yudao.module.crm.service.clue.bo.CrmClueUpdateFollowUpReqBO; +import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO; import jakarta.validation.Valid; import java.util.Collection; @@ -39,7 +39,7 @@ public interface CrmClueService { * * @param clueUpdateFollowUpReqBO 信息 */ - void updateClueFollowUp(CrmClueUpdateFollowUpReqBO clueUpdateFollowUpReqBO); + void updateClueFollowUp(CrmUpdateFollowUpReqBO clueUpdateFollowUpReqBO); /** * 删除线索 diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java index 4a6ff9575..9bec56064 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java @@ -16,8 +16,8 @@ import cn.iocoder.yudao.module.crm.dal.mysql.clue.CrmClueMapper; import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; 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.clue.bo.CrmClueUpdateFollowUpReqBO; 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.system.api.user.AdminUserApi; import jakarta.annotation.Resource; @@ -84,8 +84,8 @@ public class CrmClueServiceImpl implements CrmClueService { } @Override - public void updateClueFollowUp(CrmClueUpdateFollowUpReqBO clueUpdateFollowUpReqBO) { - clueMapper.updateById(BeanUtils.toBean(clueUpdateFollowUpReqBO, CrmClueDO.class)); + public void updateClueFollowUp(CrmUpdateFollowUpReqBO clueUpdateFollowUpReqBO) { + clueMapper.updateById(BeanUtils.toBean(clueUpdateFollowUpReqBO, CrmClueDO.class).setId(clueUpdateFollowUpReqBO.getBizId())); } @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 5962db9a8..a43ed2e65 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 @@ -6,7 +6,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactSaveReq import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.CrmContactTransferReqVO; 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.contact.bo.CrmContactUpdateFollowUpReqBO; +import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO; import jakarta.validation.Valid; import java.util.Collection; @@ -63,7 +63,7 @@ public interface CrmContactService { * * @param updateFollowUpReqBOList 跟进信息 */ - void updateContactFollowUpBatch(List updateFollowUpReqBOList); + void updateContactFollowUpBatch(List updateFollowUpReqBOList); /** * 获得联系人 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 7b6f83e04..52f2d6cf7 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 @@ -15,9 +15,9 @@ import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; 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.CrmBusinessService; -import cn.iocoder.yudao.module.crm.service.contact.bo.CrmContactUpdateFollowUpReqBO; 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.system.api.user.AdminUserApi; @@ -195,8 +195,8 @@ public class CrmContactServiceImpl implements CrmContactService { } @Override - public void updateContactFollowUpBatch(List updateFollowUpReqBOList) { - contactMapper.updateBatch(BeanUtils.toBean(updateFollowUpReqBOList, CrmContactDO.class)); + public void updateContactFollowUpBatch(List updateFollowUpReqBOList) { + contactMapper.updateBatch(CrmContactConvert.INSTANCE.convertList(updateFollowUpReqBOList)); } //======================= 查询相关 ======================= diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/bo/CrmContactUpdateFollowUpReqBO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/bo/CrmContactUpdateFollowUpReqBO.java deleted file mode 100644 index 40604353e..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/bo/CrmContactUpdateFollowUpReqBO.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.contact.bo; - -import com.mzt.logapi.starter.annotation.DiffLogField; -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotNull; -import lombok.Data; - -import java.time.LocalDateTime; - -// TODO @puhui999:是不是搞个通用的 ReqBO 就好了 -/** - * 联系人跟进信息 Update Req BO - * - * @author HUIHUI - */ -@Data -public class CrmContactUpdateFollowUpReqBO { - - @Schema(description = "联系人编号", example = "3167") - @NotNull(message = "联系人编号不能为空") - private Long id; - - @Schema(description = "最后跟进时间") - @DiffLogField(name = "最后跟进时间") - @NotNull(message = "最后跟进时间不能为空") - private LocalDateTime contactLastTime; - - @Schema(description = "下次联系时间") - @DiffLogField(name = "下次联系时间") - @NotNull(message = "下次联系时间不能为空") - private LocalDateTime contactNextTime; - - @Schema(description = "最后更进内容") - @DiffLogField(name = "最后更进内容") - @NotNull(message = "最后更进内容不能为空") - private String contactLastContent; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java index 26a9256f2..ec52d85c0 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java @@ -6,7 +6,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractSaveR import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractTransferReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; -import cn.iocoder.yudao.module.crm.service.contract.bo.CrmContractUpdateFollowUpReqBO; +import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO; import jakarta.validation.Valid; import java.util.Collection; @@ -55,7 +55,7 @@ public interface CrmContractService { * * @param contractUpdateFollowUpReqBO 信息 */ - void updateContractFollowUp(CrmContractUpdateFollowUpReqBO contractUpdateFollowUpReqBO); + void updateContractFollowUp(CrmUpdateFollowUpReqBO contractUpdateFollowUpReqBO); /** * 获得合同 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 b9142dd35..dc921e952 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 @@ -13,7 +13,7 @@ import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper; import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; 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.contract.bo.CrmContractUpdateFollowUpReqBO; +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 com.mzt.logapi.context.LogRecordContext; @@ -137,8 +137,8 @@ public class CrmContractServiceImpl implements CrmContractService { } @Override - public void updateContractFollowUp(CrmContractUpdateFollowUpReqBO contractUpdateFollowUpReqBO) { - contractMapper.updateById(BeanUtils.toBean(contractUpdateFollowUpReqBO, CrmContractDO.class)); + public void updateContractFollowUp(CrmUpdateFollowUpReqBO contractUpdateFollowUpReqBO) { + contractMapper.updateById(BeanUtils.toBean(contractUpdateFollowUpReqBO, CrmContractDO.class).setId(contractUpdateFollowUpReqBO.getBizId())); } //======================= 查询相关 ======================= diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/bo/CrmContractUpdateFollowUpReqBO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/bo/CrmContractUpdateFollowUpReqBO.java deleted file mode 100644 index 57c1f5f50..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/bo/CrmContractUpdateFollowUpReqBO.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.contract.bo; - -import com.mzt.logapi.starter.annotation.DiffLogField; -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotNull; -import lombok.Data; - -import java.time.LocalDateTime; - -// TODO @puhui999:是不是搞个通用的 ReqBO 就好了 -/** - * 合同跟进信息 Update Req BO - * - * @author HUIHUI - */ -@Data -public class CrmContractUpdateFollowUpReqBO { - - @Schema(description = "合同编号", example = "3167") - @NotNull(message = "合同编号不能为空") - private Long id; - - @Schema(description = "最后跟进时间") - @DiffLogField(name = "最后跟进时间") - @NotNull(message = "最后跟进时间不能为空") - private LocalDateTime contactLastTime; - - @Schema(description = "下次联系时间") - @DiffLogField(name = "下次联系时间") - @NotNull(message = "下次联系时间不能为空") - private LocalDateTime contactNextTime; - - @Schema(description = "最后更进内容") - @DiffLogField(name = "最后更进内容") - @NotNull(message = "最后更进内容不能为空") - private String contactLastContent; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerService.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerService.java index d40b08118..8cd2448b7 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerService.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerService.java @@ -6,7 +6,7 @@ import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPageR import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerSaveReqVO; import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerTransferReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; -import cn.iocoder.yudao.module.crm.service.customer.bo.CrmCustomerUpdateFollowUpReqBO; +import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO; import jakarta.validation.Valid; import java.util.Collection; @@ -96,7 +96,7 @@ public interface CrmCustomerService { * * @param customerUpdateFollowUpReqBO 请求 */ - void updateCustomerFollowUp(CrmCustomerUpdateFollowUpReqBO customerUpdateFollowUpReqBO); + void updateCustomerFollowUp(CrmUpdateFollowUpReqBO customerUpdateFollowUpReqBO); // ==================== 公海相关操作 ==================== diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java index a88b230e3..5c1f5134a 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/CrmCustomerServiceImpl.java @@ -21,7 +21,7 @@ import cn.iocoder.yudao.module.crm.framework.permission.core.util.CrmPermissionU import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService; 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.bo.CrmCustomerUpdateFollowUpReqBO; +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.system.api.user.AdminUserApi; @@ -205,8 +205,8 @@ public class CrmCustomerServiceImpl implements CrmCustomerService { } @Override - public void updateCustomerFollowUp(CrmCustomerUpdateFollowUpReqBO customerUpdateFollowUpReqBO) { - customerMapper.updateById(BeanUtils.toBean(customerUpdateFollowUpReqBO, CrmCustomerDO.class)); + public void updateCustomerFollowUp(CrmUpdateFollowUpReqBO customerUpdateFollowUpReqBO) { + customerMapper.updateById(BeanUtils.toBean(customerUpdateFollowUpReqBO, CrmCustomerDO.class).setId(customerUpdateFollowUpReqBO.getBizId())); } // ==================== 公海相关操作 ==================== diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/bo/CrmCustomerUpdateFollowUpReqBO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/bo/CrmCustomerUpdateFollowUpReqBO.java deleted file mode 100644 index 2ba7fbb05..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/customer/bo/CrmCustomerUpdateFollowUpReqBO.java +++ /dev/null @@ -1,33 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.customer.bo; - -import com.mzt.logapi.starter.annotation.DiffLogField; -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Data; - -import java.time.LocalDateTime; - -// TODO @puhui999:是不是搞个通用的 ReqBO 就好了 -/** - * 跟进信息 Update Req BO - * - * @author HUIHUI - */ -@Data -public class CrmCustomerUpdateFollowUpReqBO { - - @Schema(description = "主键", example = "3167") - private Long id; - - @Schema(description = "最后跟进时间") - @DiffLogField(name = "最后跟进时间") - private LocalDateTime contactLastTime; - - @Schema(description = "下次联系时间") - @DiffLogField(name = "下次联系时间") - private LocalDateTime contactNextTime; - - @Schema(description = "最后更进内容") - @DiffLogField(name = "最后更进内容") - private String contactLastContent; - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java index f1c98e7d7..d812ce048 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java @@ -9,19 +9,22 @@ import cn.iocoder.yudao.module.crm.controller.admin.followup.vo.CrmFollowUpRecor import cn.iocoder.yudao.module.crm.dal.dataobject.followup.CrmFollowUpRecordDO; import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO; import cn.iocoder.yudao.module.crm.dal.mysql.followup.CrmFollowUpRecordMapper; +import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; 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.CrmBusinessService; -import cn.iocoder.yudao.module.crm.service.business.bo.CrmBusinessUpdateFollowUpReqBO; +import cn.iocoder.yudao.module.crm.service.clue.CrmClueService; import cn.iocoder.yudao.module.crm.service.contact.CrmContactService; -import cn.iocoder.yudao.module.crm.service.contact.bo.CrmContactUpdateFollowUpReqBO; -import cn.iocoder.yudao.module.crm.service.followup.handle.CrmFollowUpHandler; +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 jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import java.time.LocalDateTime; +import java.util.Collections; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -45,11 +48,15 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService { @Resource private CrmPermissionService permissionService; @Resource - private List followUpHandlers; - @Resource private CrmBusinessService businessService; @Resource + private CrmClueService clueService; + @Resource private CrmContactService contactService; + @Resource + private CrmContractService contractService; + @Resource + private CrmCustomerService customerService; @Override @CrmPermission(bizTypeValue = "#createReqVO.bizType", bizId = "#createReqVO.bizId", level = CrmPermissionLevelEnum.WRITE) @@ -60,29 +67,88 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService { LocalDateTime now = LocalDateTime.now(); // 2. 更新 bizId 对应的记录; - followUpHandlers.forEach(handler -> handler.execute(followUpRecord, now)); + updateBizTypeFollowUp(followUpRecord, now); // 3.1 更新 contactIds 对应的记录 if (CollUtil.isNotEmpty(createReqVO.getContactIds())) { - // TODO @puhui999:可以用链式设置哈 - contactService.updateContactFollowUpBatch(convertList(createReqVO.getContactIds(), contactId -> { - CrmContactUpdateFollowUpReqBO crmContactUpdateFollowUpReqBO = new CrmContactUpdateFollowUpReqBO(); - crmContactUpdateFollowUpReqBO.setId(contactId).setContactNextTime(followUpRecord.getNextTime()) - .setContactLastTime(now).setContactLastContent(followUpRecord.getContent()); - return crmContactUpdateFollowUpReqBO; - })); + contactService.updateContactFollowUpBatch(convertList(createReqVO.getContactIds(), contactId -> + new CrmUpdateFollowUpReqBO().setBizId(contactId).setContactNextTime(followUpRecord.getNextTime()) + .setContactLastTime(now).setContactLastContent(followUpRecord.getContent()))); } // 3.2 需要更新 businessIds、contactIds 对应的记录 if (CollUtil.isNotEmpty(createReqVO.getBusinessIds())) { - businessService.updateContactFollowUpBatch(convertList(createReqVO.getBusinessIds(), businessId -> { - CrmBusinessUpdateFollowUpReqBO crmBusinessUpdateFollowUpReqBO = new CrmBusinessUpdateFollowUpReqBO(); - crmBusinessUpdateFollowUpReqBO.setId(businessId).setContactNextTime(followUpRecord.getNextTime()) - .setContactLastTime(now).setContactLastContent(followUpRecord.getContent()); - return crmBusinessUpdateFollowUpReqBO; - })); + businessService.updateBusinessFollowUpBatch(convertList(createReqVO.getBusinessIds(), businessId -> + new CrmUpdateFollowUpReqBO().setBizId(businessId).setContactNextTime(followUpRecord.getNextTime()) + .setContactLastTime(now).setContactLastContent(followUpRecord.getContent()))); } return followUpRecord.getId(); } + /** + * 执行更新 + * + * @param followUpRecord 跟进记录 + * @param now 跟进时间 + */ + private void updateBizTypeFollowUp(CrmFollowUpRecordDO followUpRecord, LocalDateTime now) { + updateBusinessFollowUp(followUpRecord, now); + updateClueFollowUp(followUpRecord, now); + updateContactFollowUp(followUpRecord, now); + updateContractFollowUp(followUpRecord, now); + updateCustomerFollowUp(followUpRecord, now); + } + + private void updateBusinessFollowUp(CrmFollowUpRecordDO followUpRecord, LocalDateTime now) { + if (ObjUtil.notEqual(CrmBizTypeEnum.CRM_BUSINESS.getType(), followUpRecord.getBizType())) { + return; + } + + // 更新商机跟进信息 + businessService.updateBusinessFollowUpBatch(Collections.singletonList(new CrmUpdateFollowUpReqBO() + .setBizId(followUpRecord.getBizId()).setContactNextTime(followUpRecord.getNextTime()).setContactLastTime(now) + .setContactLastContent(followUpRecord.getContent()))); + } + + private void updateClueFollowUp(CrmFollowUpRecordDO followUpRecord, LocalDateTime now) { + if (ObjUtil.notEqual(CrmBizTypeEnum.CRM_LEADS.getType(), followUpRecord.getBizType())) { + return; + } + + // 更新线索跟进信息 + clueService.updateClueFollowUp(new CrmUpdateFollowUpReqBO().setBizId(followUpRecord.getBizId()).setContactLastTime(now) + .setContactNextTime(followUpRecord.getNextTime()).setContactLastContent(followUpRecord.getContent())); + } + + private void updateContactFollowUp(CrmFollowUpRecordDO followUpRecord, LocalDateTime now) { + if (ObjUtil.notEqual(CrmBizTypeEnum.CRM_CONTACT.getType(), followUpRecord.getBizType())) { + return; + } + + // 更新联系人跟进信息 + contactService.updateContactFollowUpBatch(Collections.singletonList(new CrmUpdateFollowUpReqBO() + .setBizId(followUpRecord.getBizId()).setContactNextTime(followUpRecord.getNextTime()).setContactLastTime(now) + .setContactLastContent(followUpRecord.getContent()))); + } + + private void updateContractFollowUp(CrmFollowUpRecordDO followUpRecord, LocalDateTime now) { + if (ObjUtil.notEqual(CrmBizTypeEnum.CRM_CONTRACT.getType(), followUpRecord.getBizType())) { + return; + } + + // 更新合同跟进信息 + contractService.updateContractFollowUp(new CrmUpdateFollowUpReqBO().setBizId(followUpRecord.getBizId()).setContactLastTime(now) + .setContactNextTime(followUpRecord.getNextTime()).setContactLastContent(followUpRecord.getContent())); + } + + private void updateCustomerFollowUp(CrmFollowUpRecordDO followUpRecord, LocalDateTime now) { + if (ObjUtil.notEqual(CrmBizTypeEnum.CRM_CUSTOMER.getType(), followUpRecord.getBizType())) { + return; + } + + // 更新客户跟进信息 + customerService.updateCustomerFollowUp(new CrmUpdateFollowUpReqBO().setBizId(followUpRecord.getBizId()).setContactLastTime(now) + .setContactNextTime(followUpRecord.getNextTime()).setContactLastContent(followUpRecord.getContent())); + } + @Override public void deleteFollowUpRecord(Long id, Long userId) { // 校验存在 diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/bo/CrmClueUpdateFollowUpReqBO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/bo/CrmUpdateFollowUpReqBO.java similarity index 67% rename from yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/bo/CrmClueUpdateFollowUpReqBO.java rename to yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/bo/CrmUpdateFollowUpReqBO.java index d4697acc2..6ddf71c7d 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/bo/CrmClueUpdateFollowUpReqBO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/bo/CrmUpdateFollowUpReqBO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.crm.service.clue.bo; +package cn.iocoder.yudao.module.crm.service.followup.bo; import com.mzt.logapi.starter.annotation.DiffLogField; import io.swagger.v3.oas.annotations.media.Schema; @@ -7,18 +7,18 @@ import lombok.Data; import java.time.LocalDateTime; -// TODO @puhui999:是不是搞个通用的 ReqBO 就好了 + /** - * 线索跟进信息 Update Req BO + * 跟进信息 Update Req BO * * @author HUIHUI */ @Data -public class CrmClueUpdateFollowUpReqBO { +public class CrmUpdateFollowUpReqBO { - @Schema(description = "线索编号", example = "3167") - @NotNull(message = "线索编号不能为空") - private Long id; + @Schema(description = "数据编号", example = "3167") + @NotNull(message = "数据编号不能为空") + private Long bizId; @Schema(description = "最后跟进时间") @DiffLogField(name = "最后跟进时间") @@ -27,7 +27,6 @@ public class CrmClueUpdateFollowUpReqBO { @Schema(description = "下次联系时间") @DiffLogField(name = "下次联系时间") - @NotNull(message = "下次联系时间不能为空") private LocalDateTime contactNextTime; @Schema(description = "最后更进内容") diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmBusinessFollowUpHandler.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmBusinessFollowUpHandler.java deleted file mode 100644 index ffba7fb7e..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmBusinessFollowUpHandler.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.followup.handle; - -import cn.hutool.core.util.ObjUtil; -import cn.iocoder.yudao.module.crm.dal.dataobject.followup.CrmFollowUpRecordDO; -import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; -import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService; -import cn.iocoder.yudao.module.crm.service.business.bo.CrmBusinessUpdateFollowUpReqBO; -import jakarta.annotation.Resource; -import org.springframework.stereotype.Component; - -import java.time.LocalDateTime; -import java.util.Collections; - -/** - * CRM 商机的 {@link CrmFollowUpHandler} 实现类 - * - * @author HUIHUI - */ -@Component -public class CrmBusinessFollowUpHandler implements CrmFollowUpHandler { - - @Resource - private CrmBusinessService businessService; - - @Override - public void execute(CrmFollowUpRecordDO followUpRecord, LocalDateTime now) { - if (ObjUtil.notEqual(CrmBizTypeEnum.CRM_BUSINESS.getType(), followUpRecord.getBizType())) { - return; - } - - // 更新商机跟进信息 - CrmBusinessUpdateFollowUpReqBO businessUpdateFollowUpReqBO = new CrmBusinessUpdateFollowUpReqBO(); - businessUpdateFollowUpReqBO.setId(followUpRecord.getBizId()).setContactNextTime(followUpRecord.getNextTime()) - .setContactLastTime(now).setContactLastContent(followUpRecord.getContent()); - businessService.updateContactFollowUpBatch(Collections.singletonList(businessUpdateFollowUpReqBO)); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmClueFollowUpHandler.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmClueFollowUpHandler.java deleted file mode 100644 index ade2b2aaa..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmClueFollowUpHandler.java +++ /dev/null @@ -1,37 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.followup.handle; - -import cn.hutool.core.util.ObjUtil; -import cn.iocoder.yudao.module.crm.dal.dataobject.followup.CrmFollowUpRecordDO; -import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; -import cn.iocoder.yudao.module.crm.service.clue.CrmClueService; -import cn.iocoder.yudao.module.crm.service.clue.bo.CrmClueUpdateFollowUpReqBO; -import jakarta.annotation.Resource; -import org.springframework.stereotype.Component; - -import java.time.LocalDateTime; - -/** - * CRM 线索的 {@link CrmFollowUpHandler} 实现类 - * - * @author HUIHUI - */ -@Component -public class CrmClueFollowUpHandler implements CrmFollowUpHandler { - - @Resource - private CrmClueService clueService; - - @Override - public void execute(CrmFollowUpRecordDO followUpRecord, LocalDateTime now) { - if (ObjUtil.notEqual(CrmBizTypeEnum.CRM_LEADS.getType(), followUpRecord.getBizType())) { - return; - } - - // 更新线索跟进信息 - CrmClueUpdateFollowUpReqBO clueUpdateFollowUpReqBO = new CrmClueUpdateFollowUpReqBO(); - clueUpdateFollowUpReqBO.setId(followUpRecord.getBizId()).setContactNextTime(followUpRecord.getNextTime()) - .setContactLastTime(now).setContactLastContent(followUpRecord.getContent()); - clueService.updateClueFollowUp(clueUpdateFollowUpReqBO); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmContactFollowUpHandler.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmContactFollowUpHandler.java deleted file mode 100644 index f38942111..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmContactFollowUpHandler.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.followup.handle; - -import cn.hutool.core.util.ObjUtil; -import cn.iocoder.yudao.module.crm.dal.dataobject.followup.CrmFollowUpRecordDO; -import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; -import cn.iocoder.yudao.module.crm.service.contact.CrmContactService; -import cn.iocoder.yudao.module.crm.service.contact.bo.CrmContactUpdateFollowUpReqBO; -import jakarta.annotation.Resource; -import org.springframework.stereotype.Component; - -import java.time.LocalDateTime; -import java.util.Collections; - -/** - * CRM 联系人的 {@link CrmFollowUpHandler} 实现类 - * - * @author HUIHUI - */ -@Component -public class CrmContactFollowUpHandler implements CrmFollowUpHandler { - - @Resource - private CrmContactService contactService; - - @Override - public void execute(CrmFollowUpRecordDO followUpRecord, LocalDateTime now) { - if (ObjUtil.notEqual(CrmBizTypeEnum.CRM_CONTACT.getType(), followUpRecord.getBizType())) { - return; - } - - // 更新联系人跟进信息 - CrmContactUpdateFollowUpReqBO contactUpdateFollowUpReqBO = new CrmContactUpdateFollowUpReqBO(); - contactUpdateFollowUpReqBO.setId(followUpRecord.getBizId()).setContactNextTime(followUpRecord.getNextTime()) - .setContactLastTime(now).setContactLastContent(followUpRecord.getContent()); - contactService.updateContactFollowUpBatch(Collections.singletonList(contactUpdateFollowUpReqBO)); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmContractFollowUpHandler.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmContractFollowUpHandler.java deleted file mode 100644 index 269015fd0..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmContractFollowUpHandler.java +++ /dev/null @@ -1,37 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.followup.handle; - -import cn.hutool.core.util.ObjUtil; -import cn.iocoder.yudao.module.crm.dal.dataobject.followup.CrmFollowUpRecordDO; -import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; -import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; -import cn.iocoder.yudao.module.crm.service.contract.bo.CrmContractUpdateFollowUpReqBO; -import jakarta.annotation.Resource; -import org.springframework.stereotype.Component; - -import java.time.LocalDateTime; - -/** - * CRM 合同的 {@link CrmFollowUpHandler} 实现类 - * - * @author HUIHUI - */ -@Component -public class CrmContractFollowUpHandler implements CrmFollowUpHandler { - - @Resource - private CrmContractService contractService; - - @Override - public void execute(CrmFollowUpRecordDO followUpRecord, LocalDateTime now) { - if (ObjUtil.notEqual(CrmBizTypeEnum.CRM_CONTRACT.getType(), followUpRecord.getBizType())) { - return; - } - - // 更新合同跟进信息 - CrmContractUpdateFollowUpReqBO contractUpdateFollowUpReqBO = new CrmContractUpdateFollowUpReqBO(); - contractUpdateFollowUpReqBO.setId(followUpRecord.getBizId()).setContactNextTime(followUpRecord.getNextTime()) - .setContactLastTime(now).setContactLastContent(followUpRecord.getContent()); - contractService.updateContractFollowUp(contractUpdateFollowUpReqBO); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmCustomerFollowUpHandler.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmCustomerFollowUpHandler.java deleted file mode 100644 index 0e0931555..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmCustomerFollowUpHandler.java +++ /dev/null @@ -1,37 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.followup.handle; - -import cn.hutool.core.util.ObjUtil; -import cn.iocoder.yudao.module.crm.dal.dataobject.followup.CrmFollowUpRecordDO; -import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum; -import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; -import cn.iocoder.yudao.module.crm.service.customer.bo.CrmCustomerUpdateFollowUpReqBO; -import jakarta.annotation.Resource; -import org.springframework.stereotype.Component; - -import java.time.LocalDateTime; - -/** - * CRM 客户的 {@link CrmFollowUpHandler} 实现类 - * - * @author HUIHUI - */ -@Component -public class CrmCustomerFollowUpHandler implements CrmFollowUpHandler { - - @Resource - private CrmCustomerService customerService; - - @Override - public void execute(CrmFollowUpRecordDO followUpRecord, LocalDateTime now) { - if (ObjUtil.notEqual(CrmBizTypeEnum.CRM_CUSTOMER.getType(), followUpRecord.getBizType())) { - return; - } - - // 更新客户跟进信息 - CrmCustomerUpdateFollowUpReqBO customerUpdateFollowUpReqBO = new CrmCustomerUpdateFollowUpReqBO(); - customerUpdateFollowUpReqBO.setId(followUpRecord.getBizId()).setContactNextTime(followUpRecord.getNextTime()) - .setContactLastTime(now).setContactLastContent(followUpRecord.getContent()); - customerService.updateCustomerFollowUp(customerUpdateFollowUpReqBO); - } - -} diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmFollowUpHandler.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmFollowUpHandler.java deleted file mode 100644 index 82bcec835..000000000 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/handle/CrmFollowUpHandler.java +++ /dev/null @@ -1,23 +0,0 @@ -package cn.iocoder.yudao.module.crm.service.followup.handle; - -import cn.iocoder.yudao.module.crm.dal.dataobject.followup.CrmFollowUpRecordDO; - -import java.time.LocalDateTime; - -/** - * CRM 跟进信息处理器 handler 接口 - * - * @author HUIHUI - */ -public interface CrmFollowUpHandler { - - // TODO @puhui999:需要考虑,下次联系时间为空; - /** - * 执行更新 - * - * @param followUpRecord 跟进记录 - * @param now 跟进时间 - */ - void execute(CrmFollowUpRecordDO followUpRecord, LocalDateTime now); - -} diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java index 7a3a3c011..27cb92637 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java @@ -1,9 +1,11 @@ package cn.iocoder.yudao.module.product.convert.comment; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentCreateReqVO; +import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; @@ -59,4 +61,6 @@ public interface ProductCommentConvert { return divide.intValue(); } + PageResult convertPage(PageResult productCommentDOPageResult); + } diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java index 83ec2c456..50ff0af56 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java @@ -9,20 +9,19 @@ import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommen import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; -import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentStatisticsRespVO; import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper; import cn.iocoder.yudao.module.product.enums.comment.ProductCommentScoresEnum; import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; +import jakarta.annotation.Resource; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Lazy; -import jakarta.annotation.Resource; import java.time.LocalDateTime; import java.util.Date; @@ -148,10 +147,10 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { assertEquals(2, result3.getTotal()); // 测试分页 tab count - AppCommentStatisticsRespVO tabsCount = productCommentService.getCommentStatistics(spuId, Boolean.TRUE); - assertEquals(4, tabsCount.getGoodCount()); - assertEquals(2, tabsCount.getMediocreCount()); - assertEquals(0, tabsCount.getNegativeCount()); + //AppCommentStatisticsRespVO tabsCount = productCommentService.getCommentStatistics(spuId, Boolean.TRUE); + //assertEquals(4, tabsCount.getGoodCount()); + //assertEquals(2, tabsCount.getMediocreCount()); + //assertEquals(0, tabsCount.getNegativeCount()); } From 4ce9271ecedf39e1f06e0213bd8bfb4c396b0c2c Mon Sep 17 00:00:00 2001 From: min Date: Sat, 20 Jan 2024 15:08:45 +0800 Subject: [PATCH 23/27] =?UTF-8?q?CRM=EF=BC=9A=E3=80=90=E7=BA=BF=E7=B4=A2?= =?UTF-8?q?=E3=80=91=E5=88=9B=E5=BB=BA=E3=80=81=E5=88=A0=E9=99=A4=E7=BA=BF?= =?UTF-8?q?=E7=B4=A2=E6=97=B6=E5=90=8C=E6=97=B6=E5=88=9B=E5=BB=BA=E3=80=81?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=95=B0=E6=8D=AE=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../crm/service/clue/CrmClueServiceImpl.java | 42 ++++++++++++++----- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java index 506424697..d311be78e 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java @@ -21,16 +21,21 @@ import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPerm import cn.iocoder.yudao.module.crm.service.clue.bo.CrmClueUpdateFollowUpReqBO; import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; 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 jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; -import java.util.*; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +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.convertSet; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS; @@ -56,15 +61,24 @@ public class CrmClueServiceImpl implements CrmClueService { private AdminUserApi adminUserApi; @Override - // TODO @min:补充相关几个方法的操作日志; + @Transactional(rollbackFor = Exception.class) public Long createClue(CrmClueSaveReqVO createReqVO) { - // 校验关联数据 + // 1. 校验关联数据 validateRelationDataExists(createReqVO); - // 插入 + // 2. 插入 CrmClueDO clue = BeanUtils.toBean(createReqVO, CrmClueDO.class); clueMapper.insert(clue); - // 返回 + + // 3. 创建数据权限 + CrmPermissionCreateReqBO createReqBO = new CrmPermissionCreateReqBO() + .setBizType(CrmBizTypeEnum.CRM_LEADS.getType()) + .setBizId(clue.getId()) + // 设置当前操作的人为负责人 + .setUserId(getLoginUserId()) + .setLevel(CrmPermissionLevelEnum.OWNER.getLevel()); + crmPermissionService.createPermission(createReqBO); + return clue.getId(); } @@ -87,20 +101,26 @@ public class CrmClueServiceImpl implements CrmClueService { } @Override + @Transactional(rollbackFor = Exception.class) @CrmPermission(bizType = CrmBizTypeEnum.CRM_LEADS, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) public void deleteClue(Long id) { - // 校验存在 - validateClueExists(id); - // 删除 + // 1. 校验存在 + CrmClueDO clue = validateClueExists(id); + + // 2. 删除 clueMapper.deleteById(id); - // 删除数据权限 + + // 3. 删除数据权限 crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_LEADS.getType(), id); + } - private void validateClueExists(Long id) { - if (clueMapper.selectById(id) == null) { + private CrmClueDO validateClueExists(Long id) { + CrmClueDO crmClueDO = clueMapper.selectById(id); + if (crmClueDO == null) { throw exception(CLUE_NOT_EXISTS); } + return crmClueDO; } @Override From 604611e1d2c3035db1457e11c7749571b1b91f33 Mon Sep 17 00:00:00 2001 From: min Date: Sat, 20 Jan 2024 15:38:55 +0800 Subject: [PATCH 24/27] =?UTF-8?q?CRM=EF=BC=9A=E3=80=90=E7=BA=BF=E7=B4=A2?= =?UTF-8?q?=E3=80=91=E8=A1=A5=E5=85=85=E7=9B=B8=E5=85=B3=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/crm/enums/LogRecordConstants.java | 6 ++++ .../crm/service/clue/CrmClueServiceImpl.java | 31 ++++++++++++++++--- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java index 223994725..198886e68 100644 --- a/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java +++ b/yudao-module-crm/yudao-module-crm-api/src/main/java/cn/iocoder/yudao/module/crm/enums/LogRecordConstants.java @@ -11,6 +11,12 @@ public interface LogRecordConstants { // ======================= CRM_LEADS 线索 ======================= String CRM_LEADS_TYPE = "CRM 线索"; + String CRM_LEADS_CREATE_SUB_TYPE = "创建线索"; + String CRM_LEADS_CREATE_SUCCESS = "创建了线索{{#clue.name}}"; + String CRM_LEADS_UPDATE_SUB_TYPE = "更新线索"; + String CRM_LEADS_UPDATE_SUCCESS = "更新了线索【{{#clueName}}】: {_DIFF{#updateReqVO}}"; + String CRM_LEADS_DELETE_SUB_TYPE = "删除线索"; + String CRM_LEADS_DELETE_SUCCESS = "删除了线索【{{#clueName}}】"; // ======================= CRM_CUSTOMER 客户 ======================= diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java index d311be78e..0d2be4ba9 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.crm.service.clue; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -23,6 +24,9 @@ import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; 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.mzt.logapi.context.LogRecordContext; +import com.mzt.logapi.service.impl.DiffParseFunction; +import com.mzt.logapi.starter.annotation.LogRecord; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -37,6 +41,7 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS; /** @@ -62,6 +67,9 @@ public class CrmClueServiceImpl implements CrmClueService { @Override @Transactional(rollbackFor = Exception.class) + @LogRecord(type = CRM_LEADS_TYPE, subType = CRM_LEADS_CREATE_SUB_TYPE, bizNo = "{{#clue.id}}", + success = CRM_LEADS_CREATE_SUCCESS) + // TODO @min:补充相关几个方法的操作日志; public Long createClue(CrmClueSaveReqVO createReqVO) { // 1. 校验关联数据 validateRelationDataExists(createReqVO); @@ -79,20 +87,31 @@ public class CrmClueServiceImpl implements CrmClueService { .setLevel(CrmPermissionLevelEnum.OWNER.getLevel()); crmPermissionService.createPermission(createReqBO); + // 4. 记录操作日志上下文 + LogRecordContext.putVariable("clue", clue); return clue.getId(); } @Override + @Transactional(rollbackFor = Exception.class) + @LogRecord(type = CRM_LEADS_TYPE, subType = CRM_LEADS_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}", + success = CRM_LEADS_UPDATE_SUCCESS) @CrmPermission(bizType = CrmBizTypeEnum.CRM_LEADS, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE) public void updateClue(CrmClueSaveReqVO updateReqVO) { - // 校验线索是否存在 - validateClueExists(updateReqVO.getId()); - // 校验关联数据 + Assert.notNull(updateReqVO.getId(), "线索编号不能为空"); + // 1. 校验线索是否存在 + CrmClueDO oldClue = validateClueExists(updateReqVO.getId()); + // 2. 校验关联数据 validateRelationDataExists(updateReqVO); - // 更新 + // 3. 更新 CrmClueDO updateObj = BeanUtils.toBean(updateReqVO, CrmClueDO.class); clueMapper.updateById(updateObj); + + // 3. 记录操作日志上下文 + LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldClue, CrmCustomerSaveReqVO.class)); + LogRecordContext.putVariable("clueName", oldClue.getName()); + } @Override @@ -102,6 +121,8 @@ public class CrmClueServiceImpl implements CrmClueService { @Override @Transactional(rollbackFor = Exception.class) + @LogRecord(type = CRM_LEADS_TYPE, subType = CRM_LEADS_DELETE_SUB_TYPE, bizNo = "{{#id}}", + success = CRM_LEADS_DELETE_SUCCESS) @CrmPermission(bizType = CrmBizTypeEnum.CRM_LEADS, bizId = "#id", level = CrmPermissionLevelEnum.OWNER) public void deleteClue(Long id) { // 1. 校验存在 @@ -113,6 +134,8 @@ public class CrmClueServiceImpl implements CrmClueService { // 3. 删除数据权限 crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_LEADS.getType(), id); + // 4. 记录操作日志上下文 + LogRecordContext.putVariable("clueName", clue.getName()); } private CrmClueDO validateClueExists(Long id) { From 16fd1a96392c3f298fbc6ba9459423233749e327 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 20 Jan 2024 18:46:51 +0800 Subject: [PATCH 25/27] =?UTF-8?q?=F0=9F=90=9B=20oracle=20limit=20=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E4=B8=8D=E6=AD=A3=E7=A1=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yudao/framework/mybatis/core/query/QueryWrapperX.java | 2 +- .../system/controller/admin/notice/vo/NoticeSaveReqVO.java | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/QueryWrapperX.java b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/QueryWrapperX.java index 9661b7363..eec4172f1 100644 --- a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/QueryWrapperX.java +++ b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/QueryWrapperX.java @@ -151,7 +151,7 @@ public class QueryWrapperX extends QueryWrapper { switch (SqlConstants.DB_TYPE) { case ORACLE: case ORACLE_12C: - super.eq("ROWNUM", n); + super.le("ROWNUM", n); break; case SQL_SERVER: case SQL_SERVER2005: diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeSaveReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeSaveReqVO.java index d3d3e61ce..78794ed71 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeSaveReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notice/vo/NoticeSaveReqVO.java @@ -11,8 +11,7 @@ import jakarta.validation.constraints.Size; @Data public class NoticeSaveReqVO { - @Schema(description = "岗位公告编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - @NotNull(message = "岗位公告编号不能为空") + @Schema(description = "岗位公告编号", example = "1024") private Long id; @Schema(description = "公告标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "小博主") From 39ae547b9d9730e9dcd9960a7a426bf87fc44b15 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 20 Jan 2024 18:55:28 +0800 Subject: [PATCH 26/27] =?UTF-8?q?=F0=9F=93=96=20CRM=EF=BC=9Acode=20review?= =?UTF-8?q?=20=E7=BA=BF=E7=B4=A2=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../crm/service/clue/CrmClueServiceImpl.java | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java index 0d2be4ba9..0185c3206 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/clue/CrmClueServiceImpl.java @@ -69,7 +69,6 @@ public class CrmClueServiceImpl implements CrmClueService { @Transactional(rollbackFor = Exception.class) @LogRecord(type = CRM_LEADS_TYPE, subType = CRM_LEADS_CREATE_SUB_TYPE, bizNo = "{{#clue.id}}", success = CRM_LEADS_CREATE_SUCCESS) - // TODO @min:补充相关几个方法的操作日志; public Long createClue(CrmClueSaveReqVO createReqVO) { // 1. 校验关联数据 validateRelationDataExists(createReqVO); @@ -111,7 +110,6 @@ public class CrmClueServiceImpl implements CrmClueService { // 3. 记录操作日志上下文 LogRecordContext.putVariable(DiffParseFunction.OLD_OBJECT, BeanUtils.toBean(oldClue, CrmCustomerSaveReqVO.class)); LogRecordContext.putVariable("clueName", oldClue.getName()); - } @Override @@ -189,23 +187,21 @@ public class CrmClueServiceImpl implements CrmClueService { throw exception(CLUE_ANY_CLUE_NOT_EXISTS, StrUtil.join(",", clueIds)); } - // 过滤出未转化的客户 - List unTransformClues = CollectionUtils.filterList(clues, - clue -> ObjectUtil.notEqual(Boolean.TRUE, clue.getTransformStatus())); // 存在已经转化的,直接提示哈。避免操作的用户,以为都转化成功了 - if (ObjectUtil.notEqual(clues.size(), unTransformClues.size())) { - clueIds.removeAll(convertSet(unTransformClues, CrmClueDO::getId)); - throw exception(CLUE_ANY_CLUE_ALREADY_TRANSLATED, StrUtil.join(",", clueIds)); + List translatedClues = CollectionUtils.filterList(clues, + clue -> ObjectUtil.equal(Boolean.TRUE, clue.getTransformStatus())); + if (CollUtil.isNotEmpty(translatedClues)) { + throw exception(CLUE_ANY_CLUE_ALREADY_TRANSLATED, StrUtil.join(",", convertSet(translatedClues, CrmClueDO::getId))); } // 遍历线索(未转化的线索),创建对应的客户 - unTransformClues.forEach(clue -> { + reqVO.getIds().forEach(id -> { // 1. 创建客户 - CrmCustomerSaveReqVO customerSaveReqVO = BeanUtils.toBean(clue, CrmCustomerSaveReqVO.class).setId(null); + CrmCustomerSaveReqVO customerSaveReqVO = BeanUtils.toBean(id, CrmCustomerSaveReqVO.class).setId(null); Long customerId = customerService.createCustomer(customerSaveReqVO, userId); // TODO @puhui999:如果有跟进记录,需要一起转过去;提问:艿艿这里是复制线索所有的跟进吗?还是直接把线索相关的跟进 bizType、bizId 全改为关联客户? // 2. 更新线索 - clueMapper.updateById(new CrmClueDO().setId(clue.getId()) + clueMapper.updateById(new CrmClueDO().setId(id) .setTransformStatus(Boolean.TRUE).setCustomerId(customerId)); }); } From c6c8dddfec8d6266630f4800e41771901e582f28 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 20 Jan 2024 19:05:16 +0800 Subject: [PATCH 27/27] =?UTF-8?q?=F0=9F=93=96=20CRM=EF=BC=9Acode=20review?= =?UTF-8?q?=20=E8=B7=9F=E8=BF=9B=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module/crm/convert/business/CrmBusinessConvert.java | 4 ++-- .../yudao/module/crm/convert/contact/CrmContactConvert.java | 4 ++-- .../crm/service/followup/CrmFollowUpRecordServiceImpl.java | 1 + .../crm/service/followup/bo/CrmUpdateFollowUpReqBO.java | 1 - .../product/convert/comment/ProductCommentConvert.java | 4 ---- .../service/comment/ProductCommentServiceImplTest.java | 5 +++-- 6 files changed, 8 insertions(+), 11 deletions(-) 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 56bba541e..d7f990043 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 @@ -50,8 +50,8 @@ public interface CrmBusinessConvert { @Mapping(target = "id", source = "reqBO.bizId") CrmBusinessDO convert(CrmUpdateFollowUpReqBO reqBO); - default List convertList(List updateFollowUpReqBOList) { - return CollectionUtils.convertList(updateFollowUpReqBOList, INSTANCE::convert); + default List convertList(List list) { + return CollectionUtils.convertList(list, INSTANCE::convert); } } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/CrmContactConvert.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/CrmContactConvert.java index 1d32331bb..5fd2afa67 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/CrmContactConvert.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/convert/contact/CrmContactConvert.java @@ -70,8 +70,8 @@ public interface CrmContactConvert { @Mapping(target = "id", source = "reqBO.bizId") CrmContactDO convert(CrmUpdateFollowUpReqBO reqBO); - default List convertList(List updateFollowUpReqBOList) { - return CollectionUtils.convertList(updateFollowUpReqBOList, INSTANCE::convert); + default List convertList(List list) { + return CollectionUtils.convertList(list, INSTANCE::convert); } } diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java index d812ce048..a2da1ee3e 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/CrmFollowUpRecordServiceImpl.java @@ -66,6 +66,7 @@ public class CrmFollowUpRecordServiceImpl implements CrmFollowUpRecordService { crmFollowUpRecordMapper.insert(followUpRecord); LocalDateTime now = LocalDateTime.now(); + // TODO @puhui999:感觉可以这里基于 type 做 102 到 104 这种判断;然后,每个类型的调用封装一个小方法,之后调用这些小方法;再之后,74-76、80-82 也是等价的处理; // 2. 更新 bizId 对应的记录; updateBizTypeFollowUp(followUpRecord, now); // 3.1 更新 contactIds 对应的记录 diff --git a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/bo/CrmUpdateFollowUpReqBO.java b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/bo/CrmUpdateFollowUpReqBO.java index 6ddf71c7d..74e789436 100644 --- a/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/bo/CrmUpdateFollowUpReqBO.java +++ b/yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/followup/bo/CrmUpdateFollowUpReqBO.java @@ -7,7 +7,6 @@ import lombok.Data; import java.time.LocalDateTime; - /** * 跟进信息 Update Req BO * diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java index 27cb92637..7a3a3c011 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/comment/ProductCommentConvert.java @@ -1,11 +1,9 @@ package cn.iocoder.yudao.module.product.convert.comment; -import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentCreateReqVO; -import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; @@ -61,6 +59,4 @@ public interface ProductCommentConvert { return divide.intValue(); } - PageResult convertPage(PageResult productCommentDOPageResult); - } diff --git a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java index 50ff0af56..1b92e21f2 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java +++ b/yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/comment/ProductCommentServiceImplTest.java @@ -3,13 +3,13 @@ package cn.iocoder.yudao.module.product.service.comment; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.RandomUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentPageReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentReplyReqVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentRespVO; import cn.iocoder.yudao.module.product.controller.admin.comment.vo.ProductCommentUpdateVisibleReqVO; import cn.iocoder.yudao.module.product.controller.app.comment.vo.AppCommentPageReqVO; -import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; import cn.iocoder.yudao.module.product.dal.mysql.comment.ProductCommentMapper; import cn.iocoder.yudao.module.product.enums.comment.ProductCommentScoresEnum; @@ -128,7 +128,8 @@ public class ProductCommentServiceImplTest extends BaseDbUnitTest { productCommentPageReqVO.setReplyStatus(Boolean.TRUE); PageResult commentPage = productCommentService.getCommentPage(productCommentPageReqVO); - PageResult result = ProductCommentConvert.INSTANCE.convertPage(productCommentMapper.selectPage(productCommentPageReqVO)); + PageResult result = BeanUtils.toBean(productCommentMapper.selectPage(productCommentPageReqVO), + ProductCommentRespVO.class); assertEquals(result.getTotal(), commentPage.getTotal()); PageResult all = productCommentService.getCommentPage(new ProductCommentPageReqVO());