feat(oa/crm):优化报价单物料明细更新逻辑

- 引入差异更新机制,避免全量删除插入
- 子表更新时保留未变更数据,提升性能
- 增加删除标记条件过滤,确保数据准确性
-优化导入包结构,统一使用 java.util.*
- 明细为空时清空子表,保证数据一致性
- 添加排序和删除标记查询条件
- 使用 insertOrUpdate 简化新增与修改操作
- 回写主表金额汇总逻辑保持不变
dev
zangch@mesnac.com 1 month ago
parent 331f558633
commit 35de964169

@ -25,11 +25,10 @@ import org.dromara.oa.crm.service.ICrmQuoteInfoService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.Collection; import java.util.*;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.util.List; import java.util.stream.Collectors;
import java.util.Map;
/** /**
* Service * Service
@ -59,6 +58,7 @@ public class CrmQuoteInfoServiceImpl implements ICrmQuoteInfoService {
List<CrmQuoteMaterialVo> items = quoteMaterialMapper.selectVoList( List<CrmQuoteMaterialVo> items = quoteMaterialMapper.selectVoList(
JoinWrappers.lambda(CrmQuoteMaterial.class) JoinWrappers.lambda(CrmQuoteMaterial.class)
.selectAll(CrmQuoteMaterial.class) .selectAll(CrmQuoteMaterial.class)
.eq("t.del_flag", "0")
.eq(CrmQuoteMaterial::getQuoteId, quoteId) .eq(CrmQuoteMaterial::getQuoteId, quoteId)
.orderByAsc(CrmQuoteMaterial::getItemNo) .orderByAsc(CrmQuoteMaterial::getItemNo)
); );
@ -98,6 +98,7 @@ public class CrmQuoteInfoServiceImpl implements ICrmQuoteInfoService {
MPJLambdaWrapper<CrmQuoteInfo> lqw = JoinWrappers.lambda(CrmQuoteInfo.class) MPJLambdaWrapper<CrmQuoteInfo> lqw = JoinWrappers.lambda(CrmQuoteInfo.class)
// 主表全部字段 // 主表全部字段
.selectAll(CrmQuoteInfo.class) .selectAll(CrmQuoteInfo.class)
.eq(CrmQuoteInfo::getDelFlag, "0")
// 客户方联系人CrmCustomerContact别名CustomerContact // 客户方联系人CrmCustomerContact别名CustomerContact
.selectAs("CustomerContact", CrmCustomerContact::getContactName, CrmQuoteInfo::getCustomerContactRealName) .selectAs("CustomerContact", CrmCustomerContact::getContactName, CrmQuoteInfo::getCustomerContactRealName)
.leftJoin(CrmCustomerContact.class, "CustomerContact", CrmCustomerContact::getContactId, CrmQuoteInfo::getCustomerContactId) .leftJoin(CrmCustomerContact.class, "CustomerContact", CrmCustomerContact::getContactId, CrmQuoteInfo::getCustomerContactId)
@ -194,23 +195,42 @@ public class CrmQuoteInfoServiceImpl implements ICrmQuoteInfoService {
validEntityBeforeSave(update); validEntityBeforeSave(update);
boolean ok = baseMapper.updateById(update) > 0; boolean ok = baseMapper.updateById(update) > 0;
if (!ok) return false; if (!ok) return false;
// 全量覆盖子表:先删后增(保持简单一致性) // 差异更新子表:存在则更新,不存在则插入;并删除前端未提交的旧记录
Long qid = bo.getQuoteId(); Long qid = bo.getQuoteId();
quoteMaterialMapper.delete(Wrappers.<CrmQuoteMaterial>lambdaQuery().eq(CrmQuoteMaterial::getQuoteId, qid)); List<CrmQuoteMaterial> oldItems = quoteMaterialMapper.selectList(
Wrappers.<CrmQuoteMaterial>lambdaQuery().eq(CrmQuoteMaterial::getQuoteId, qid)
);
List<CrmQuoteMaterialBo> itemsBo = bo.getItemsBo(); List<CrmQuoteMaterialBo> itemsBo = bo.getItemsBo();
if (itemsBo != null && !itemsBo.isEmpty()) { if (itemsBo != null && !itemsBo.isEmpty()) {
for (int i = 0; i < itemsBo.size(); i++) { for (int i = 0; i < itemsBo.size(); i++) {
CrmQuoteMaterialBo itemBo = itemsBo.get(i); CrmQuoteMaterialBo itemBo = itemsBo.get(i);
CrmQuoteMaterial entity = MapstructUtils.convert(itemBo, CrmQuoteMaterial.class); CrmQuoteMaterial entity = MapstructUtils.convert(itemBo, CrmQuoteMaterial.class);
// 避免主键冲突:子表使用自增主键,插入前显式置空 // 统一归属报价ID
entity.setQuoteMaterialId(null);
entity.setQuoteId(qid); entity.setQuoteId(qid);
// 若未指定序号则按顺序回填
if (entity.getItemNo() == null) { if (entity.getItemNo() == null) {
entity.setItemNo((long) (i + 1)); entity.setItemNo((long) (i + 1));
} }
quoteMaterialMapper.insert(entity); // 使用 insertOrUpdate 简化增改逻辑,参考合同物料实现
quoteMaterialMapper.insertOrUpdate(entity);
} }
// 删除旧记录中未在本次提交集合内的记录
Set<Long> incomingIds = itemsBo.stream()
.map(CrmQuoteMaterialBo::getQuoteMaterialId)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
for (CrmQuoteMaterial old : oldItems) {
if (!incomingIds.contains(old.getQuoteMaterialId())) {
quoteMaterialMapper.deleteById(old.getQuoteMaterialId());
}
}
} else {
// 当前未提交明细则清空子表
quoteMaterialMapper.delete(Wrappers.<CrmQuoteMaterial>lambdaQuery().eq(CrmQuoteMaterial::getQuoteId, qid));
} }
// 回写主表金额汇总 // 回写主表金额汇总
this.recalcTotals(qid); this.recalcTotals(qid);
return true; return true;

@ -74,11 +74,13 @@ public class CrmQuoteMaterialServiceImpl implements ICrmQuoteMaterialService {
Map<String, Object> params = bo.getParams(); Map<String, Object> params = bo.getParams();
MPJLambdaWrapper<CrmQuoteMaterial> lqw = JoinWrappers.lambda(CrmQuoteMaterial.class) MPJLambdaWrapper<CrmQuoteMaterial> lqw = JoinWrappers.lambda(CrmQuoteMaterial.class)
.selectAll(CrmQuoteMaterial.class) .selectAll(CrmQuoteMaterial.class)
// 联表选择SAP物料名称 & 销售物料名称 .eq(CrmQuoteMaterial::getDelFlag, "0")
.select(BaseMaterialInfo::getMaterialName) // 联表选择SAP物料名称 & 销售物料名称
.select(BaseRelationMaterial::getSaleMaterialName) .select(BaseMaterialInfo::getMaterialName)
.leftJoin(BaseMaterialInfo.class, BaseMaterialInfo::getMaterialId, CrmQuoteMaterial::getMaterialId) .select(BaseRelationMaterial::getSaleMaterialName)
.leftJoin(BaseRelationMaterial.class, BaseRelationMaterial::getRelationMaterialId, CrmQuoteMaterial::getRelationMaterialId) .leftJoin(BaseMaterialInfo.class, BaseMaterialInfo::getMaterialId, CrmQuoteMaterial::getMaterialId)
.leftJoin(BaseRelationMaterial.class, BaseRelationMaterial::getRelationMaterialId, CrmQuoteMaterial::getRelationMaterialId)
.eq(bo.getQuoteId() != null, CrmQuoteMaterial::getQuoteId, bo.getQuoteId()) .eq(bo.getQuoteId() != null, CrmQuoteMaterial::getQuoteId, bo.getQuoteId())
.eq(bo.getItemNo() != null, CrmQuoteMaterial::getItemNo, bo.getItemNo()) .eq(bo.getItemNo() != null, CrmQuoteMaterial::getItemNo, bo.getItemNo())
.like(StringUtils.isNotBlank(bo.getProductName()), CrmQuoteMaterial::getProductName, bo.getProductName()) .like(StringUtils.isNotBlank(bo.getProductName()), CrmQuoteMaterial::getProductName, bo.getProductName())

Loading…
Cancel
Save