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.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Service
@ -59,6 +58,7 @@ public class CrmQuoteInfoServiceImpl implements ICrmQuoteInfoService {
List<CrmQuoteMaterialVo> items = quoteMaterialMapper.selectVoList(
JoinWrappers.lambda(CrmQuoteMaterial.class)
.selectAll(CrmQuoteMaterial.class)
.eq("t.del_flag", "0")
.eq(CrmQuoteMaterial::getQuoteId, quoteId)
.orderByAsc(CrmQuoteMaterial::getItemNo)
);
@ -98,6 +98,7 @@ public class CrmQuoteInfoServiceImpl implements ICrmQuoteInfoService {
MPJLambdaWrapper<CrmQuoteInfo> lqw = JoinWrappers.lambda(CrmQuoteInfo.class)
// 主表全部字段
.selectAll(CrmQuoteInfo.class)
.eq(CrmQuoteInfo::getDelFlag, "0")
// 客户方联系人CrmCustomerContact别名CustomerContact
.selectAs("CustomerContact", CrmCustomerContact::getContactName, CrmQuoteInfo::getCustomerContactRealName)
.leftJoin(CrmCustomerContact.class, "CustomerContact", CrmCustomerContact::getContactId, CrmQuoteInfo::getCustomerContactId)
@ -194,23 +195,42 @@ public class CrmQuoteInfoServiceImpl implements ICrmQuoteInfoService {
validEntityBeforeSave(update);
boolean ok = baseMapper.updateById(update) > 0;
if (!ok) return false;
// 全量覆盖子表:先删后增(保持简单一致性)
// 差异更新子表:存在则更新,不存在则插入;并删除前端未提交的旧记录
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();
if (itemsBo != null && !itemsBo.isEmpty()) {
for (int i = 0; i < itemsBo.size(); i++) {
CrmQuoteMaterialBo itemBo = itemsBo.get(i);
CrmQuoteMaterial entity = MapstructUtils.convert(itemBo, CrmQuoteMaterial.class);
// 避免主键冲突:子表使用自增主键,插入前显式置空
entity.setQuoteMaterialId(null);
// 统一归属报价ID
entity.setQuoteId(qid);
// 若未指定序号则按顺序回填
if (entity.getItemNo() == null) {
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);
return true;

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

Loading…
Cancel
Save