package org.springblade.mdm.machinefile.service; import com.baomidou.mybatisplus.core.metadata.IPage; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.springblade.core.log.exception.ServiceException; import org.springblade.core.mp.base.BizServiceImpl; import org.springblade.core.mp.support.Condition; import org.springblade.core.oss.OssTemplate; import org.springblade.core.oss.model.BladeFile; import org.springblade.mdm.basesetting.machine.service.MachineService; import org.springblade.mdm.basesetting.machine.entity.Machine; import org.springblade.mdm.commons.service.MachineDirTranslator; import org.springblade.mdm.machinefile.entity.MachineFile; import org.springblade.mdm.machinefile.entity.MachineFileChangeHis; import org.springblade.mdm.machinefile.mapper.MachineFileMapper; import org.springblade.mdm.machinefile.vo.MachineFileQueryVO; import org.springblade.mdm.machinefile.vo.MachineBackFileQueryVO; import org.springblade.mdm.program.vo.CompareDataVO; import org.springblade.mdm.statreport.vo.MachineFileExceptionQueryVO; import org.springblade.mdm.utils.FileContentUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Optional; /** * 机床文件 * * @author yangys */ @Slf4j @Service @AllArgsConstructor public class MachineFileService extends BizServiceImpl { private final MachineService machineService; private final MachineFileChangeHisService machineFileChangeHisService; private final OssTemplate ossTemplate; private MachineDirTranslator machineDirTranslator; /** * 获取文件全路径 * @param id 数据id * @return 文件全路径 */ public String getFilePath(Long id) { MachineFile machineFile = getById(id); Machine machine = machineService.getByCode(machineFile.getMachineCode()); return getBasePath(machine, machineFile.getDirType()) + File.separator + machineFile.getName(); } public String getFilePath(MachineFile machineFile) { Machine machine = machineService.getByCode(machineFile.getMachineCode()); return getBasePath(machine, machineFile.getDirType()) + File.separator + machineFile.getName(); } @Transactional(readOnly = true) public String getMachineFileContent(Long id) { MachineFile machineFile = getById(id); Machine machine = machineService.getByCode(machineFile.getMachineCode()); String filePathStr = getBasePath(machine,machineFile.getDirType())+ File.separator+machineFile.getName(); String content; Path filePath = Paths.get(filePathStr); if(!filePath.toFile().exists()){ return StringUtils.EMPTY; } try (InputStream inputStream = Files.newInputStream(filePath)) { // 使用输入流读取文件内容 content = FileContentUtil.getContentFromStream(inputStream); } catch (IOException e) { log.error("读取文件md5失败",e); return StringUtils.EMPTY; } return content; } /** * 获取基本路径 * @param machine 机床 * @param dirType 目录类型 * @return 目录基本路径 */ public static String getBasePath(Machine machine,String dirType){ String dirPath; switch (dirType) { case MachineFile.DIR_TYPE_REC: dirPath = machine.getProgReceiveDir(); break; case MachineFile.DIR_TYPE_SEND: dirPath = machine.getProgSendDir(); break; case MachineFile.DIR_TYPE_TEMP: dirPath = machine.getProgTempDir(); break; default: log.warn("目录类型不匹配:{}",dirType); return null;//不符合任何类型,直接退出 } return dirPath; } @Transactional public void saveFileContent(Long id, String content) throws IOException { MachineFile machineFile = getById(id); Machine machine = machineService.getByCode(machineFile.getMachineCode()); String filePathStr = getBasePath(machine,machineFile.getDirType())+ File.separator+machineFile.getName(); Path filePath = Paths.get(filePathStr); String ossName; BladeFile bfile; try (InputStream inputStream = Files.newInputStream(filePath)) { bfile = ossTemplate.putFile(machineFile.getName(), inputStream); } ossName =bfile.getName(); try (InputStream inputStream = Files.newInputStream(filePath)) { // 使用输入流读取文件内容 String charsetName = FileContentUtil.detectFromInputStream(inputStream); FileUtils.writeStringToFile(filePath.toFile(),content,charsetName); } catch (IOException e) { log.error("读取文件编码失败",e); throw new ServiceException("获取文件编码失败"); } try (InputStream inputStream = Files.newInputStream(filePath)) { bfile = ossTemplate.putFile(machineFile.getName(), inputStream); } //保存历史记录 MachineFileChangeHis his = new MachineFileChangeHis(); his.setMachineFileId(id); his.setOssName(ossName); his.setOssNameAfter(bfile.getName()); this.machineFileChangeHisService.save(his); } /** * 获取文件的输入流 * @param machineFile * @return * @throws IOException */ public InputStream getInputStream(MachineFile machineFile) throws IOException { Machine machine = machineService.getByCode(machineFile.getMachineCode()); String filePathStr = getBasePath(machine,machineFile.getDirType())+ File.separator+machineFile.getName(); Path filePath = Paths.get(filePathStr); return Files.newInputStream(filePath); } @Transactional(readOnly = true) public IPage filePageForAccept(MachineBackFileQueryVO query) { return this.baseMapper.filePageForAccept(Condition.getPage(query),query); } public MachineFile getExistsFile(String name, String dirType, String machineCode) { return this.lambdaQuery().eq(MachineFile::getName, name) .eq(MachineFile::getDirType, dirType) .eq(MachineFile::getMachineCode, machineCode).list().stream().findFirst().orElse(null); } /** * 回传程序处理 分页查询 * @param query * @return */ /* public IPage handlePageQuery(MachineAcceptedFileHandleQueryVO query) { IPage page = this.getBaseMapper().handlePageQuery(Condition.getPage(query),query); return page; }*/ /** * 机床文件分页查询 * @param query * @return */ public IPage pageQuery(MachineFileQueryVO query) { return baseMapper.pageQuery(Condition.getPage(query),query); } /** * 获取修改记录前后2个文件内容 * @param id * @return * @throws IOException */ public CompareDataVO queryHisContentForCompare(Long id) throws IOException { CompareDataVO vo = new CompareDataVO(); MachineFileChangeHis his = machineFileChangeHisService.getById(id); vo.setContent1(FileContentUtil.getContentFromStream(ossTemplate.statFileStream(his.getOssName()))); vo.setContent2(FileContentUtil.getContentFromStream(ossTemplate.statFileStream(his.getOssNameAfter()))); return vo; } /** * 刷新文件信息,不存在新增,存在则更新 * @param mf */ public void refreshFileData(MachineFile mf) { MachineFile existFileInDb = getExistsFile(mf.getName(),mf.getDirType(),mf.getMachineCode()); if(existFileInDb == null) { save(mf); }else{ log.info("文件在库中已存在:{}",mf.getName()); existFileInDb.setFileSize(mf.getFileSize()); existFileInDb.setProgramStatus(mf.getProgramStatus()); existFileInDb.setFileCreateTime(mf.getFileCreateTime()); existFileInDb.setFileModifyTime(mf.getFileModifyTime()); existFileInDb.setStatus(MachineFile.STATUS_NORMAL); if(!com.alibaba.excel.util.StringUtils.equals(existFileInDb.getMd5(),mf.getMd5())){ //文件内容发生变化了,设置状态为初始状态 existFileInDb.setStatus(MachineFile.STATUS_NORMAL); } existFileInDb.setMd5(mf.getMd5()); updateById(existFileInDb); } } /** * 物理删除文件信息 * @param id 数据id */ public void deleteById(Long id) { baseMapper.deleteById(id); } /** * 异常文件记录查询 * @param query * @return */ @Transactional(readOnly = true) public IPage exceptionFilePageQuery(MachineFileExceptionQueryVO query) { return baseMapper.exceptionFilePageQuery(Condition.getPage(query),query); } /** * 修改文件名称 * @param id 文件id * @param name 新名称 */ public void changeName(Long id, String name) throws IOException { MachineFile machineFile = getById(id); if(machineFile.getName().equals(name)) { return; } Machine machine = machineService.getByCode(machineFile.getMachineCode()); String baseDir = machineDirTranslator.trans(getBasePath(machine,machineFile.getDirType())); String targetFilePath = baseDir + File.separator + name; Path filePath = Paths.get(targetFilePath); if(filePath.toFile().exists()) { throw new ServiceException("同名文件已存在:"+name); } Files.move(Paths.get(baseDir+File.separator+machineFile.getName()),filePath); baseMapper.deleteById(id); } public MachineFile getByNameAndMachineInDir(String name, String machineCode, String dirType) { Optional optFIle = this.lambdaQuery().eq(MachineFile::getName, name).eq(MachineFile::getMachineCode, machineCode) .eq(MachineFile::getDirType, dirType).eq(MachineFile::getStatus, MachineFile.STATUS_NORMAL).oneOpt(); return optFIle.orElse(null); } }