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 lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; 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; /** * @author :yys * @date : 2025/7/30 9:26 */ @Service @Slf4j @RequiredArgsConstructor public class AfterSalesServiceServiceImpl extends ServiceImpl implements AfterSalesServiceService { 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 listPage(Page page, AfterSalesServiceNewDto afterSalesService) { Long tenantId = SecurityUtils.getLoginUser().getTenantId(); SysDept sysDept = sysDeptMapper.selectDeptById(tenantId); IPage afterSalesServiceIPage = afterSalesServiceMapper.listPage(page, afterSalesService); afterSalesServiceIPage.getRecords().forEach(item -> { item.setDeptName(sysDept.getDeptName()); }); return afterSalesServiceIPage; } @Override public boolean addAfterSalesServiceDto(AfterSalesServiceNewDto afterSalesServiceNewDto) { afterSalesServiceNewDto.setStatus(1); if (afterSalesServiceNewDto.getProductModelIdList() != null && afterSalesServiceNewDto.getProductModelIdList().isEmpty() ) { String productModelIds = afterSalesServiceNewDto.getProductModelIdList().stream() .map(String::valueOf) .collect(Collectors.joining(",")); afterSalesServiceNewDto.setProductModelIds(productModelIds); } 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); if (afterSalesService == null) { throw new RuntimeException("售后工单不存在"); } // 工单可以不关联产品(反馈登记导入、历史数据都是空),此处必须容错 List collect = StringUtils.isEmpty(afterSalesService.getProductModelIds()) ? new ArrayList<>() : Arrays.stream(afterSalesService.getProductModelIds().split(",")) .filter(StringUtils::isNotEmpty) .map(Long::valueOf) .collect(Collectors.toList()); List list = collect.isEmpty() ? new ArrayList<>() : salesLedgerProductService.list(new QueryWrapper().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() .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(); 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 countAfterSalesService() { List 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 rows; try { ExcelUtil 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 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() .eq(SalesLedger::getSalesContractNo, contractNo) .eq(SalesLedger::getCustomerId, customer.getId()) .last("limit 1")); if (ledger == null) { ledger = salesLedgerMapper.selectOne(new LambdaQueryWrapper() .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 customers = customerMapper.selectList(new LambdaQueryWrapper() .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 datas = sysDictDataMapper.selectDictDataByType(dictType); if (CollectionUtils.isEmpty(datas)) { return null; } for (SysDictData d : datas) { if (label.equals(d.getDictLabel())) { return d.getDictValue(); } } return null; } }