package org.springblade.mdm.basesetting.machine.service;
|
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.toolkit.MybatisUtils;
|
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.tool.api.R;
|
import org.springblade.core.tool.utils.BeanUtil;
|
import org.springblade.core.tool.utils.Func;
|
import org.springblade.core.tool.utils.SpringUtil;
|
import org.springblade.mdm.basesetting.machine.entity.Machine;
|
import org.springblade.mdm.basesetting.machine.mapper.MachineMapper;
|
import org.springblade.mdm.basesetting.machine.vo.MachineQueryVO;
|
import org.springblade.mdm.basesetting.machine.vo.MachineSaveVO;
|
import org.springblade.mdm.basesetting.machine.vo.MachineVO;
|
import org.springblade.mdm.basesetting.producedivision.service.MdmDeptService;
|
import org.springblade.mdm.commons.service.MachineDirTranslator;
|
import org.springblade.mdm.commons.service.ParamService;
|
import org.springblade.mdm.machinefile.entity.MachineFile;
|
import org.springblade.mdm.machinefile.filewatch.DynamicDirectoryWatcher;
|
import org.springblade.mdm.machinefile.filewatch.MachineFileChangeListener;
|
import org.springblade.mdm.machinefile.filewatch.WatchInfo;
|
import org.springblade.mdm.machinefile.service.MachineFileService;
|
import org.springblade.mdm.program.service.ProgramAnnotationService;
|
import org.springblade.system.feign.ISysClient;
|
import org.springblade.system.pojo.entity.Dept;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.io.IOException;
|
import java.nio.file.Files;
|
import java.nio.file.InvalidPathException;
|
import java.nio.file.Path;
|
import java.nio.file.Paths;
|
import java.util.List;
|
import java.util.Optional;
|
|
@Service
|
public class MachineService extends BizServiceImpl<MachineMapper, Machine> {
|
@Autowired
|
private ISysClient sysClient;
|
@Autowired
|
private DynamicDirectoryWatcher dynamicDirectoryWatcher;
|
@Autowired
|
private ParamService paramService;
|
@Autowired
|
private MachineDirTranslator machineDirTranslator;
|
|
@Transactional(rollbackFor = Exception.class)
|
public void saveMachine(MachineSaveVO vo) throws IOException {
|
checkMachine(vo);
|
if(existsByCode(vo.getCode(),null)){
|
throw new ServiceException("机床编码已存在:"+vo.getCode());
|
}
|
if(existsByEquipmentCode(vo.getEquipmentCode(),null)){
|
throw new ServiceException("设备编号已存在:"+vo.getEquipmentCode());
|
}
|
|
Machine machine = new Machine();
|
BeanUtil.copyProperties(vo, machine);
|
machine.setId(null);
|
this.save(machine);
|
makeMachineDirs(machine);
|
addDirWatcher(machine);
|
}
|
|
|
void makeMachineDirs(Machine machine) throws IOException {
|
Path dir;
|
if(StringUtils.isNotBlank(machine.getProgSendDir())){
|
createDirIsNotExists(machineDirTranslator.trans(machine.getProgSendDir()));
|
}
|
|
if(StringUtils.isNotBlank(machineDirTranslator.trans(machine.getProgReceiveDir()))){
|
createDirIsNotExists(machineDirTranslator.trans(machine.getProgReceiveDir()));
|
}
|
|
if(StringUtils.isNotBlank(machineDirTranslator.trans(machine.getProgTempDir()))){
|
createDirIsNotExists(machineDirTranslator.trans(machine.getProgTempDir()));
|
}
|
}
|
|
void createDirIsNotExists(String pathdir) throws IOException {
|
Path dir = Paths.get(pathdir);
|
if(!Files.exists(dir)){
|
Files.createDirectories(dir);
|
}
|
}
|
void addDirWatcher(Machine machine){
|
String type = paramService.networkType();
|
if(type.equals(ParamService.NETWORK_TYPE_SHEMI)){
|
//涉密网不需要监控目录
|
return;
|
}
|
try {
|
MachineFileService machineFileService = SpringUtil.getBean(MachineFileService.class);
|
ProgramAnnotationService annoService = SpringUtil.getBean(ProgramAnnotationService.class);
|
|
if(StringUtils.isNotBlank(machine.getProgSendDir())) {
|
|
String sendDir = machineDirTranslator.trans(machine.getProgSendDir());
|
|
WatchInfo watchInfoSend = new WatchInfo();
|
watchInfoSend.setMachine(machine);
|
watchInfoSend.setDirType(MachineFile.DIR_TYPE_SEND);
|
watchInfoSend.setPath(sendDir);
|
|
Path path = Paths.get(sendDir);
|
if(!dynamicDirectoryWatcher.containsPath(path)) {
|
dynamicDirectoryWatcher.addDirectory(path,
|
new MachineFileChangeListener(machineFileService,
|
annoService,
|
watchInfoSend));
|
}
|
}
|
|
if(StringUtils.isNotBlank(machine.getProgReceiveDir())) {
|
|
String recDir = machineDirTranslator.trans(machine.getProgReceiveDir());
|
|
WatchInfo watchInfoRec = new WatchInfo();
|
watchInfoRec.setMachine(machine);
|
watchInfoRec.setDirType(MachineFile.DIR_TYPE_REC);
|
watchInfoRec.setPath(recDir);
|
Path path = Paths.get(recDir);
|
if(!dynamicDirectoryWatcher.containsPath(path)) {
|
dynamicDirectoryWatcher.addDirectory(path,
|
new MachineFileChangeListener(machineFileService,
|
annoService,
|
watchInfoRec));
|
}
|
}
|
|
if(StringUtils.isNotBlank(machine.getProgTempDir())) {
|
String tempDir = machineDirTranslator.trans(machine.getProgTempDir());
|
WatchInfo watchInfoTemp = new WatchInfo();
|
watchInfoTemp.setMachine(machine);
|
watchInfoTemp.setDirType(MachineFile.DIR_TYPE_TEMP);
|
watchInfoTemp.setPath(tempDir);
|
Path path = Paths.get(machine.getProgTempDir());
|
if(!dynamicDirectoryWatcher.containsPath(path)) {
|
dynamicDirectoryWatcher.addDirectory(path,
|
new MachineFileChangeListener(machineFileService,
|
annoService,
|
watchInfoTemp));
|
}
|
}
|
} catch (Exception e) {
|
log.error("增加机床监控异常",e);
|
throw new RuntimeException(e);
|
}
|
}
|
/**
|
* 检查机床录入数据
|
* @param vo 录入的表单数据VO
|
*/
|
void checkMachine(MachineSaveVO vo){
|
if(Func.isEmpty(vo.getCode())){
|
throw new ServiceException("机床编码不能为空");
|
}
|
|
if(Func.isEmpty(vo.getName())){
|
throw new ServiceException("机床类型不能为空");
|
}
|
|
if(Func.isEmpty(vo.getMachineGroupCode())){
|
throw new ServiceException("所属组织不能为空");
|
}
|
|
if(Func.isEmpty(vo.getMachineSpec())){
|
throw new ServiceException("机床类型不能为空");
|
}
|
}
|
|
/**
|
* 根据机床编码判断机床是否存在
|
* @param code 机床编码
|
* @param excludeId 排除id
|
* @return 是否存在
|
*/
|
boolean existsByCode(String code,Long excludeId){
|
return this.lambdaQuery().eq(Machine::getCode, code).ne(excludeId!=null,Machine::getId, excludeId).count()>0;
|
}
|
|
/**
|
* 根据 设备编号判断机床是否存在
|
* @param equipmentCode 设备编号
|
* @param excludeId 排除id
|
* @return 是否存在
|
*/
|
boolean existsByEquipmentCode(String equipmentCode,Long excludeId){
|
return this.lambdaQuery().eq(Machine::getEquipmentCode, equipmentCode).ne(excludeId!=null,Machine::getId, excludeId).count()>0;
|
}
|
|
|
/**
|
* 修改机床信息
|
* @param vo
|
* @return
|
*/
|
public boolean updateMachine(MachineSaveVO vo) throws Exception {
|
|
checkMachine(vo);
|
if(existsByCode(vo.getCode(),vo.getId())){
|
throw new ServiceException("机床编码已存在:"+vo.getCode());
|
}
|
if(existsByEquipmentCode(vo.getEquipmentCode(),vo.getId())){
|
throw new ServiceException("设备编号已存在:"+vo.getEquipmentCode());
|
}
|
Machine machine = this.getById(vo.getId());
|
|
Machine machineBak = new Machine();
|
BeanUtil.copyProperties(machine, machineBak);
|
|
machine.setMachineSpec(vo.getMachineSpec());
|
machine.setCode(vo.getCode());
|
machine.setEquipmentCode(vo.getEquipmentCode());
|
machine.setName(vo.getName());
|
machine.setMachineGroupCode(vo.getMachineGroupCode());
|
machine.setManufacturer(vo.getManufacturer());
|
machine.setOperator(vo.getOperator());
|
machine.setControlSystem(vo.getControlSystem());
|
machine.setOwnerDept(vo.getOwnerDept());
|
machine.setProgSendDir(vo.getProgSendDir());
|
machine.setProgReceiveDir(vo.getProgReceiveDir());
|
machine.setProgTempDir(vo.getProgTempDir());
|
machine.setStatus(vo.getStatus());
|
machine.setRemark(vo.getRemark());
|
machine.setSendDirExpiryHours(vo.getSendDirExpiryHours());
|
machine.setReceiveDirExpiryHours(vo.getReceiveDirExpiryHours());
|
|
boolean updateR = this.updateById(machine);
|
removeDirWatcher(machineBak);
|
addDirWatcher(machine);
|
|
return updateR;
|
}
|
|
/**
|
* 去掉目录监控
|
* @param machine
|
* @throws Exception
|
*/
|
private void removeDirWatcher(Machine machine) throws Exception {
|
String type = paramService.networkType();
|
if(type.equals(ParamService.NETWORK_TYPE_SHEMI)){
|
//涉密网不需要监控目录
|
return;
|
}
|
if(StringUtils.isNotBlank(machine.getProgSendDir())) {
|
dynamicDirectoryWatcher.removeDirectory(Paths.get(machine.getProgSendDir()));
|
}
|
|
if(StringUtils.isNotBlank(machine.getProgReceiveDir())) {
|
dynamicDirectoryWatcher.removeDirectory(Paths.get(machine.getProgReceiveDir()));
|
}
|
|
if(StringUtils.isNotBlank(machine.getProgTempDir())) {
|
dynamicDirectoryWatcher.removeDirectory(Paths.get(machine.getProgTempDir()));
|
}
|
}
|
|
/**
|
* 查询分页
|
* @param query 查询参数
|
* @return 分页数据
|
*/
|
public IPage<MachineVO> pageQuery(MachineQueryVO query) {
|
|
if (query.getDeptId() != null) {
|
R<Dept> rs = sysClient.getDept(query.getDeptId());
|
if(rs.isSuccess()){
|
query.setDeptAncestors(rs.getData().getAncestors()+","+rs.getData().getId());
|
}
|
}
|
return this.getBaseMapper().pageQuery(Condition.getPage(query), query);
|
}
|
|
/**
|
* 查询详情
|
* @param id 机床id
|
* @return
|
*/
|
public MachineVO detail(long id) {
|
Machine machine = this.getById(id);
|
|
MachineVO vo = new MachineVO();
|
BeanUtil.copyProperties(machine, vo);
|
|
return vo;
|
}
|
|
/**
|
* 产生机床回传结构数据
|
* @param id
|
*/
|
/*
|
public void genMachineFileBackDirs(Long id) throws IOException {
|
Machine machine = this.getById(id);
|
if(Func.isNotBlank(machine.getProgReceiveDir())){
|
if(isLegalDirectoryPath(machine.getProgReceiveDir())) {
|
Path path = Paths.get(machine.getProgReceiveDir());
|
Files.createDirectories(path);
|
}else{
|
throw new RuntimeException("非法的目录格式");
|
}
|
}
|
}*/
|
|
/**
|
* 判断是否是合法的目录格式
|
* @param path
|
* @return
|
*/
|
static boolean isLegalDirectoryPath(String path) {
|
// 基础检查
|
if (path == null || path.trim().isEmpty()) {
|
return false;
|
}
|
|
// 使用NIO检查路径格式
|
Path nioPath;
|
try {
|
nioPath = Paths.get(path);
|
if (!nioPath.normalize().toString().equals(path)) {
|
return false; // 路径不规范
|
}
|
} catch (InvalidPathException ex) {
|
return false;
|
}
|
|
return true;
|
|
}
|
|
/**
|
* 根据机床编码获取机床
|
* @param machineCode 机床编码
|
* @return
|
*/
|
public Machine getByCode(String machineCode) {
|
return this.lambdaQuery().eq(Machine::getCode, machineCode).one();
|
}
|
|
/**
|
* 获取所有启用状态的机床列表
|
* @return 机床列表
|
*/
|
public List<Machine> getEnableMachines() {
|
return lambdaQuery().eq(Machine::getStatus,Machine.STATUS_ENABLE).list();
|
}
|
|
public String escapeSqlWildcard(String value) {
|
if (StringUtils.isBlank(value)) {
|
return value;
|
}
|
return value.replace("\\", "\\\\")
|
.replace("%", "\\%")
|
.replace("_", "\\_");
|
}
|
/**
|
* 根据下发路径的注释查询机床
|
* @param sendPathLine 下发路径注释文本
|
*/
|
public Machine getMachineBySendPathAnnotation(String sendPathLine) {
|
//路径为空,不匹配任何机器
|
if(StringUtils.isBlank(sendPathLine)){
|
return null;
|
}
|
//去掉末尾括号(发那科) ,末尾路径分隔符
|
String oriPath = StringUtils.removeEnd(StringUtils.removeEnd(StringUtils.removeEnd(sendPathLine,")"),"/"),"\\");
|
|
String tempPathRepl1 = StringUtils.replace(oriPath,"/","\\");//反斜杠版本的路径
|
String tempPathRepl2 = StringUtils.replace(oriPath,"\\","/");//正斜杠版本的路径
|
|
//去掉前2位可能的注释(*-)。
|
String sendPath1 = escapeSqlWildcard(StringUtils.trim(StringUtils.substring(tempPathRepl1,2)));
|
String sendPath2 = escapeSqlWildcard(StringUtils.trim(StringUtils.substring(tempPathRepl2,2)));
|
|
Optional<Machine> machineOpt = lambdaQuery().eq(Machine::getStatus,Machine.STATUS_ENABLE).and(w -> {
|
w.like(Machine::getProgSendDir,sendPath1).or().like(Machine::getProgSendDir,sendPath2);
|
}).last("limit 1").oneOpt();
|
|
return machineOpt.orElse(null);
|
}
|
|
/**
|
* 根据设备编号查询机床
|
* @param equipmentCode 设备编号
|
* @return 机床对象
|
*/
|
public Machine getByEquipmentCode(String equipmentCode) {
|
return this.lambdaQuery().eq(Machine::getEquipmentCode, equipmentCode).one();
|
}
|
}
|