package com.ruoyi.basic.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.basic.dto.CustomerFollowUpDto;
import com.ruoyi.basic.mapper.CustomerFollowUpMapper;
import com.ruoyi.basic.pojo.CustomerFollowUp;
import com.ruoyi.basic.pojo.CustomerFollowUpFile;
import com.ruoyi.basic.service.CustomerFollowUpFileService;
import com.ruoyi.basic.service.CustomerFollowUpService;
import com.ruoyi.basic.service.ICustomerService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
/**
*
* 客户根据接口实现类
*
*
* @author deslrey
* @version 1.0
* @since 2026/03/04 14:48
*/
@Service
public class CustomerFollowUpServiceImpl extends ServiceImpl implements CustomerFollowUpService {
@Autowired
private CustomerFollowUpFileService customerFollowUpFileService;
@Value("${file.upload-dir}")
private String uploadDir;
@Override
@Transactional(rollbackFor = Exception.class)
public boolean insertCustomerFollowUp(CustomerFollowUp customerFollowUp) {
validateFollowUp(customerFollowUp);
Long currentUserId = SecurityUtils.getUserId();
Long currentTenantId = SecurityUtils.getLoginUser().getTenantId();
customerFollowUp.setFollowerUserId(currentUserId);
customerFollowUp.setCreateTime(LocalDateTime.now());
customerFollowUp.setTenantId(currentTenantId);
int result = baseMapper.insert(customerFollowUp);
if (result < 1) {
throw new ServiceException("客户跟进数据添加失败");
}
return true;
}
@Override
public int updateCustomerFollowUp(CustomerFollowUp customerFollowUp) {
validateFollowUp(customerFollowUp);
customerFollowUp.setUpdateTime(LocalDateTime.now());
return baseMapper.updateById(customerFollowUp);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void addFollowUpFiles(List files, Integer followUpId) {
handleFollowUpFiles(files, followUpId);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteFollowUpFile(Integer fileId) {
CustomerFollowUpFile file = customerFollowUpFileService.getById(fileId);
if (file != null) {
try {
Files.deleteIfExists(Paths.get(file.getFileUrl()));
} catch (Exception e) {
throw new ServiceException("删除文件失败:" + e.getMessage());
}
customerFollowUpFileService.removeById(fileId);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public int deleteCustomerFollowUpById(Integer id) {
if (id == null) {
throw new ServiceException("跟进ID不能为空");
}
List files = customerFollowUpFileService.list(new LambdaQueryWrapper()
.eq(CustomerFollowUpFile::getFollowUpId, id));
if (files != null && !files.isEmpty()) {
for (CustomerFollowUpFile file : files) {
deleteFollowUpFile(file.getId().intValue());
}
}
int result = baseMapper.deleteById(id);
if (result < 1) {
throw new ServiceException("客户跟进记录删除失败");
}
return result;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteByCustomerId(Long customerId) {
if (customerId == null) {
throw new ServiceException("客户ID不能为空");
}
List followUps = list(new LambdaQueryWrapper()
.eq(CustomerFollowUp::getCustomerId, customerId));
if (followUps != null && !followUps.isEmpty()) {
for (CustomerFollowUp followUp : followUps) {
deleteCustomerFollowUpById(followUp.getId());
}
}
}
private void handleFollowUpFiles(List multipartFiles, Integer followUpId) {
if (multipartFiles == null || multipartFiles.isEmpty()) {
return;
}
Long currentUserId = SecurityUtils.getUserId();
Long currentTenantId = SecurityUtils.getLoginUser().getTenantId();
List fileList = new ArrayList<>();
for (MultipartFile file : multipartFiles) {
if (file == null || file.isEmpty()) {
continue;
}
try {
String formalDir = uploadDir + "/" + LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE);
Path formalDirPath = Paths.get(formalDir);
if (!Files.exists(formalDirPath)) {
Files.createDirectories(formalDirPath);
}
String originalFilename = file.getOriginalFilename();
String fileExtension = FilenameUtils.getExtension(originalFilename);
String formalFilename = followUpId + "_" +
System.currentTimeMillis() + "_" +
UUID.randomUUID().toString().substring(0, 8) +
(StringUtils.hasText(fileExtension) ? "." + fileExtension : "");
Path formalFilePath = formalDirPath.resolve(formalFilename);
file.transferTo(formalFilePath.toFile());
CustomerFollowUpFile followUpFile = new CustomerFollowUpFile();
followUpFile.setFollowUpId(followUpId);
followUpFile.setFileName(originalFilename);
followUpFile.setFileUrl(formalFilePath.toString());
followUpFile.setFileSize(file.getSize());
followUpFile.setFileSuffix(fileExtension);
followUpFile.setCreateUser(currentUserId);
followUpFile.setCreateTime(LocalDateTime.now());
followUpFile.setTenantId(currentTenantId);
fileList.add(followUpFile);
} catch (Exception e) {
throw new ServiceException("文件 [" + file.getOriginalFilename() + "] 上传失败:" + e.getMessage());
}
}
if (!fileList.isEmpty()) {
customerFollowUpFileService.saveBatch(fileList);
}
}
private void validateFollowUp(CustomerFollowUp followUp) {
if (followUp == null) {
throw new ServiceException("跟进数据不能为空");
}
if (StringUtils.isEmpty(followUp.getFollowUpMethod())) {
throw new ServiceException("跟进方式不能为空");
}
if (StringUtils.isEmpty(followUp.getFollowUpLevel())) {
throw new ServiceException("跟进程度不能为空");
}
if (followUp.getFollowUpTime() == null) {
throw new ServiceException("跟进时间不能为空");
}
if (StringUtils.isEmpty(followUp.getFollowerUserName())) {
throw new ServiceException("跟进人不能为空");
}
if (StringUtils.isEmpty(followUp.getContent())) {
throw new ServiceException("跟进内容不能为空");
}
}
@Override
public CustomerFollowUpDto getFollowUpWithFiles(Integer id) {
CustomerFollowUp followUp = baseMapper.selectById(id);
if (followUp == null) {
return null;
}
CustomerFollowUpDto dto = new CustomerFollowUpDto();
BeanUtils.copyProperties(followUp, dto);
List fileList = customerFollowUpFileService.list(new LambdaQueryWrapper()
.eq(CustomerFollowUpFile::getFollowUpId, id));
dto.setFileList(fileList);
return dto;
}
}