zss
10 小时以前 e7c4fc593964bbdc67be4f775599d52aaa01c302
src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -1,6 +1,7 @@
package com.ruoyi.sales.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
@@ -8,25 +9,30 @@
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.account.pojo.AccountExpense;
import com.ruoyi.account.pojo.AccountIncome;
import com.ruoyi.account.service.AccountIncomeService;
import com.ruoyi.basic.mapper.CustomerMapper;
import com.ruoyi.basic.mapper.ProductModelMapper;
import com.ruoyi.basic.pojo.Customer;
import com.ruoyi.basic.pojo.ProductModel;
import com.ruoyi.common.enums.FileNameType;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.other.mapper.TempFileMapper;
import com.ruoyi.other.pojo.TempFile;
import com.ruoyi.production.mapper.SalesLedgerSchedulingMapper;
import com.ruoyi.production.pojo.SalesLedgerScheduling;
import com.ruoyi.production.dto.ProductStructureDto;
import com.ruoyi.production.mapper.*;
import com.ruoyi.production.pojo.*;
import com.ruoyi.project.system.domain.SysDept;
import com.ruoyi.project.system.mapper.SysDeptMapper;
import com.ruoyi.quality.mapper.QualityInspectMapper;
import com.ruoyi.quality.pojo.QualityInspect;
import com.ruoyi.sales.dto.MonthlyAmountDto;
import com.ruoyi.sales.dto.SalesLedgerDto;
import com.ruoyi.sales.mapper.*;
import com.ruoyi.sales.pojo.*;
import com.ruoyi.sales.service.ISalesLedgerProductService;
import com.ruoyi.sales.service.ISalesLedgerService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -72,6 +78,7 @@
    private final CustomerMapper customerMapper;
    private final SalesLedgerProductMapper salesLedgerProductMapper;
    private final SalesLedgerProductServiceImpl salesLedgerProductServiceImpl;
    private final CommonFileMapper commonFileMapper;
@@ -82,6 +89,33 @@
    private final InvoiceLedgerMapper invoiceLedgerMapper;
    private final SalesLedgerSchedulingMapper salesLedgerSchedulingMapper;
    private final SalesLedgerWorkMapper salesLedgerWorkMapper;
    private final SalesLedgerProductionAccountingMapper salesLedgerProductionAccountingMapper;
    private final InvoiceRegistrationProductMapper invoiceRegistrationProductMapper;
    private final InvoiceRegistrationMapper invoiceRegistrationMapper;
    private final ProductOrderMapper productOrderMapper;
    private final ProcessRouteMapper processRouteMapper;
    private final ProductProcessRouteMapper productProcessRouteMapper;
    private final ProcessRouteItemMapper processRouteItemMapper;
    private final ProductProcessRouteItemMapper productProcessRouteItemMapper;
    private final ProductWorkOrderMapper productWorkOrderMapper;
    private final ProductionProductMainMapper productionProductMainMapper;
    private final ProductionProductOutputMapper productionProductOutputMapper;
    private final ProductionProductInputMapper productionProductInputMapper;
    private final QualityInspectMapper qualityInspectMapper;
    @Autowired
    private SysDeptMapper sysDeptMapper;
@@ -94,6 +128,10 @@
    private static final long LOCK_EXPIRE_TIME = 30;  // 锁自动过期时间(秒)
    private final RedisTemplate<String, String> redisTemplate;
    @Autowired
    private ProductModelMapper productModelMapper;
    @Autowired
    private ProductStructureMapper productStructureMapper;
    @Override
    public List<SalesLedger> selectSalesLedgerList(SalesLedgerDto salesLedgerDto) {
@@ -181,8 +219,8 @@
        // 查询原始数据
        LambdaQueryWrapper<SalesLedger> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.select(SalesLedger::getCustomerId,
                        SalesLedger::getCustomerName,
                        SalesLedger::getContractAmount)
                SalesLedger::getCustomerName,
                SalesLedger::getContractAmount)
                .orderByDesc(SalesLedger::getContractAmount);
        List<SalesLedger> records = salesLedgerMapper.selectList(queryWrapper);
@@ -190,7 +228,7 @@
        Map<Long, GroupedCustomer> groupedMap = new LinkedHashMap<>(); // 使用LinkedHashMap保持排序
        for (SalesLedger record : records) {
            groupedMap.computeIfAbsent(record.getCustomerId(),
                            k -> new GroupedCustomer(record.getCustomerId(), record.getCustomerName()))
                    k -> new GroupedCustomer(record.getCustomerId(), record.getCustomerName()))
                    .addAmount(record.getContractAmount());
        }
@@ -348,20 +386,60 @@
        if (CollectionUtils.isEmpty(idList)) {
            return 0;
        }
        // 生产订单有待排产数据,台账不可删除
        LambdaQueryWrapper<SalesLedgerScheduling> salesLedgerSchedulingLambdaQueryWrapper = new LambdaQueryWrapper<SalesLedgerScheduling>()
                .in(SalesLedgerScheduling::getSalesLedgerId, idList);
        if (salesLedgerSchedulingMapper.selectCount(salesLedgerSchedulingLambdaQueryWrapper) > 0) {
            throw new BaseException("有排产数据,不可删除");
        // 删除销售管理数据
        LambdaQueryWrapper<SalesLedgerProduct> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SalesLedgerProduct::getSalesLedgerId, idList)
                .select(SalesLedgerProduct::getId);
        List<SalesLedgerProduct> products = salesLedgerProductMapper.selectList(queryWrapper);
        List<Long> productIds = products.stream()
                .map(SalesLedgerProduct::getId)
                .collect(Collectors.toList());
        //删除生产数据
        salesLedgerProductServiceImpl.deleteProductionData(productIds);
        // 批量删除产品子表
        if (!productIds.isEmpty()) {
            salesLedgerProductMapper.deleteBatchIds(productIds);
        }
        // 1. 先删除子表数据
        LambdaQueryWrapper<SalesLedgerProduct> productWrapper = new LambdaQueryWrapper<>();
        productWrapper.in(SalesLedgerProduct::getSalesLedgerId, idList);
        salesLedgerProductMapper.delete(productWrapper);
        LambdaQueryWrapper<InvoiceRegistrationProduct> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(InvoiceRegistrationProduct::getSalesLedgerId, idList);
        List<InvoiceRegistrationProduct> invoiceRegistrationProducts = invoiceRegistrationProductMapper.selectList(wrapper);
        List<Integer> invoiceLedgerIds = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(invoiceRegistrationProducts)) {
            LambdaQueryWrapper<InvoiceLedger> wrapperOne = new LambdaQueryWrapper<>();
            wrapperOne.in(InvoiceLedger::getInvoiceRegistrationProductId, invoiceRegistrationProducts.stream().map(InvoiceRegistrationProduct::getId).collect(Collectors.toList()));
            List<InvoiceLedger> invoiceLedgers = invoiceLedgerMapper.selectList(wrapperOne);
            if (CollectionUtils.isNotEmpty(invoiceLedgers)) {
                invoiceLedgerIds = invoiceLedgers.stream().map(InvoiceLedger::getId).collect(Collectors.toList());
            }
            invoiceLedgerMapper.delete(wrapperOne);
        }
        invoiceRegistrationProductMapper.delete(wrapper);
        LambdaQueryWrapper<InvoiceRegistration> wrapperTwo = new LambdaQueryWrapper<>();
        wrapperTwo.in(InvoiceRegistration::getSalesLedgerId, idList);
        invoiceRegistrationMapper.delete(wrapperTwo);
        if (CollectionUtils.isNotEmpty(invoiceLedgerIds)) {
            LambdaQueryWrapper<ReceiptPayment> wrapperTree = new LambdaQueryWrapper<>();
            wrapperTree.in(ReceiptPayment::getInvoiceLedgerId, invoiceLedgerIds);
            receiptPaymentMapper.delete(wrapperTree);
        }
        // 删除生产管控数据
        // 删除生产订单数据
        LambdaQueryWrapper<SalesLedgerScheduling> in = new LambdaQueryWrapper<SalesLedgerScheduling>()
                .in(SalesLedgerScheduling::getSalesLedgerId, idList);
        salesLedgerSchedulingMapper.delete(in);
        // 删除生产派工数据
        LambdaQueryWrapper<SalesLedgerWork> workOrderWrapper = new LambdaQueryWrapper<>();
        workOrderWrapper.in(SalesLedgerWork::getSalesLedgerId, idList);
        salesLedgerWorkMapper.delete(workOrderWrapper);
        // 删除生产核算数据
        LambdaQueryWrapper<SalesLedgerProductionAccounting> reportWrapper = new LambdaQueryWrapper<>();
        reportWrapper.in(SalesLedgerProductionAccounting::getSalesLedgerId, idList);
        salesLedgerProductionAccountingMapper.delete(reportWrapper);
        // 2. 再删除主表数据
        return salesLedgerMapper.deleteBatchIds(idList);
    }
@@ -539,6 +617,8 @@
                salesLedgerProduct.setNoInvoiceNum(salesLedgerProduct.getQuantity());
                salesLedgerProduct.setNoInvoiceAmount(salesLedgerProduct.getTaxInclusiveTotalPrice());
                salesLedgerProductMapper.insert(salesLedgerProduct);
                // 添加生产数据
                salesLedgerProductServiceImpl.addProductionData(salesLedgerProduct);
            }
        }
    }
@@ -592,12 +672,12 @@
            return datePart + String.format("%03d", nextSequence);
        } finally {
            // 3. 释放锁(使用Lua脚本保证原子性,避免误删其他线程的锁)
            // 3. 释放锁
            String luaScript = "if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('DEL', KEYS[1]) else return 0 end";
            redisTemplate.execute(
                    new DefaultRedisScript<>(luaScript, Long.class),
                    Collections.singletonList(lockKey),
                    lockValue // 只有持有相同值的线程才能删除锁
                    lockValue
            );
        }
    }
@@ -606,7 +686,7 @@
        if (sequences.isEmpty()) {
            return 1;
        }
        // 排序后查找第一个缺失的正整数(与原逻辑一致)
        // 排序后查找第一个缺失的正整数
        sequences.sort(Integer::compareTo);
        int next = 1;
        for (int seq : sequences) {
@@ -636,14 +716,13 @@
                .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);
            // 设置 contractAmount 字段,注意这里假设字段名为 "contractAmount"
            Field amountField = mainEntityClass.getDeclaredField("contractAmount");
            amountField.setAccessible(true);
            amountField.set(entity, totalAmount);