package com.ruoyi.sales.service.impl;
|
|
import cn.hutool.core.bean.BeanUtil;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.ruoyi.framework.web.domain.AjaxResult;
|
import com.ruoyi.common.utils.SecurityUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.sales.dto.SalesContractDTO;
|
import com.ruoyi.sales.mapper.SalesContractMapper;
|
import com.ruoyi.sales.mapper.SalesContractProductMapper;
|
import com.ruoyi.sales.pojo.SalesContract;
|
import com.ruoyi.sales.pojo.SalesContractProduct;
|
import com.ruoyi.sales.service.ISalesContractService;
|
import com.ruoyi.sales.vo.SalesContractVO;
|
import jakarta.annotation.Resource;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.util.CollectionUtils;
|
|
import java.math.BigDecimal;
|
import java.time.LocalDateTime;
|
import java.util.ArrayList;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.stream.Collectors;
|
|
/**
|
* 销售合同 Service 实现
|
*/
|
@Slf4j
|
@Service
|
public class SalesContractServiceImpl extends ServiceImpl<SalesContractMapper, SalesContract> implements ISalesContractService {
|
|
@Resource
|
private SalesContractProductMapper salesContractProductMapper;
|
|
@Override
|
public IPage<SalesContractVO> listPage(Page<SalesContract> page, SalesContractDTO dto) {
|
LambdaQueryWrapper<SalesContract> queryWrapper = buildQueryWrapper(dto);
|
IPage<SalesContract> iPage = this.page(page, queryWrapper);
|
|
IPage<SalesContractVO> voPage = iPage.convert(item -> {
|
return BeanUtil.copyProperties(item, SalesContractVO.class);
|
});
|
|
return voPage;
|
}
|
|
@Override
|
public AjaxResult getDetail(Long id) {
|
SalesContract contract = this.getById(id);
|
if (contract == null) {
|
return AjaxResult.error("合同数据不存在");
|
}
|
SalesContractVO vo = BeanUtil.copyProperties(contract, SalesContractVO.class);
|
|
// 获取明细
|
LambdaQueryWrapper<SalesContractProduct> productQuery = new LambdaQueryWrapper<>();
|
productQuery.eq(SalesContractProduct::getContractId, id);
|
List<SalesContractProduct> productList = salesContractProductMapper.selectList(productQuery);
|
vo.setProductList(productList);
|
|
return AjaxResult.success(vo);
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public AjaxResult addOrUpdate(SalesContractDTO dto) {
|
SalesContract contract = BeanUtil.copyProperties(dto, SalesContract.class);
|
boolean isUpdate = contract.getId() != null;
|
|
List<SalesContractProduct> productList = dto.getProductList();
|
if (productList == null) {
|
productList = new ArrayList<>();
|
}
|
|
// 重新计算各产品的产值,并汇总合同总产值
|
BigDecimal totalOutputValue = BigDecimal.ZERO;
|
for (SalesContractProduct product : productList) {
|
BigDecimal price = product.getTaxInclusiveUnitPrice() != null ? product.getTaxInclusiveUnitPrice() : BigDecimal.ZERO;
|
BigDecimal shipped = product.getShippedQuantity() != null ? product.getShippedQuantity() : BigDecimal.ZERO;
|
BigDecimal productOutputValue = price.multiply(shipped);
|
product.setOutputValue(productOutputValue);
|
|
totalOutputValue = totalOutputValue.add(productOutputValue);
|
}
|
contract.setOutputValue(totalOutputValue);
|
|
if (isUpdate) {
|
this.updateById(contract);
|
|
// 差量更新逻辑
|
handleProductListUpdate(contract.getId(), productList);
|
} else {
|
this.save(contract);
|
|
// 批量插入明细
|
for (SalesContractProduct product : productList) {
|
product.setContractId(contract.getId());
|
salesContractProductMapper.insert(product);
|
}
|
}
|
|
return AjaxResult.success();
|
}
|
|
/**
|
* 处理产品明细的差量更新
|
*/
|
private void handleProductListUpdate(Long contractId, List<SalesContractProduct> newList) {
|
// 获取数据库中旧的明细列表
|
LambdaQueryWrapper<SalesContractProduct> productQuery = new LambdaQueryWrapper<>();
|
productQuery.eq(SalesContractProduct::getContractId, contractId);
|
List<SalesContractProduct> oldList = salesContractProductMapper.selectList(productQuery);
|
|
Map<Long, SalesContractProduct> oldMap = oldList.stream()
|
.collect(Collectors.toMap(SalesContractProduct::getId, p -> p));
|
|
// 遍历新列表进行插入或更新
|
for (SalesContractProduct newProduct : newList) {
|
newProduct.setContractId(contractId);
|
if (newProduct.getId() != null && oldMap.containsKey(newProduct.getId())) {
|
// 更新
|
salesContractProductMapper.updateById(newProduct);
|
oldMap.remove(newProduct.getId()); // 从 Map 中移除,剩下的就是需要删除的
|
} else {
|
// 新增
|
newProduct.setId(null); // 防御性处理
|
salesContractProductMapper.insert(newProduct);
|
}
|
}
|
|
// 删除在前端列表中不存在的旧记录
|
if (!oldMap.isEmpty()) {
|
salesContractProductMapper.deleteBatchIds(oldMap.keySet());
|
}
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public AjaxResult del(List<Long> ids) {
|
if (CollectionUtils.isEmpty(ids)) {
|
return AjaxResult.error("参数不能为空");
|
}
|
|
// 删除主表
|
this.removeByIds(ids);
|
|
// 级联删除子表
|
LambdaQueryWrapper<SalesContractProduct> delQuery = new LambdaQueryWrapper<>();
|
delQuery.in(SalesContractProduct::getContractId, ids);
|
salesContractProductMapper.delete(delQuery);
|
|
return AjaxResult.success();
|
}
|
|
@Override
|
public List<SalesContract> selectList(SalesContractDTO dto) {
|
return this.list(buildQueryWrapper(dto));
|
}
|
|
/**
|
* 构建查询条件
|
*/
|
private LambdaQueryWrapper<SalesContract> buildQueryWrapper(SalesContractDTO dto) {
|
LambdaQueryWrapper<SalesContract> queryWrapper = new LambdaQueryWrapper<>();
|
if (dto == null) {
|
return queryWrapper;
|
}
|
queryWrapper.like(StringUtils.isNotBlank(dto.getContractNo()), SalesContract::getContractNo, dto.getContractNo());
|
queryWrapper.like(StringUtils.isNotBlank(dto.getSigningUnit()), SalesContract::getSigningUnit, dto.getSigningUnit());
|
queryWrapper.eq(StringUtils.isNotBlank(dto.getArchiveStatus()), SalesContract::getArchiveStatus, dto.getArchiveStatus());
|
queryWrapper.ge(dto.getSignDateStart() != null, SalesContract::getSignDate, dto.getSignDateStart());
|
queryWrapper.le(dto.getSignDateEnd() != null, SalesContract::getSignDate, dto.getSignDateEnd());
|
|
queryWrapper.orderByDesc(SalesContract::getCreateTime);
|
return queryWrapper;
|
}
|
}
|