云
2026-09-24 48e8e81666b2d0f49b931cb7b93729355758f2ae
src/main/java/com/ruoyi/aftersalesservice/service/impl/AfterSalesServiceServiceImpl.java
@@ -1,32 +1,45 @@
package com.ruoyi.aftersalesservice.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
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.aftersalesservice.dto.AfterSalesServiceImportDto;
import com.ruoyi.aftersalesservice.dto.AfterSalesServiceNewDto;
import com.ruoyi.aftersalesservice.dto.CountDto;
import com.ruoyi.aftersalesservice.mapper.AfterSalesServiceMapper;
import com.ruoyi.aftersalesservice.pojo.AfterSalesService;
import com.ruoyi.aftersalesservice.service.AfterSalesServiceService;
import com.ruoyi.basic.mapper.CustomerMapper;
import com.ruoyi.basic.pojo.Customer;
import com.ruoyi.common.utils.OrderUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.project.system.domain.SysDept;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysDeptMapper;
import com.ruoyi.project.system.domain.SysDictData;
import com.ruoyi.project.system.mapper.SysDictDataMapper;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.sales.dto.SalesLedgerDto;
import com.ruoyi.sales.mapper.SalesLedgerMapper;
import com.ruoyi.sales.pojo.SalesLedger;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.sales.service.ISalesLedgerProductService;
import com.ruoyi.sales.service.ISalesLedgerService;
import com.ruoyi.sales.service.impl.SalesLedgerProductServiceImpl;
import com.ruoyi.sales.service.impl.SalesLedgerServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
@@ -36,26 +49,24 @@
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class AfterSalesServiceServiceImpl extends ServiceImpl<AfterSalesServiceMapper, AfterSalesService> implements AfterSalesServiceService {
    @Autowired
    private AfterSalesServiceMapper afterSalesServiceMapper;
    @Autowired
    private SysDeptMapper sysDeptMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private ISalesLedgerProductService salesLedgerProductService;
    @Autowired
    private ISalesLedgerService salesLedgerService;
    private final AfterSalesServiceMapper afterSalesServiceMapper;
    private final SysDeptMapper sysDeptMapper;
    private final SysUserMapper sysUserMapper;
    private final ISalesLedgerProductService salesLedgerProductService;
    private final ISalesLedgerService salesLedgerService;
    private final com.ruoyi.sales.mapper.ShippingInfoMapper shippingInfoMapper;
    private final CustomerMapper customerMapper;
    private final SalesLedgerMapper salesLedgerMapper;
    private final SysDictDataMapper sysDictDataMapper;
    @Override
    public IPage<AfterSalesService> listPage(Page page, AfterSalesService afterSalesService) {
    public IPage<AfterSalesServiceNewDto> listPage(Page page, AfterSalesServiceNewDto afterSalesService) {
        Long tenantId = SecurityUtils.getLoginUser().getTenantId();
        SysDept sysDept = sysDeptMapper.selectDeptById(tenantId);
        IPage<AfterSalesService> afterSalesServiceIPage = afterSalesServiceMapper.listPage(page, afterSalesService);
        IPage<AfterSalesServiceNewDto> afterSalesServiceIPage = afterSalesServiceMapper.listPage(page, afterSalesService);
        afterSalesServiceIPage.getRecords().forEach(item -> {
            item.setDeptName(sysDept.getDeptName());
        });
@@ -74,21 +85,220 @@
        SysUser sysUser = sysUserMapper.selectUserById(afterSalesServiceNewDto.getCheckUserId());
        if(sysUser == null) throw new RuntimeException("审核人不存在");
        afterSalesServiceNewDto.setCheckNickName(sysUser.getNickName());
        if (StringUtils.isEmpty(afterSalesServiceNewDto.getAfterSalesServiceNo())) {
            String string = OrderUtils.countAfterServiceTodayByCreateTime(afterSalesServiceMapper, "SH_");
            afterSalesServiceNewDto.setAfterSalesServiceNo(string);
        }
        return this.save(afterSalesServiceNewDto);
    }
    @Override
    public AfterSalesServiceNewDto getAfterSalesServiceNewDtoById(Long id) {
        AfterSalesService afterSalesService = afterSalesServiceMapper.selectById(id);
        SalesLedger byId = salesLedgerService.getById(afterSalesService.getSalesLedgerId());
        List<Long> collect = Arrays.stream(afterSalesService.getProductModelIds().split(",")).map(Long::valueOf).collect(Collectors.toList());
        List<SalesLedgerProduct> list = salesLedgerProductService.list(new QueryWrapper<SalesLedgerProduct>().lambda().in(SalesLedgerProduct::getProductModelId, collect));
        if (afterSalesService == null) {
            throw new RuntimeException("售后工单不存在");
        }
        // 工单可以不关联产品(反馈登记导入、历史数据都是空),此处必须容错
        List<Long> collect = StringUtils.isEmpty(afterSalesService.getProductModelIds())
                ? new ArrayList<>()
                : Arrays.stream(afterSalesService.getProductModelIds().split(","))
                        .filter(StringUtils::isNotEmpty)
                        .map(Long::valueOf)
                        .collect(Collectors.toList());
        List<SalesLedgerProduct> list = collect.isEmpty()
                ? new ArrayList<>()
                : salesLedgerProductService.list(new QueryWrapper<SalesLedgerProduct>().lambda().in(SalesLedgerProduct::getId, collect));
        if (StringUtils.isNotEmpty(afterSalesService.getProductModelQuantities())) {
            String[] quantities = afterSalesService.getProductModelQuantities().split(",");
            for (int i = 0; i < collect.size(); i++) {
                Long productId = collect.get(i);
                for (SalesLedgerProduct product : list) {
                    if (product.getId().equals(productId)) {
                        if (i < quantities.length && StringUtils.isNotEmpty(quantities[i])) {
                            product.setQuantity(new java.math.BigDecimal(quantities[i]));
                        }
                        break;
                    }
                }
            }
        }
        for (SalesLedgerProduct product : list) {
            com.ruoyi.sales.pojo.ShippingInfo shippingInfo = shippingInfoMapper.selectOne(
                new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<com.ruoyi.sales.pojo.ShippingInfo>()
                    .eq(com.ruoyi.sales.pojo.ShippingInfo::getSalesLedgerProductId, product.getId())
                    .orderByDesc(com.ruoyi.sales.pojo.ShippingInfo::getCreateTime)
                    .last("limit 1")
            );
            if (shippingInfo != null) {
                product.setShippingCarNumber(shippingInfo.getShippingCarNumber());
                product.setShippingDate(shippingInfo.getShippingDate());
                product.setShippingStatus(shippingInfo.getStatus());
                product.setExpressCompany(shippingInfo.getExpressCompany());
                product.setExpressNumber(shippingInfo.getExpressNumber());
            }
        }
        AfterSalesServiceNewDto afterSalesServiceNewDto = new AfterSalesServiceNewDto();
        BeanUtils.copyProperties(afterSalesService, afterSalesServiceNewDto);
        SalesLedgerDto salesLedgerDto = new SalesLedgerDto();
        BeanUtils.copyProperties(byId, salesLedgerDto);
        if (afterSalesService.getSalesLedgerId() != null) {
            SalesLedger byId = salesLedgerService.getById(afterSalesService.getSalesLedgerId());
            if (byId != null) {
                BeanUtils.copyProperties(byId, salesLedgerDto);
            }
        }
        salesLedgerDto.setProductData( list);
        afterSalesServiceNewDto.setSalesLedgerDto(salesLedgerDto);
        return afterSalesServiceNewDto;
    }
    @Override
    public List<CountDto> countAfterSalesService() {
        List<CountDto> stringIntegerHashMap = afterSalesServiceMapper.countAfterSalesService();
        Integer total = 0;
        for (CountDto countDto : stringIntegerHashMap) {
            total += countDto.getCount();
        }
        CountDto countDto = new CountDto();
        countDto.setStatus(3);
        countDto.setCount(total);
        stringIntegerHashMap.add(countDto);
        return stringIntegerHashMap;
    }
    @Override
    public AjaxResult importData(MultipartFile file) {
        List<AfterSalesServiceImportDto> rows;
        try {
            ExcelUtil<AfterSalesServiceImportDto> util = new ExcelUtil<>(AfterSalesServiceImportDto.class);
            rows = util.importExcel(file.getInputStream());
        } catch (Exception e) {
            log.error("反馈登记导入-解析excel失败", e);
            return AjaxResult.error("解析Excel失败:" + e.getMessage());
        }
        if (CollectionUtils.isEmpty(rows)) {
            return AjaxResult.error("导入文件无数据");
        }
        Long tenantId = SecurityUtils.getLoginUser().getTenantId();
        Long userId = SecurityUtils.getUserId();
        int success = 0;
        List<String> errors = new ArrayList<>();
        for (int i = 0; i < rows.size(); i++) {
            AfterSalesServiceImportDto row = rows.get(i);
            int rowNo = i + 2; // 首行为表头
            try {
                String customerName = trim(row.getCustomerName());
                if (StringUtils.isEmpty(customerName)) {
                    errors.add("第" + rowNo + "行:客户名称为空");
                    continue;
                }
                Customer customer = findCustomerByName(customerName, tenantId);
                if (customer == null) {
                    errors.add("第" + rowNo + "行:客户[" + customerName + "]不存在");
                    continue;
                }
                String serviceTypeName = trim(row.getServiceType());
                String serviceTypeValue = dictValueByLabel("post_sale_waiting_list", serviceTypeName);
                if (StringUtils.isEmpty(serviceTypeValue)) {
                    errors.add("第" + rowNo + "行:售后类型[" + serviceTypeName + "]不存在");
                    continue;
                }
                String urgencyName = trim(row.getUrgency());
                String urgencyValue = dictValueByLabel("degree_of_urgency", urgencyName);
                if (StringUtils.isEmpty(urgencyValue)) {
                    errors.add("第" + rowNo + "行:紧急程度[" + urgencyName + "]不存在");
                    continue;
                }
                Long salesLedgerId = null;
                String contractNo = trim(row.getSalesContractNo());
                if (StringUtils.isNotEmpty(contractNo)) {
                    SalesLedger ledger = salesLedgerMapper.selectOne(new LambdaQueryWrapper<SalesLedger>()
                            .eq(SalesLedger::getSalesContractNo, contractNo)
                            .eq(SalesLedger::getCustomerId, customer.getId())
                            .last("limit 1"));
                    if (ledger == null) {
                        ledger = salesLedgerMapper.selectOne(new LambdaQueryWrapper<SalesLedger>()
                                .eq(SalesLedger::getSalesContractNo, contractNo)
                                .last("limit 1"));
                    }
                    if (ledger == null) {
                        errors.add("第" + rowNo + "行:销售单号[" + contractNo + "]不存在");
                        continue;
                    }
                    salesLedgerId = ledger.getId();
                }
                AfterSalesServiceNewDto dto = new AfterSalesServiceNewDto();
                dto.setCustomerName(customer.getCustomerName());
                dto.setSalesLedgerId(salesLedgerId);
                dto.setServiceType(serviceTypeValue);
                dto.setUrgency(urgencyValue);
                dto.setProDesc(row.getProDesc());
                dto.setFeedbackDate(row.getFeedbackDate() != null ? row.getFeedbackDate() : new Date());
                dto.setCheckUserId(userId);
                dto.setProductModelIds("");
                dto.setProductModelQuantities("");
                if (addAfterSalesServiceDto(dto)) {
                    success++;
                } else {
                    errors.add("第" + rowNo + "行:保存失败");
                }
            } catch (Exception e) {
                log.error("反馈登记导入第{}行失败", rowNo, e);
                errors.add("第" + rowNo + "行:" + e.getMessage());
            }
        }
        AjaxResult result = AjaxResult.success();
        result.put("totalCount", rows.size());
        result.put("successCount", success);
        result.put("failCount", rows.size() - success);
        result.put("errors", errors);
        result.put("msg", "导入完成:成功 " + success + " 条,失败 " + (rows.size() - success) + " 条");
        return result;
    }
    private String trim(String value) {
        return value == null ? null : value.trim();
    }
    private Customer findCustomerByName(String name, Long tenantId) {
        List<Customer> customers = customerMapper.selectList(new LambdaQueryWrapper<Customer>()
                .eq(Customer::getCustomerName, name));
        if (CollectionUtils.isEmpty(customers)) {
            return null;
        }
        if (tenantId != null) {
            for (Customer c : customers) {
                if (tenantId.equals(c.getTenantId())) {
                    return c;
                }
            }
        }
        return customers.get(0);
    }
    private String dictValueByLabel(String dictType, String label) {
        if (StringUtils.isEmpty(label)) {
            return null;
        }
        List<SysDictData> datas = sysDictDataMapper.selectDictDataByType(dictType);
        if (CollectionUtils.isEmpty(datas)) {
            return null;
        }
        for (SysDictData d : datas) {
            if (label.equals(d.getDictLabel())) {
                return d.getDictValue();
            }
        }
        return null;
    }
}