package com.ruoyi.sales.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.sales.mapper.SalesLedgerMapper; import com.ruoyi.sales.mapper.SalesLedgerProductMapper; import com.ruoyi.sales.pojo.SalesLedger; import com.ruoyi.sales.pojo.SalesLedgerProduct; import com.ruoyi.sales.service.ISalesLedgerProductService; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.lang.reflect.Field; import java.math.BigDecimal; import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; /** * 产品信息Service业务层处理 * * @author ruoyi * @date 2025-05-08 */ @Service @AllArgsConstructor public class SalesLedgerProductServiceImpl extends ServiceImpl implements ISalesLedgerProductService { private SalesLedgerProductMapper salesLedgerProductMapper; private SalesLedgerMapper salesLedgerMapper; @Override public SalesLedgerProduct selectSalesLedgerProductById(Long id) { return salesLedgerProductMapper.selectById(id); } @Override public List selectSalesLedgerProductList(SalesLedgerProduct salesLedgerProduct) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(SalesLedgerProduct::getSalesLedgerId,salesLedgerProduct.getSalesLedgerId()); return salesLedgerProductMapper.selectList(queryWrapper); } @Override @Transactional(rollbackFor = Exception.class) public int deleteSalesLedgerProductByIds(Long[] ids) { if (ids == null || ids.length == 0) { return 0; } // 1. 先查询要删除的子表记录,获取对应的 salesLedgerId List deletedProducts = salesLedgerProductMapper.selectBatchIds(Arrays.asList(ids)); if (deletedProducts.isEmpty()) { return 0; // 没有可删除的数据 } // 可能属于多个主表(但通常一个接口只处理一个主表) Set mainIds = deletedProducts.stream() .map(SalesLedgerProduct::getSalesLedgerId) .filter(Objects::nonNull) .collect(Collectors.toSet()); // 2. 执行删除操作 int result = salesLedgerProductMapper.deleteBatchIds(Arrays.asList(ids)); // 3. 对每个主表ID进行金额更新 for (Long salesLedgerId : mainIds) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(SalesLedgerProduct::getSalesLedgerId, salesLedgerId); List remainingProducts = salesLedgerProductMapper.selectList(wrapper); // 调用通用方法更新主表金额 updateMainContractAmount( salesLedgerId, remainingProducts, SalesLedgerProduct::getTaxInclusiveTotalPrice, salesLedgerMapper, SalesLedger.class ); } return result; } @Override @Transactional(rollbackFor = Exception.class) public int addOrUpdateSalesLedgerProduct(SalesLedgerProduct salesLedgerProduct) { int result; Long salesLedgerId = salesLedgerProduct.getSalesLedgerId(); if (salesLedgerProduct.getId() == null) { result = salesLedgerProductMapper.insert(salesLedgerProduct); } else { result = salesLedgerProductMapper.updateById(salesLedgerProduct); } // 如果插入或更新成功,并且有 salesLedgerId,才继续更新主表金额 if (result > 0 && salesLedgerId != null) { // 查询该主表下的所有子表数据 LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); wrapper.eq(SalesLedgerProduct::getSalesLedgerId, salesLedgerId); List productList = salesLedgerProductMapper.selectList(wrapper); // 调用通用方法更新主表金额 updateMainContractAmount( salesLedgerId, productList, SalesLedgerProduct::getTaxInclusiveTotalPrice, salesLedgerMapper, SalesLedger.class ); } return result; } /** * 通用方法:根据主表ID和子表列表,更新主表的合同金额 */ public void updateMainContractAmount( Long mainId, List subList, Function amountGetter, BaseMapper mainMapper, Class mainEntityClass) { if (mainId == null || subList == null || subList.isEmpty()) { return; } BigDecimal totalAmount = subList.stream() .map(amountGetter) .filter(Objects::nonNull) .reduce(BigDecimal.ZERO, BigDecimal::add); try { S entity = mainEntityClass.getDeclaredConstructor().newInstance(); Field idField = mainEntityClass.getDeclaredField("id"); idField.setAccessible(true); idField.set(entity, mainId); Field amountField = mainEntityClass.getDeclaredField("contractAmount"); amountField.setAccessible(true); amountField.set(entity, totalAmount); mainMapper.updateById(entity); } catch (Exception e) { throw new RuntimeException("动态更新主表金额失败", e); } } }