商机模块
This commit is contained in:
parent
ed34b18d82
commit
f361d05940
55
sql/mysql/optinal/crm_20240114.sql
Normal file
55
sql/mysql/optinal/crm_20240114.sql
Normal file
@ -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;
|
@ -17,6 +17,7 @@ public interface ErrorCodeConstants {
|
|||||||
|
|
||||||
// ========== 商机管理 1-020-002-000 ==========
|
// ========== 商机管理 1-020-002-000 ==========
|
||||||
ErrorCode BUSINESS_NOT_EXISTS = new ErrorCode(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:商机状态、商机类型,都单独错误码段
|
// TODO @lilleo:商机状态、商机类型,都单独错误码段
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -22,6 +22,11 @@
|
|||||||
<artifactId>yudao-module-system-api</artifactId>
|
<artifactId>yudao-module-system-api</artifactId>
|
||||||
<version>${revision}</version>
|
<version>${revision}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.iocoder.boot</groupId>
|
||||||
|
<artifactId>yudao-module-system-biz</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.iocoder.boot</groupId>
|
<groupId>cn.iocoder.boot</groupId>
|
||||||
<artifactId>yudao-module-crm-api</artifactId>
|
<artifactId>yudao-module-crm-api</artifactId>
|
||||||
|
@ -55,14 +55,14 @@ public class CrmBusinessController {
|
|||||||
@PostMapping("/create")
|
@PostMapping("/create")
|
||||||
@Operation(summary = "创建商机")
|
@Operation(summary = "创建商机")
|
||||||
@PreAuthorize("@ss.hasPermission('crm:business:create')")
|
@PreAuthorize("@ss.hasPermission('crm:business:create')")
|
||||||
public CommonResult<Long> createBusiness(@Valid @RequestBody CrmBusinessCreateReqVO createReqVO) {
|
public CommonResult<Long> createBusiness(@Valid @RequestBody CrmBusinessSaveReqVO createReqVO) {
|
||||||
return success(businessService.createBusiness(createReqVO, getLoginUserId()));
|
return success(businessService.createBusiness(createReqVO, getLoginUserId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/update")
|
@PutMapping("/update")
|
||||||
@Operation(summary = "更新商机")
|
@Operation(summary = "更新商机")
|
||||||
@PreAuthorize("@ss.hasPermission('crm:business:update')")
|
@PreAuthorize("@ss.hasPermission('crm:business:update')")
|
||||||
public CommonResult<Boolean> updateBusiness(@Valid @RequestBody CrmBusinessUpdateReqVO updateReqVO) {
|
public CommonResult<Boolean> updateBusiness(@Valid @RequestBody CrmBusinessSaveReqVO updateReqVO) {
|
||||||
businessService.updateBusiness(updateReqVO);
|
businessService.updateBusiness(updateReqVO);
|
||||||
return success(true);
|
return success(true);
|
||||||
}
|
}
|
||||||
|
@ -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.CommonResult;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
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.common.util.object.BeanUtils;
|
||||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||||
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
||||||
@ -101,11 +102,12 @@ public class CrmBusinessStatusTypeController {
|
|||||||
PageResult<CrmBusinessStatusTypeDO> pageResult = businessStatusTypeService.getBusinessStatusTypePage(pageReqVO);
|
PageResult<CrmBusinessStatusTypeDO> pageResult = businessStatusTypeService.getBusinessStatusTypePage(pageReqVO);
|
||||||
// 处理部门回显
|
// 处理部门回显
|
||||||
// TODO @ljlleo:可以使用 CollectionUtils.convertSet 替代常用的 stream 操作,更简洁一点;下面几个也是哈;
|
// TODO @ljlleo:可以使用 CollectionUtils.convertSet 替代常用的 stream 操作,更简洁一点;下面几个也是哈;
|
||||||
Set<Long> deptIds = pageResult.getList().stream()
|
// Set<Long> deptIds = pageResult.getList().stream()
|
||||||
.map(CrmBusinessStatusTypeDO::getDeptIds)
|
// .map(CrmBusinessStatusTypeDO::getDeptIds)
|
||||||
.filter(Objects::nonNull)
|
// .filter(Objects::nonNull)
|
||||||
.flatMap(Collection::stream)
|
// .flatMap(Collection::stream)
|
||||||
.collect(Collectors.toSet());
|
// .collect(Collectors.toSet());
|
||||||
|
Set<Long> deptIds = CollectionUtils.convertSetByFlatMap(pageResult.getList(), CrmBusinessStatusTypeDO::getDeptIds,Collection::stream);
|
||||||
List<DeptRespDTO> deptList = deptApi.getDeptList(deptIds);
|
List<DeptRespDTO> deptList = deptApi.getDeptList(deptIds);
|
||||||
return success(CrmBusinessStatusTypeConvert.INSTANCE.convertPage(pageResult, deptList));
|
return success(CrmBusinessStatusTypeConvert.INSTANCE.convertPage(pageResult, deptList));
|
||||||
}
|
}
|
||||||
|
@ -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<CrmProductSaveReqVO> product = new ArrayList<>();
|
||||||
|
|
||||||
|
}
|
@ -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 {
|
||||||
|
}
|
@ -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 {
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
@ -24,6 +24,6 @@ public class CrmBusinessStatusTypeSaveReqVO {
|
|||||||
|
|
||||||
// TODO @ljlleo VO 里面,我们不使用默认值哈。这里 Lists.newArrayList() 看看怎么去掉。上面 deptIds 也是类似噢
|
// TODO @ljlleo VO 里面,我们不使用默认值哈。这里 Lists.newArrayList() 看看怎么去掉。上面 deptIds 也是类似噢
|
||||||
@Schema(description = "商机状态集合", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "商机状态集合", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private List<CrmBusinessStatusSaveReqVO> statusList = Lists.newArrayList();
|
private List<CrmBusinessStatusSaveReqVO> statusList;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ public interface CrmBusinessConvert {
|
|||||||
|
|
||||||
CrmBusinessConvert INSTANCE = Mappers.getMapper(CrmBusinessConvert.class);
|
CrmBusinessConvert INSTANCE = Mappers.getMapper(CrmBusinessConvert.class);
|
||||||
|
|
||||||
CrmBusinessDO convert(CrmBusinessCreateReqVO bean);
|
CrmBusinessDO convert(CrmBusinessSaveReqVO bean);
|
||||||
|
|
||||||
CrmBusinessDO convert(CrmBusinessUpdateReqVO bean);
|
CrmBusinessDO convert(CrmBusinessUpdateReqVO bean);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
}
|
@ -41,9 +41,9 @@ public interface CrmBusinessStatusTypeConvert {
|
|||||||
|
|
||||||
default CrmBusinessStatusTypeRespVO convert(CrmBusinessStatusTypeDO bean, List<CrmBusinessStatusDO> statusList) {
|
default CrmBusinessStatusTypeRespVO convert(CrmBusinessStatusTypeDO bean, List<CrmBusinessStatusDO> statusList) {
|
||||||
// TODO @ljlleo 可以链式赋值,简化成一行;
|
// TODO @ljlleo 可以链式赋值,简化成一行;
|
||||||
CrmBusinessStatusTypeRespVO result = convert(bean);
|
// CrmBusinessStatusTypeRespVO result = convert(bean);
|
||||||
result.setStatusList(statusList);
|
// result.setStatusList(statusList);
|
||||||
return result;
|
return convert(bean).setStatusList(statusList);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package cn.iocoder.yudao.module.crm.dal.dataobject.business;
|
package cn.iocoder.yudao.module.crm.dal.dataobject.business;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
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.KeySequence;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
@ -52,6 +54,7 @@ public class CrmBusinessDO extends BaseDO {
|
|||||||
* 客户编号
|
* 客户编号
|
||||||
*
|
*
|
||||||
* TODO @ljileo:这个字段,后续要写下关联的实体哈
|
* TODO @ljileo:这个字段,后续要写下关联的实体哈
|
||||||
|
* 关联 {@link CrmCustomerDO#getId()}
|
||||||
*/
|
*/
|
||||||
private Long customerId;
|
private Long customerId;
|
||||||
/**
|
/**
|
||||||
@ -101,6 +104,7 @@ public class CrmBusinessDO extends BaseDO {
|
|||||||
* 负责人的用户编号
|
* 负责人的用户编号
|
||||||
*
|
*
|
||||||
* 关联 AdminUserDO 的 id 字段
|
* 关联 AdminUserDO 的 id 字段
|
||||||
|
* {@link AdminUserDO#getId()}
|
||||||
*/
|
*/
|
||||||
private Long ownerUserId;
|
private Long ownerUserId;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
}
|
@ -39,7 +39,7 @@ public class CrmBusinessStatusDO {
|
|||||||
*
|
*
|
||||||
* TODO 这里是不是改成 Integer 存储,百分比 * 100 ;
|
* TODO 这里是不是改成 Integer 存储,百分比 * 100 ;
|
||||||
*/
|
*/
|
||||||
private String percent;
|
private Integer percent;
|
||||||
/**
|
/**
|
||||||
* 排序
|
* 排序
|
||||||
*/
|
*/
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package cn.iocoder.yudao.module.crm.dal.dataobject.business;
|
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.dataobject.BaseDO;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
|
import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
|
||||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||||
@ -43,6 +44,7 @@ public class CrmBusinessStatusTypeDO extends BaseDO {
|
|||||||
* 开启状态
|
* 开启状态
|
||||||
*
|
*
|
||||||
* TODO 改成 Integer,关联 CommonStatus
|
* TODO 改成 Integer,关联 CommonStatus
|
||||||
|
* {@link CommonStatusEnum}
|
||||||
*/
|
*/
|
||||||
private Boolean status;
|
private Boolean status;
|
||||||
|
|
||||||
|
@ -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<CrmBusinessProductDO> {
|
||||||
|
default void deleteByBusinessId(Long id) {
|
||||||
|
delete(CrmBusinessProductDO::getBusinessId, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
default CrmBusinessProductDO selectByBusinessId(Long id) {
|
||||||
|
return selectOne(CrmBusinessProductDO::getBusinessId, id);
|
||||||
|
}
|
||||||
|
}
|
@ -28,4 +28,15 @@ public interface CrmBusinessStatusTypeMapper extends BaseMapperX<CrmBusinessStat
|
|||||||
.eqIfPresent(CrmBusinessStatusTypeDO::getStatus, queryVO.getStatus())
|
.eqIfPresent(CrmBusinessStatusTypeDO::getStatus, queryVO.getStatus())
|
||||||
.inIfPresent(CrmBusinessStatusTypeDO::getId, queryVO.getIdList()));
|
.inIfPresent(CrmBusinessStatusTypeDO::getId, queryVO.getIdList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID和name查询
|
||||||
|
*
|
||||||
|
* @param id 商机状态类型id
|
||||||
|
* @param name 状态类型名
|
||||||
|
* @return result
|
||||||
|
*/
|
||||||
|
default CrmBusinessStatusTypeDO selectByIdAndName(Long id, String name) {
|
||||||
|
return selectOne(CrmBusinessStatusTypeDO::getId, id, CrmBusinessStatusTypeDO::getName, name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,5 +63,8 @@ public interface CrmContractMapper extends BaseMapperX<CrmContractDO> {
|
|||||||
default Long selectCountByContactId(Long contactId) {
|
default Long selectCountByContactId(Long contactId) {
|
||||||
return selectCount(CrmContractDO::getContactId, contactId);
|
return selectCount(CrmContractDO::getContactId, contactId);
|
||||||
}
|
}
|
||||||
|
default CrmContractDO selectByBizId(Long businessId) {
|
||||||
|
return selectOne(CrmContractDO::getBusinessId, businessId);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
package cn.iocoder.yudao.module.crm.service.business;
|
package cn.iocoder.yudao.module.crm.service.business;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
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.*;
|
||||||
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.dal.dataobject.business.CrmBusinessDO;
|
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.contact.CrmContactDO;
|
||||||
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
|
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
|
||||||
@ -27,14 +24,14 @@ public interface CrmBusinessService {
|
|||||||
* @param userId 用户编号
|
* @param userId 用户编号
|
||||||
* @return 编号
|
* @return 编号
|
||||||
*/
|
*/
|
||||||
Long createBusiness(@Valid CrmBusinessCreateReqVO createReqVO, Long userId);
|
Long createBusiness(@Valid CrmBusinessSaveReqVO createReqVO, Long userId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新商机
|
* 更新商机
|
||||||
*
|
*
|
||||||
* @param updateReqVO 更新信息
|
* @param updateReqVO 更新信息
|
||||||
*/
|
*/
|
||||||
void updateBusiness(@Valid CrmBusinessUpdateReqVO updateReqVO);
|
void updateBusiness(@Valid CrmBusinessSaveReqVO updateReqVO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除商机
|
* 删除商机
|
||||||
|
@ -4,14 +4,18 @@ import cn.hutool.core.collection.CollUtil;
|
|||||||
import cn.hutool.core.collection.ListUtil;
|
import cn.hutool.core.collection.ListUtil;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
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.*;
|
||||||
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO;
|
import cn.iocoder.yudao.module.crm.controller.admin.product.vo.product.CrmProductSaveReqVO;
|
||||||
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.convert.business.CrmBusinessConvert;
|
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.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.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.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.common.CrmBizTypeEnum;
|
||||||
import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
|
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.framework.permission.core.annotations.CrmPermission;
|
||||||
@ -26,11 +30,14 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
import static cn.iocoder.yudao.framework.common.util.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.ErrorCodeConstants.BUSINESS_NOT_EXISTS;
|
||||||
import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*;
|
import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*;
|
||||||
|
|
||||||
@ -46,6 +53,13 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
|
|||||||
@Resource
|
@Resource
|
||||||
private CrmBusinessMapper businessMapper;
|
private CrmBusinessMapper businessMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CrmBusinessProductMapper businessProductMapper;
|
||||||
|
@Resource
|
||||||
|
private CrmContractMapper contractMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CrmContactBusinessMapper contactBusinessMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private CrmPermissionService permissionService;
|
private CrmPermissionService permissionService;
|
||||||
@Resource
|
@Resource
|
||||||
@ -55,29 +69,79 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
|
|||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
@LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_CREATE_SUB_TYPE, bizNo = "{{#business.id}}",
|
@LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_CREATE_SUB_TYPE, bizNo = "{{#business.id}}",
|
||||||
success = CRM_BUSINESS_CREATE_SUCCESS)
|
success = CRM_BUSINESS_CREATE_SUCCESS)
|
||||||
public Long createBusiness(CrmBusinessCreateReqVO createReqVO, Long userId) {
|
public Long createBusiness(CrmBusinessSaveReqVO createReqVO, Long userId) {
|
||||||
// 1. 插入商机
|
// 1. 插入商机
|
||||||
CrmBusinessDO business = CrmBusinessConvert.INSTANCE.convert(createReqVO);
|
CrmBusinessDO business = CrmBusinessConvert.INSTANCE.convert(createReqVO);
|
||||||
businessMapper.insert(business);
|
businessMapper.insert(business);
|
||||||
// TODO 商机待定:插入商机与产品的关联表;校验商品存在
|
// TODO 商机待定:插入商机与产品的关联表;校验商品存在
|
||||||
|
verifyCrmBusinessProduct(business.getId());
|
||||||
|
if (!createReqVO.getProduct().isEmpty()) {
|
||||||
|
createBusinessProducts(createReqVO.getProduct(), business.getId());
|
||||||
|
}
|
||||||
// TODO 商机待定:在联系人的详情页,如果直接【新建商机】,则需要关联下。这里要搞个 CrmContactBusinessDO 表
|
// TODO 商机待定:在联系人的详情页,如果直接【新建商机】,则需要关联下。这里要搞个 CrmContactBusinessDO 表
|
||||||
|
createContactBusiness(business.getId(), createReqVO.getContactId());
|
||||||
|
|
||||||
// 2. 创建数据权限
|
// 2. 创建数据权限
|
||||||
|
// 设置当前操作的人为负责人
|
||||||
permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_BUSINESS.getType())
|
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. 记录操作日志上下文
|
// 4. 记录操作日志上下文
|
||||||
LogRecordContext.putVariable("business", business);
|
LogRecordContext.putVariable("business", business);
|
||||||
return business.getId();
|
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<CrmProductSaveReqVO> products, Long businessId) {
|
||||||
|
List<CrmBusinessProductDO> 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
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
@LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}",
|
@LogRecord(type = CRM_BUSINESS_TYPE, subType = CRM_BUSINESS_UPDATE_SUB_TYPE, bizNo = "{{#updateReqVO.id}}",
|
||||||
success = CRM_BUSINESS_UPDATE_SUCCESS)
|
success = CRM_BUSINESS_UPDATE_SUCCESS)
|
||||||
@CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
|
@CrmPermission(bizType = CrmBizTypeEnum.CRM_BUSINESS, bizId = "#updateReqVO.id", level = CrmPermissionLevelEnum.WRITE)
|
||||||
public void updateBusiness(CrmBusinessUpdateReqVO updateReqVO) {
|
public void updateBusiness(CrmBusinessSaveReqVO updateReqVO) {
|
||||||
// 1. 校验存在
|
// 1. 校验存在
|
||||||
CrmBusinessDO oldBusiness = validateBusinessExists(updateReqVO.getId());
|
CrmBusinessDO oldBusiness = validateBusinessExists(updateReqVO.getId());
|
||||||
|
|
||||||
@ -85,6 +149,10 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
|
|||||||
CrmBusinessDO updateObj = CrmBusinessConvert.INSTANCE.convert(updateReqVO);
|
CrmBusinessDO updateObj = CrmBusinessConvert.INSTANCE.convert(updateReqVO);
|
||||||
businessMapper.updateById(updateObj);
|
businessMapper.updateById(updateObj);
|
||||||
// TODO 商机待定:插入商机与产品的关联表;校验商品存在
|
// TODO 商机待定:插入商机与产品的关联表;校验商品存在
|
||||||
|
verifyCrmBusinessProduct(updateReqVO.getId());
|
||||||
|
if (!updateReqVO.getProduct().isEmpty()) {
|
||||||
|
createBusinessProducts(updateReqVO.getProduct(), updateReqVO.getId());
|
||||||
|
}
|
||||||
|
|
||||||
// TODO @商机待定:如果状态发生变化,插入商机状态变更记录表
|
// TODO @商机待定:如果状态发生变化,插入商机状态变更记录表
|
||||||
// 3. 记录操作日志上下文
|
// 3. 记录操作日志上下文
|
||||||
@ -101,6 +169,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
|
|||||||
// 校验存在
|
// 校验存在
|
||||||
CrmBusinessDO business = validateBusinessExists(id);
|
CrmBusinessDO business = validateBusinessExists(id);
|
||||||
// TODO @商机待定:需要校验有没关联合同。CrmContractDO 的 businessId 字段
|
// TODO @商机待定:需要校验有没关联合同。CrmContractDO 的 businessId 字段
|
||||||
|
validateContractExists(id);
|
||||||
|
|
||||||
// 删除
|
// 删除
|
||||||
businessMapper.deleteById(id);
|
businessMapper.deleteById(id);
|
||||||
@ -111,6 +180,19 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
|
|||||||
LogRecordContext.putVariable("businessName", business.getName());
|
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) {
|
private CrmBusinessDO validateBusinessExists(Long id) {
|
||||||
CrmBusinessDO crmBusiness = businessMapper.selectById(id);
|
CrmBusinessDO crmBusiness = businessMapper.selectById(id);
|
||||||
if (crmBusiness == null) {
|
if (crmBusiness == null) {
|
||||||
|
@ -95,14 +95,18 @@ public class CrmBusinessStatusTypeServiceImpl implements CrmBusinessStatusTypeSe
|
|||||||
|
|
||||||
// TODO @ljlleo 这个方法,这个参考 validateDeptNameUnique 实现。
|
// TODO @ljlleo 这个方法,这个参考 validateDeptNameUnique 实现。
|
||||||
private void validateBusinessStatusTypeExists(String name, Long id) {
|
private void validateBusinessStatusTypeExists(String name, Long id) {
|
||||||
LambdaQueryWrapper<CrmBusinessStatusTypeDO> wrapper = new LambdaQueryWrapperX<>();
|
CrmBusinessStatusTypeDO businessStatusTypeDO = businessStatusTypeMapper.selectByIdAndName(id, name);
|
||||||
if(null != id) {
|
if (businessStatusTypeDO != null) {
|
||||||
wrapper.ne(CrmBusinessStatusTypeDO::getId, id);
|
|
||||||
}
|
|
||||||
long cnt = businessStatusTypeMapper.selectCount(wrapper.eq(CrmBusinessStatusTypeDO::getName, name));
|
|
||||||
if (cnt > 0) {
|
|
||||||
throw exception(BUSINESS_STATUS_TYPE_NAME_EXISTS);
|
throw exception(BUSINESS_STATUS_TYPE_NAME_EXISTS);
|
||||||
}
|
}
|
||||||
|
// LambdaQueryWrapper<CrmBusinessStatusTypeDO> 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
|
@Override
|
||||||
|
@ -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.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.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.controller.admin.business.vo.business.CrmBusinessUpdateReqVO;
|
||||||
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
|
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
|
||||||
import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessMapper;
|
import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessMapper;
|
||||||
@ -39,7 +40,7 @@ public class CrmBusinessServiceImplTest extends BaseDbUnitTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testCreateBusiness_success() {
|
public void testCreateBusiness_success() {
|
||||||
// 准备参数
|
// 准备参数
|
||||||
CrmBusinessCreateReqVO reqVO = randomPojo(CrmBusinessCreateReqVO.class);
|
CrmBusinessSaveReqVO reqVO = randomPojo(CrmBusinessSaveReqVO.class);
|
||||||
|
|
||||||
// 调用
|
// 调用
|
||||||
Long businessId = businessService.createBusiness(reqVO, getLoginUserId());
|
Long businessId = businessService.createBusiness(reqVO, getLoginUserId());
|
||||||
@ -56,7 +57,7 @@ public class CrmBusinessServiceImplTest extends BaseDbUnitTest {
|
|||||||
CrmBusinessDO dbBusiness = randomPojo(CrmBusinessDO.class);
|
CrmBusinessDO dbBusiness = randomPojo(CrmBusinessDO.class);
|
||||||
businessMapper.insert(dbBusiness);// @Sql: 先插入出一条存在的数据
|
businessMapper.insert(dbBusiness);// @Sql: 先插入出一条存在的数据
|
||||||
// 准备参数
|
// 准备参数
|
||||||
CrmBusinessUpdateReqVO reqVO = randomPojo(CrmBusinessUpdateReqVO.class, o -> {
|
CrmBusinessSaveReqVO reqVO = randomPojo(CrmBusinessSaveReqVO.class, o -> {
|
||||||
o.setId(dbBusiness.getId()); // 设置更新的 ID
|
o.setId(dbBusiness.getId()); // 设置更新的 ID
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -70,7 +71,7 @@ public class CrmBusinessServiceImplTest extends BaseDbUnitTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testUpdateBusiness_notExists() {
|
public void testUpdateBusiness_notExists() {
|
||||||
// 准备参数
|
// 准备参数
|
||||||
CrmBusinessUpdateReqVO reqVO = randomPojo(CrmBusinessUpdateReqVO.class);
|
CrmBusinessSaveReqVO reqVO = randomPojo(CrmBusinessSaveReqVO.class);
|
||||||
|
|
||||||
// 调用, 并断言异常
|
// 调用, 并断言异常
|
||||||
assertServiceException(() -> businessService.updateBusiness(reqVO), BUSINESS_NOT_EXISTS);
|
assertServiceException(() -> businessService.updateBusiness(reqVO), BUSINESS_NOT_EXISTS);
|
||||||
|
Loading…
Reference in New Issue
Block a user