Commit 655fc03394ffbcb690256248bb41007995d33c87

Authored by YunaiV
2 parents d732008e 14d2195c

Merge branch 'develop' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into develop

Showing 12 changed files with 167 additions and 52 deletions
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/controller/admin/business/vo/product/CrmBusinessProductSaveReqVO.java
1 1 package cn.iocoder.yudao.module.crm.controller.admin.business.vo.product;
2 2  
3 3 import io.swagger.v3.oas.annotations.media.Schema;
  4 +import jakarta.validation.constraints.NotEmpty;
4 5 import jakarta.validation.constraints.NotNull;
5 6 import lombok.Data;
6 7  
... ... @@ -16,12 +17,12 @@ public class CrmBusinessProductSaveReqVO {
16 17 // TODO @lzxhqs:这个字段,应该是 Long 类型
17 18 @Schema(description = "商机编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320")
18 19 @NotNull(message = "商机编号不能为空")
19   - private Integer businessId;
  20 + private Long businessId;
20 21  
21 22 // TODO @lzxhqs:这个字段,应该是 Long 类型
22 23 @Schema(description = "产品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320")
23 24 @NotNull(message = "产品编号不能为空")
24   - private Integer productId;
  25 + private Long productId;
25 26  
26 27 @Schema(description = "产品单价", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320")
27 28 @NotNull(message = "产品单价不能为空")
... ... @@ -45,7 +46,7 @@ public class CrmBusinessProductSaveReqVO {
45 46  
46 47 // TODO @lzxhqs:字符串,用 @NotEmpty,因为要考虑 "" 前端搞了这个玩意
47 48 @Schema(description = "单位", requiredMode = Schema.RequiredMode.REQUIRED, example = "30320")
48   - @NotNull(message = "单位不能为空")
  49 + @NotEmpty(message = "单位不能为空")
49 50 private String unit;
50 51  
51 52 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessDO.java
... ... @@ -98,7 +98,7 @@ public class CrmBusinessDO extends BaseDO {
98 98 *
99 99 * TODO @lzxhqs:目前就是 Boolean;是否跟进
100 100 */
101   - private Integer followUpStatus;
  101 + private Boolean followUpStatus;
102 102  
103 103 /**
104 104 * 负责人的用户编号
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/dataobject/business/CrmBusinessProductDO.java
... ... @@ -48,7 +48,7 @@ public class CrmBusinessProductDO extends BaseDO {
48 48 /**
49 49 * 产品单价
50 50 */
51   - private BigDecimal price;
  51 + private Integer price;
52 52  
53 53 /**
54 54 * 销售价格
... ... @@ -59,19 +59,19 @@ public class CrmBusinessProductDO extends BaseDO {
59 59 /**
60 60 * 数量
61 61 */
62   - private BigDecimal num;
  62 + private BigDecimal count;
63 63  
64 64 // TODO @lzxhqs:改成 discountPercent
65 65 /**
66 66 * 折扣
67 67 */
68   - private BigDecimal discount;
  68 + private BigDecimal discountPercent;
69 69  
70 70 // TODO @lzxhqs:改成 totalPrice;总计价格,和现有项目风格一致;
71 71 /**
72 72 * 小计(折扣后价格)
73 73 */
74   - private BigDecimal subtotal;
  74 + private BigDecimal totalPrice;
75 75  
76 76 /**
77 77 * 单位
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/business/CrmBusinessProductMapper.java
... ... @@ -7,10 +7,12 @@ import org.apache.ibatis.annotations.Mapper;
7 7  
8 8 /**
9 9 * 商机产品 Mapper // TODO @lzxhqs:类注释,和作者之间要有一个空行
  10 + *
10 11 * @author lzxhqs
11 12 */
12 13 @Mapper
13 14 public interface CrmBusinessProductMapper extends BaseMapperX<CrmBusinessProductDO> {
  15 +
14 16 default void deleteByBusinessId(Long id) { // TODO @lzxhqs:第一个方法,和类之间最好空一行;
15 17 delete(CrmBusinessProductDO::getBusinessId, id);
16 18 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/dal/mysql/contract/CrmContractMapper.java
... ... @@ -65,8 +65,9 @@ public interface CrmContractMapper extends BaseMapperX&lt;CrmContractDO&gt; {
65 65 default Long selectCountByContactId(Long contactId) {
66 66 return selectCount(CrmContractDO::getContactId, contactId);
67 67 }
68   - default CrmContractDO selectByBizId(Long businessId) { // TODO @lzxhqs:1)方法和方法之间要有空行;2)selectCountByBusinessId,一个是应该求数量,一个是不要缩写 BizId 可读性;
69   - return selectOne(CrmContractDO::getBusinessId, businessId);
  68 +
  69 + default Long selectCountByBusinessId(Long businessId) { // TODO @lzxhqs:1)方法和方法之间要有空行;2)selectCountByBusinessId,一个是应该求数量,一个是不要缩写 BizId 可读性;
  70 + return selectCount(CrmContractDO::getBusinessId, businessId);
70 71 }
71 72  
72 73 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessProductService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.service.business;
  2 +
  3 +import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO;
  4 +
  5 +import java.util.List;
  6 +
  7 +/**
  8 + * 商机产品关联表 Service 接口
  9 + *
  10 + * @author lzxhqs
  11 + */
  12 +public interface CrmBusinessProductService {
  13 +
  14 + /**
  15 + * 批量新增商机产品关联数据
  16 + * @param list 商机产品集合
  17 + */
  18 + void insertBatch(List<CrmBusinessProductDO> list);
  19 +
  20 + /**
  21 + * 根据商机id获取商机产品关联数据集合
  22 + * @param businessId 商机id
  23 + */
  24 + List<CrmBusinessProductDO> selectListByBusinessId(Long businessId);
  25 +
  26 + /**
  27 + * 批量更新商机产品表
  28 + * @param list 商机产品数据集合
  29 + */
  30 + void updateBatch(List<CrmBusinessProductDO> list);
  31 +
  32 + /**
  33 + * 批量删除
  34 + * @param list 需要删除的商机产品集合
  35 + */
  36 + void deleteBatch(List<CrmBusinessProductDO> list);
  37 +
  38 + /**
  39 + *根据商机id删除商机产品关联数据
  40 + * @param businessId 商机id
  41 + */
  42 + void deleteByBusinessId(Long businessId);
  43 +}
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessProductServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.crm.service.business;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  4 +import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO;
  5 +import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessProductMapper;
  6 +import jakarta.annotation.Resource;
  7 +import org.springframework.stereotype.Service;
  8 +import org.springframework.validation.annotation.Validated;
  9 +
  10 +import java.util.List;
  11 +
  12 +/**
  13 + * 商机产品关联表 Service 实现类
  14 + *
  15 + * @author lzxhqs
  16 + */
  17 +@Service
  18 +@Validated
  19 +public class CrmBusinessProductServiceImpl implements CrmBusinessProductService {
  20 + @Resource
  21 + private CrmBusinessProductMapper businessProductMapper;
  22 +
  23 + @Override
  24 + public void insertBatch(List<CrmBusinessProductDO> list) {
  25 + businessProductMapper.insertBatch(list);
  26 + }
  27 +
  28 + @Override
  29 + public List<CrmBusinessProductDO> selectListByBusinessId(Long businessId) {
  30 + return businessProductMapper.selectList(CrmBusinessProductDO::getBusinessId,businessId);
  31 + }
  32 +
  33 + @Override
  34 + public void updateBatch(List<CrmBusinessProductDO> list) {
  35 + businessProductMapper.updateBatch(list);
  36 + }
  37 +
  38 + @Override
  39 + public void deleteBatch(List<CrmBusinessProductDO> list) {
  40 + businessProductMapper.deleteBatchIds(CollectionUtils.convertList(list,CrmBusinessProductDO::getId));
  41 +
  42 + }
  43 +
  44 + @Override
  45 + public void deleteByBusinessId(Long businessId) {
  46 + businessProductMapper.deleteByBusinessId(businessId);
  47 + }
  48 +}
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/business/CrmBusinessServiceImpl.java
... ... @@ -2,7 +2,9 @@ package cn.iocoder.yudao.module.crm.service.business;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.collection.ListUtil;
  5 +import cn.hutool.core.util.ObjectUtil;
5 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
6 8 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
7 9 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessPageReqVO;
8 10 import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessSaveReqVO;
... ... @@ -13,15 +15,12 @@ import cn.iocoder.yudao.module.crm.convert.businessproduct.CrmBusinessProductCon
13 15 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
14 16 import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessProductDO;
15 17 import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactBusinessDO;
16   -import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
17 18 import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessMapper;
18   -import cn.iocoder.yudao.module.crm.dal.mysql.business.CrmBusinessProductMapper;
19   -import cn.iocoder.yudao.module.crm.dal.mysql.contactbusinesslink.CrmContactBusinessMapper;
20   -import cn.iocoder.yudao.module.crm.dal.mysql.contract.CrmContractMapper;
21 19 import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
22 20 import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
23 21 import cn.iocoder.yudao.module.crm.framework.permission.core.annotations.CrmPermission;
24 22 import cn.iocoder.yudao.module.crm.service.contact.CrmContactBusinessService;
  23 +import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
25 24 import cn.iocoder.yudao.module.crm.service.followup.bo.CrmUpdateFollowUpReqBO;
26 25 import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
27 26 import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
... ... @@ -33,7 +32,6 @@ import org.springframework.stereotype.Service;
33 32 import org.springframework.transaction.annotation.Transactional;
34 33 import org.springframework.validation.annotation.Validated;
35 34  
36   -import java.util.ArrayList;
37 35 import java.util.Collection;
38 36 import java.util.List;
39 37  
... ... @@ -56,14 +54,13 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
56 54 private CrmBusinessMapper businessMapper;
57 55  
58 56 @Resource
59   - private CrmBusinessProductMapper businessProductMapper;
  57 + private CrmBusinessProductService businessProductService;
60 58 // TODO @lzxhqs:不直接调用这个 mapper,要调用对方的 service;每个业务独立收敛
61 59 @Resource
62   - private CrmContractMapper contractMapper;
  60 + private CrmContractService contractService;
63 61  
64 62 // TODO @lzxhqs:不直接调用这个 mapper,要调用对方的 service;每个业务独立收敛
65   - @Resource
66   - private CrmContactBusinessMapper contactBusinessMapper;
  63 +
67 64 @Resource
68 65 private CrmPermissionService permissionService;
69 66 @Resource
... ... @@ -81,10 +78,9 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
81 78 businessMapper.insert(business);
82 79 // TODO 商机待定:插入商机与产品的关联表;校验商品存在
83 80 // TODO lzxhqs:新增时,是不是不用调用这个方法哈;
84   - verifyCrmBusinessProduct(business.getId());
85 81 // TODO @lzxhqs:用 CollUtils.isNotEmpty;
86   - if (!createReqVO.getProducts().isEmpty()) {
87   - createBusinessProducts(createReqVO.getProducts(), business.getId());
  82 + if (CollUtil.isNotEmpty(createReqVO.getProducts())) {
  83 + createBusinessProducts(createReqVO.getProducts(), business.getId(), false);
88 84 }
89 85 // TODO 商机待定:在联系人的详情页,如果直接【新建商机】,则需要关联下。这里要搞个 CrmContactBusinessDO 表
90 86 createContactBusiness(business.getId(), createReqVO.getContactId());
... ... @@ -111,37 +107,39 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
111 107 CrmContactBusinessDO contactBusiness = new CrmContactBusinessDO();
112 108 contactBusiness.setBusinessId(businessId);
113 109 contactBusiness.setContactId(contactId);
114   - contactBusinessMapper.insert(contactBusiness);
  110 + contactBusinessService.insert(contactBusiness);
115 111  
116 112 }
117 113  
118 114 // TODO @lzxhqs:这个方法注释格式不对;删除@description,然后把 插入商机产品关联表 作为方法注释;
119 115 /**
120   - * @param products 产品集合
121   - * @description 插入商机产品关联表
  116 + * 插入商机产品关联表
  117 + *
  118 + * @param products 产品集合
  119 + * @param businessId 商机id
  120 + * @param updateFlag 更新标识 true 代表更新
122 121 * @author lzxhqs
123 122 */
124   - private void createBusinessProducts(List<CrmBusinessProductSaveReqVO> products, Long businessId) {
  123 + private void createBusinessProducts(List<CrmBusinessProductSaveReqVO> products, Long businessId, Boolean updateFlag) {
125 124 // TODO @lzxhqs:可以用 CollectionUtils.convertList;
126   - List<CrmBusinessProductDO> list = new ArrayList<>();
127   - for (CrmBusinessProductSaveReqVO product : products) {
128   - CrmBusinessProductDO businessProductDO = CrmBusinessProductConvert.INSTANCE.convert(product);
129   - businessProductDO.setBusinessId(businessId);
130   - list.add(businessProductDO);
131   - }
132   - businessProductMapper.insertBatch(list);
133   - }
134   -
135   - /**
136   - * @param id businessId
137   - * @description 校验管理的产品存在则删除
138   - * @author lzxhqs
139   - */
140   - private void verifyCrmBusinessProduct(Long id) {
141   - CrmBusinessProductDO businessProductDO = businessProductMapper.selectByBusinessId(id);
142   - if (businessProductDO != null) {
143   - //通过商机Id删除
144   - businessProductMapper.deleteByBusinessId(id);
  125 + List<CrmBusinessProductDO> list = CollectionUtils.convertList(products, product ->
  126 + CrmBusinessProductConvert.INSTANCE.convert(product).setBusinessId(businessId));
  127 + if (Boolean.TRUE.equals(updateFlag)) {
  128 +// 根据商机 id从商机产品关联表中获取已存在的数据集合
  129 + List<CrmBusinessProductDO> oldProducts = businessProductService.selectListByBusinessId(businessId);
  130 + List<List<CrmBusinessProductDO>> diffList = CollectionUtils.diffList(oldProducts, list, (oldValue, newValue) ->
  131 + ObjectUtil.equal(oldValue.getProductId(), newValue.getProductId()));
  132 + if (CollUtil.isNotEmpty(diffList.getFirst())) {
  133 + businessProductService.insertBatch(diffList.getFirst());
  134 + }
  135 + if (CollUtil.isNotEmpty(diffList.get(1))) {
  136 + businessProductService.updateBatch(diffList.get(1));
  137 + }
  138 + if (CollUtil.isNotEmpty(diffList.get(2))) {
  139 + businessProductService.deleteBatch(diffList.get(2));
  140 + }
  141 + } else {
  142 + businessProductService.insertBatch(list);
145 143 }
146 144  
147 145 }
... ... @@ -160,9 +158,10 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
160 158 businessMapper.updateById(updateObj);
161 159 // TODO 商机待定:插入商机与产品的关联表;校验商品存在
162 160 // TODO @lzxhqs:更新时,可以调用 CollectionUtils 的 diffList,尽量避免这种先删除再插入;而是新增的插入、变更的更新,没的删除;不然这个表每次更新,会多好多数据;
163   - verifyCrmBusinessProduct(updateReqVO.getId());
164   - if (!updateReqVO.getProducts().isEmpty()) {
165   - createBusinessProducts(updateReqVO.getProducts(), updateReqVO.getId());
  161 + if (CollUtil.isNotEmpty(updateReqVO.getProducts())) {
  162 + createBusinessProducts(updateReqVO.getProducts(), updateReqVO.getId(), true);
  163 + } else {
  164 + businessProductService.deleteByBusinessId(updateReqVO.getId());
166 165 }
167 166  
168 167 // TODO @商机待定:如果状态发生变化,插入商机状态变更记录表
... ... @@ -197,14 +196,14 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
197 196 }
198 197  
199 198 /**
  199 + * 删除校验合同是关联合同
  200 + *
200 201 * @param businessId 商机id
201   - * @throws
202   - * @description 删除校验合同是关联合同
203 202 * @author lzxhqs
204 203 */
205 204 private void validateContractExists(Long businessId) {
206   - CrmContractDO contract = contractMapper.selectByBizId(businessId);
207   - if (contract != null) {
  205 + Long count = contractService.selectCountByBusinessId(businessId);
  206 + if (count > 0) {
208 207 throw exception(BUSINESS_CONTRACT_EXISTS);
209 208 }
210 209 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactBusinessService.java
... ... @@ -42,4 +42,9 @@ public interface CrmContactBusinessService {
42 42 */
43 43 List<CrmContactBusinessDO> getContactBusinessListByContactId(Long contactId);
44 44  
  45 + /**
  46 + * 新增联系人与商机的
  47 + * @param contactBusiness 新增联系人与商机的对象
  48 + */
  49 + void insert(CrmContactBusinessDO contactBusiness);
45 50 }
46 51 \ No newline at end of file
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contact/CrmContactBusinessServiceImpl.java
... ... @@ -85,4 +85,9 @@ public class CrmContactBusinessServiceImpl implements CrmContactBusinessService
85 85 return contactBusinessMapper.selectListByContactId(contactId);
86 86 }
87 87  
  88 + @Override
  89 + public void insert(CrmContactBusinessDO contactBusiness) {
  90 + contactBusinessMapper.insert(contactBusiness);
  91 + }
  92 +
88 93 }
89 94 \ No newline at end of file
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractService.java
... ... @@ -110,4 +110,10 @@ public interface CrmContractService {
110 110 */
111 111 Long getContractCountByCustomerId(Long customerId);
112 112  
  113 + /**
  114 + * 根据商机ID获取关联客户的合同数量
  115 + * @param businessId 商机ID
  116 + * @return 数量
  117 + */
  118 + Long selectCountByBusinessId(Long businessId);
113 119 }
... ...
yudao-module-crm/yudao-module-crm-biz/src/main/java/cn/iocoder/yudao/module/crm/service/contract/CrmContractServiceImpl.java
... ... @@ -178,5 +178,10 @@ public class CrmContractServiceImpl implements CrmContractService {
178 178 return contractMapper.selectCount(CrmContractDO::getCustomerId, customerId);
179 179 }
180 180  
  181 + @Override
  182 + public Long selectCountByBusinessId(Long businessId) {
  183 + return contractMapper.selectCountByBusinessId(businessId);
  184 + }
  185 +
181 186 // TODO @合同待定:需要新增一个 ContractConfigDO 表,合同配置,重点是到期提醒;
182 187 }
... ...