diff --git a/main/java/shkd/repc/task/DobeContractAttachmentTask.java b/main/java/shkd/repc/task/DobeContractAttachmentTask.java index 1bf7208..38c8137 100644 --- a/main/java/shkd/repc/task/DobeContractAttachmentTask.java +++ b/main/java/shkd/repc/task/DobeContractAttachmentTask.java @@ -26,7 +26,7 @@ import java.util.Map; */ public class DobeContractAttachmentTask extends AbstractTask implements Plugin { - private static final String entityName = "recon_contractbi";//表名 t_recon_contractbill + private static final String entityName = "recon_contractbill";//表名 t_recon_contractbill private static final String attachKey = "attachmentcontactdoc";//合同普通附件面板标识 private static final String zwattKey = "attachmentpanel";//合同正文(盖章件)附件面板标识 private static final Log logger = LogFactory.getLog(DobeContractAttachmentTask.class); @@ -52,7 +52,7 @@ public class DobeContractAttachmentTask extends AbstractTask implements Plugin { } //获取appId String appId = MetadataServiceHelper.getDataEntityType(entityName).getAppId(); - //TODO 获取oa token 此token时效是多少 + //获取oa token 此token时效是多少 String oaToken = OAUtils.getOaToken("oa-contract-attachment"); if(DobeDWUtils.isEmpty(oaToken)){ return; @@ -75,11 +75,12 @@ public class DobeContractAttachmentTask extends AbstractTask implements Plugin { //拿到OA附件接口返回的NAS文件存放路径 requrl = oaUrl+oa_menthod+contractno+"?summaryId="+fj_oaid+"&subReference="+fj_zwid; + logger.info(contractno+" OA附件接口请求地址\n{}", requrl); try { // 发送get请求oa附件接口并获取响应 resultjson = HttpClientUtils.get(requrl, customerHeader,null); resultjsonObject = JSONObject.parseObject(resultjson); - logger.info(contractno+" OA附件接口返回结果:\n{}", resultjson); + logger.info(contractno+" OA附件接口返回结果\n{}", resultjson); // 检查JSON对象是否为空 if (resultjsonObject != null && !resultjsonObject.isEmpty()) { if(resultjsonObject.getBoolean("success")){ @@ -92,22 +93,24 @@ public class DobeContractAttachmentTask extends AbstractTask implements Plugin { } } catch (Exception e) { //记录OA接口异常信息 - logger.info(String.format(contractno+" 调用OA附件接口异常:%s", e.getMessage())); + logger.info(String.format(contractno+" 调用OA附件接口异常\n{}", e.getMessage())); DobeDWUtils.saveLog(contractno,"致远附件",requrl,e.getMessage(), false,"调用OA附件接口"); throw new RuntimeException(e); } //访问NAS文件指定存放路径,拿到当前附件和正文目录下的所有文件对象,记录日志 - //在nas路径里,需要供应链系统在/isc/prod/{code}/下继续组装相对地址: - // /isc/prod/{code}/{summaryId}/下文件夹内为表单附件,/isc/prod/{code}/{subReference}/为合同正文附件 + //在nas路径里,需要供应链系统在/isc/oa/prod/{code}/下继续组装相对地址: + // /isc/oa/prod/{code}/{summaryId}/下文件夹内为表单附件,/isc/oa/prod/{code}/{subReference}/为合同正文附件 if(!DobeDWUtils.isEmpty(nasPath)){ //处理表单附件目录 + nasPath = nasPath.substring(2).replace("\\","/"); try { - //TODO nasPath+fj_oaid; - boolean upresult = AttachmentFileUtil.saveDirFile2Attchment(appId,entityName,contractid,nasPath+fj_oaid,attachKey); + //nasPath+fj_oaid; + logger.info(contractno+" OA附件接口返回nasPath\n{}", nasPath+"/"+fj_oaid); + boolean upresult = AttachmentFileUtil.saveDirFile2Attchment(appId,entityName,contractid,nasPath+"/"+fj_oaid,attachKey); //处理合同正文附件目录 if(!DobeDWUtils.isEmpty(fj_zwid)){ - //TODO nasPath+fj_zwid; - AttachmentFileUtil.saveDirFile2Attchment(appId,entityName,contractid,nasPath+fj_zwid,zwattKey); + //nasPath+fj_zwid; + AttachmentFileUtil.saveDirFile2Attchment(appId,entityName,contractid,nasPath+"/"+fj_zwid,zwattKey); } //上传成功后更新合同未上传附件的标记为false if(upresult){ @@ -117,11 +120,11 @@ public class DobeContractAttachmentTask extends AbstractTask implements Plugin { } } catch (Exception e) { //记录附件上传异常信息 - logger.info(String.format(contractno+" 从NAS上传文件至星瀚异常:%s", e.getMessage())); + logger.info(String.format(contractno+" 从NAS上传文件至星瀚异常\n{}", e.getMessage())); DobeDWUtils.saveLog(contractno,"NAS附件",nasPath,e.getMessage(),false,"NAS上传文件至星瀚"); } }else{ - logger.info(contractno+" OA附件接口返回路径为空,fj_oaid:", fj_oaid); + logger.info(contractno+" OA附件接口返回路径为空,fj_oaid\n{}", fj_oaid); } } } diff --git a/main/java/shkd/utils/AttachmentFileUtil.java b/main/java/shkd/utils/AttachmentFileUtil.java index 2aa2986..cf6bd10 100644 --- a/main/java/shkd/utils/AttachmentFileUtil.java +++ b/main/java/shkd/utils/AttachmentFileUtil.java @@ -16,12 +16,16 @@ import kd.bos.entity.MainEntityType; import kd.bos.fileservice.FileItem; import kd.bos.fileservice.FileService; import kd.bos.fileservice.FileServiceFactory; +import kd.bos.logging.Log; +import kd.bos.logging.LogFactory; import kd.bos.servicehelper.AttachmentServiceHelper; import kd.bos.servicehelper.MetadataServiceHelper; import kd.bos.util.FileNameUtils; public class AttachmentFileUtil { + private static final Log logger = LogFactory.getLog(AttachmentFileUtil.class); + /**将第三方提供的某个在线文件上传至星瀚对应单据附件上 * @param entity 目标单据实体标识 * @param pk 目标数据id @@ -116,9 +120,20 @@ public class AttachmentFileUtil { * @throws IOException */ public static boolean saveDirFile2Attchment(String appId,String entity,Object pk,String dirpath,String attachKey) throws IOException { - File[] files = new File(dirpath).listFiles(); + File currentDir = new File("."); + logger.info("当前系统路径"+currentDir.getAbsolutePath()); + + logger.info("传入的路径"+dirpath); + File dirfile = new File(dirpath); + if(!dirfile.isDirectory()){ + //传入的路径不是目录或者目录不存在 + logger.info("不是目录或者目录不存在"+dirpath); + return false; + } + File[] files = dirfile.listFiles(); if(files.length == 0){ //目录下没有文件,不需要处理 + logger.info("目录下没有文件,不需要处理"+dirpath); return false; } List> attachments = new ArrayList<>(); @@ -139,7 +154,7 @@ public class AttachmentFileUtil { //文件大小 attachItem.put("size", destFile.length()); //将文件流存入临时文件缓存(拷贝完成)(最后一个参数为缓存有效期,600秒) - tempUrl = cache.saveAsFullUrl(fileName, Files.readAllBytes(destFile.toPath()), 600); + tempUrl = cache.saveAsFullUrl(fileName, Files.readAllBytes(destFile.toPath()), 900); //修改时间 attachItem.put("lastModified",System.currentTimeMillis()); //将文件缓存中的附件文件上传到正式文件服务器 @@ -158,9 +173,47 @@ public class AttachmentFileUtil { //将新文件的物理路径存入map attachItem.put("url", actUrl); attachments.add(attachItem); - //维护单据和附件的关系(非文件上传) - AttachmentServiceHelper.upload(entity, pk, attachKey, attachments); } + //维护单据和附件的关系(非文件上传) + AttachmentServiceHelper.upload(entity, pk, attachKey, attachments); + return true; + } + + /**将星瀚nfs上某个目录下的所有文件关联至星瀚对应单据附件上,不需要文件上传 + * @param appId 目标单据所属应用标识 + * @param entity 目标单据实体标识 + * @param pk 目标数据id + * @param attachKey 附件面板标识 + * @param dirpath 文件目录路径 + * @throws IOException + */ + public static boolean realtionDirFile2Attchment(String appId,String entity,Object pk,String dirpath,String attachKey) { + File[] files = new File(dirpath).listFiles(); + if(files.length == 0){ + //目录下没有文件,不需要处理 + return false; + } + List> attachments = new ArrayList<>(); + Map attachItem; + String fileName; + File destFile; + //遍历目标目录,得到所有文件 + for (int i = 0; i < files.length; i++) { + destFile = files[i]; + fileName = destFile.getName(); + attachItem = new HashMap<>(); + //文件名称 + attachItem.put("name", fileName); + //文件大小 + attachItem.put("size", destFile.length()); + //修改时间 + attachItem.put("lastModified",System.currentTimeMillis()); + //将文件的物理路径存入map + attachItem.put("url", destFile.getPath()); + attachments.add(attachItem); + } + //维护单据和附件的关系(非文件上传) + AttachmentServiceHelper.upload(entity, pk, attachKey, attachments); return true; } diff --git a/main/java/shkd/utils/SFTPConnectUtil.java b/main/java/shkd/utils/SFTPConnectUtil.java new file mode 100644 index 0000000..307a999 --- /dev/null +++ b/main/java/shkd/utils/SFTPConnectUtil.java @@ -0,0 +1,324 @@ +package shkd.utils; + + +import com.jcraft.jsch.*; +import com.jcraft.jsch.ChannelSftp.LsEntry; +import kd.bos.logging.Log; +import kd.bos.logging.LogFactory; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Properties; +import java.util.Vector; + +/** + *

+ * ClassName: SFTPConnectUtil + *

+ *

+ * Description: 连接SFTP + *

+ */ +public class SFTPConnectUtil { + + /** + * 日志 + */ + private final static Log logger = LogFactory.getLog(SFTPConnectUtil.class); + /** + * 连接SFTP服务器 + * + * @param host + * 主机 + * @param port + * 端口 + * @param username + * 用户名 + * @param password + * 密码 + * @return ChannelSftp + */ + public static ChannelSftp connectSFTP(String host, int port, + String username, String password) { + // 声明ChannelSftp对象 + ChannelSftp sftp = null; + try { + // 创建JSch对象 + JSch jsch = new JSch(); + // 根据用户名,主机IP,端口获取一个Session对象 + Session sshSession = jsch.getSession(username, host, port); + if (!isEmpty(password)) { + sshSession.setPassword(password); + } + // 新建属性类 + Properties sshConfig = new Properties(); + /* + * 连接新主机时,不进行公钥确认; + * 在首次连接服务器时,会弹出公钥确认的提示。这会导致某些自动化任务,由于初次连接服务器而导致自动化任务中断。 + */ + sshConfig.put("StrictHostKeyChecking", "no"); + // 配置连接设置 + sshSession.setConfig(sshConfig); + // 建立连接 + sshSession.connect(); + // 打开SFTP通道 + Channel channel = sshSession.openChannel("sftp"); + // 建立SFTP通道的连接 + channel.connect(); + // 强转ChannelSftp对象 + sftp = (ChannelSftp) channel; + } catch (JSchException e) { + logger.error("connectSFTP:" + e.toString()); + return null; + } + return sftp; + } + + /** + * 上传文件 + * + * @param directory + * 上传的目录 + * @param uploadFile + * 要上传的文件 + * @param sftp + * @return boolean + */ + public static boolean uploadFile(String directory, File uploadFile, + ChannelSftp sftp,String fileName) { + try { + // 进入指定目录 + sftp.cd(directory); + sftp.put(new FileInputStream(uploadFile), fileName); + } catch (FileNotFoundException e) { + logger.error("uploadFile -- FileNotFoundException:" + e.toString()); + return false; + } catch (SftpException e) { + logger.error("uploadFile -- SftpException:" + e.toString()); + return false; + } + return true; + } + + /** + * 上传附件 + * @param directory + * @param fileInputStream + * @param fileName + * @param sftp + * @return + */ + public static boolean uploadFile(String directory, FileInputStream fileInputStream,String fileName, + ChannelSftp sftp) { + try { + // 进入指定目录 + sftp.cd(directory); + sftp.put(fileInputStream, fileName); + } catch (SftpException e) { + logger.error("uploadFile -- SftpException:" + e.toString()); + return false; + } + return true; + } + /** + * 下载文件 + * + * @param directory + * 下载目录 + * @param downloadFile + * 下载的文件 + * @param saveFile + * 存在本地的路径 + * @param sftp + * @return boolean + */ + public static boolean downloadFile(String directory, String downloadFile, + File saveFile, ChannelSftp sftp) { + try { + // 进入指定目录 + sftp.cd(directory); + // 下载文件到指定路径 + sftp.get(downloadFile, new FileOutputStream(saveFile)); + } catch (FileNotFoundException e) { + logger.error("downloadFile -- FileNotFoundException:" + + e.toString()); + return false; + } catch (SftpException e) { + logger.error("downloadFile -- SftpException:" + e.toString()); + return false; + } + return true; + } + + /** + * 删除文件 + * + * @param directory + * 要删除文件所在目录 + * @param deleteFile + * 要删除的文件 + * @param sftp + * @return boolean + */ + public static boolean deleteFile(String directory, String deleteFile, + ChannelSftp sftp) { + try { + // 进入指定目录 + sftp.cd(directory); + // 删除文件 + sftp.rm(deleteFile); + } catch (SftpException e) { + logger.error("deleteFile -- SftpException:" + e.toString()); + return false; + } + return true; + } + + /** + * 创建文件夹 + * + * @param directory + * 目标目录 + * @param creatDir + * 要创建的文件 + * @param sftp + * @return boolean + */ + public static boolean createDir(String directory, String creatDir, + ChannelSftp sftp) { + try { + // 进入指定目录 + sftp.cd(directory); + // 创建文件夹 + sftp.mkdir(creatDir); + } catch (SftpException e) { + logger.error("deleteFile -- SftpException:" + e.toString()); + return false; + } + return true; + } + + /** + * 删除文件夹 + * + * @param directory + * 目标目录 + * @param deleteDir + * 要删除的文件 + * @param sftp + * @return boolean + */ + public static boolean deleteDir(String directory, String deleteDir, + ChannelSftp sftp) { + try { + // 进入指定目录 + sftp.cd(directory); + // 删除文件夹 + sftp.rmdir(deleteDir); + } catch (SftpException e) { + logger.error("deleteFile -- SftpException:" + e.toString()); + return false; + } + return true; + } + + /** + * 列出目录下的文件 + * + * @param directory + * 要列出的目录 + * @param sftp + * @return Vector + * @throws SftpException + */ + @SuppressWarnings("unchecked") + public static Vector getListFiles(String directory, + ChannelSftp sftp) { + Vector lsVec = null; + try { + // 列出指定目录下的所有文件和子目录 + lsVec = sftp.ls(directory); + } catch (SftpException e) { + logger.error("getListFiles -- SftpException:" + e.toString()); + return null; + } + return lsVec; + } + + /** + * 删除上传与下载临时目录的文件 + * + * @param file + * 要删除的文件 + */ + public static void deleteFileByTemp(File file) { + // 目录是否存在 + if (file.exists()) { + // 获取当前路径的文件列表 + File[] listFiles = file.listFiles(); + // 遍历文件列表 + for (File files : listFiles) { + // 如果是文件夹,递归调用此方法 + if (files.isDirectory()) { + deleteFileByTemp(files); + // 如果是文件,直接删除 + } else if (files.isFile()) { + logger.info(files.getName() + "---" + files.delete()); + } + } + // 删除根目录文件 + logger.info(file.getName() + "---" + file.delete()); + } else { + logger.info("当前路径不存在!"); + } + } + + /** + * 判断字符串是否为空 + * + * @param str + * @return boolean + */ + public static boolean isEmpty(String str) { + if (null == str || "".equals(str)) { + return true; + } + return false; + } + + /** + * 判断对象是否为空 + * + * @param + * @return boolean + */ + public static boolean isEmpty(Object obj) { + if (null == obj || "".equals(obj)) { + return true; + } + return false; + } + + /** + * 设置上传文件名 + * + * @return String + */ + public static String setFileName() { + return new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()); + } + + /** + * 设置上传文件夹名 + * + * @return String + */ + public static String setDirName() { + return new SimpleDateFormat("yyyyMMdd").format(new Date()); + } +} +