# Xhy-Document-collection-platform **Repository Path**: codingwwr/xhy-document-collection-platform ## Basic Information - **Project Name**: Xhy-Document-collection-platform - **Description**: 文件收集平台,拥有权限管理,团队隔离,云存储,定时任务,日志记录等功能。已在本专业为90人提供服务稳定运行半年 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 12 - **Created**: 2024-04-18 - **Last Updated**: 2024-04-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 文件收集平台 ## 介绍 文件收集平台已稳定运行半年,以供90人使用,极大提高传统收作业的繁琐,提高收文件效率。负责人只需要发布任务->配置定时任务。 [点我传送门-介绍项目视频](https://www.bilibili.com/video/BV1RM411L7yA/) **传统收作业** ![输入图片说明](doc/img/%E4%BC%A0%E7%BB%9F.jpg) **平台收作业** ![输入图片说明](doc/img/%E5%B9%B3%E5%8F%B0.jpg) ## 使用说法 0.从doc中找到sql文件导入 1.将数据源信息配置换成自己的数据源信息 2.在OSSUtil这个类中配置oss相关信息 3.因新版本配置了STS,因此还需要在阿里云中配置STS相关信息在OSSUtil#getSTS()中 4.如果项目需要使用在线预览文件功能,你可以引入kkfileview,或者其他的在线预览 5.因项目中使用oss进行文件存储,因此涉及到url一定要小心,暴露的url配置好防盗链,sts 端口:8000 超级管理员账号:123456 密码:123 ## 核心技术 JDK:1.8 MySql:5.5.36 框架:SpringBoot+MyBatis+Oss ## 核心功能 1.团队隔离 2.云端存储 3.定时任务 4.日志记录 5.在线预览文件 ## 功能介绍 ### 1.成员功能介绍 #### 1.任务 1.此处展示了负责人所发布的任务 2.查看记录可查看该任务提交情况 ![输入图片说明](doc/img/%E6%88%90%E5%91%98%E4%BB%BB%E5%8A%A1.png) #### 2.文件记录 1.此处记录了当前用户文件相关操作 ![输入图片说明](doc/%E6%88%90%E5%91%98%E6%96%87%E4%BB%B6%E8%AE%B0%E5%BD%95.png) ### 2.团队负责人功能介绍 #### 1.发布任务 1.任务一旦发布,任务名称以及任务所属团队不可修改。 2.文件名模板配置后成员上传文件更自动更正文件名:用于统一文件名格式 3.作业描述:和在线预览文档项目相关 ![输入图片说明](doc/img/%E5%8F%91%E5%B8%83%E4%BB%BB%E5%8A%A1.png) #### 2.任务收集记录 1.在此下载后会在下载记录中查看,此处是为了解决下载文件数量过多服务端响应过慢卡死状态 ![输入图片说明](doc/img/%E4%BB%BB%E5%8A%A1%E6%94%B6%E9%9B%86%E8%AE%B0%E5%BD%95.png) #### 3.下载记录 1.此处记录了下载文件以及定时发送的文件记录 ![输入图片说明](doc/img/%E4%B8%8B%E8%BD%BD%E8%AE%B0%E5%BD%95.png) #### 4.邮箱配置 1.使用定时任务需要在此先配置邮箱,配置后需要校验邮箱是否可用(会给填写的邮箱发送邮箱校验) ![输入图片说明](doc/img/%E9%82%AE%E7%AE%B1%E9%85%8D%E7%BD%AE.png) #### 5.定时任务 1.此处记录定时任务添加等状态 2.交作业方式:会携带文件 3.通知:用于通知任务收集情况 ![输入图片说明](doc/img/%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1.png) #### 6.添加定时任务 1.邮件内容默认不填则是默认的模板,如果要填写的话可以根据模板填写 2.接收方需要在邮箱管理中配置 ![输入图片说明](doc/img/%E6%B7%BB%E5%8A%A0%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1.png) #### 7.成员文件记录 1.此处记录了团队成员文件相关记录 ![输入图片说明](doc/img/%E6%88%90%E5%91%98%E6%96%87%E4%BB%B6%E8%AE%B0%E5%BD%95.png) ### 3.超级管理员 #### 1. 添加团队负责人 在此给予用户授权即可 ![输入图片说明](doc/img/%E7%BB%99%E4%BA%88%E8%B4%9F%E8%B4%A3%E4%BA%BA%E6%9D%83%E9%99%90.png) #### 2.公告 1.发布公告后其他用户会收到公告 2.公告内容的样式需要手动写html标签 ![输入图片说明](doc/img/%E5%85%AC%E5%91%8A%E6%98%BE%E7%A4%BA.png) ![输入图片说明](doc/img/%E5%85%AC%E5%91%8A.png) ## 注意点 1.项目采用OSS存储文件,因此需要注意隐藏url以及配置防盗链 2.每个团队默认上传文件大小500M,用完后需要管理员分配 3.项目由去年开发,和我现在编码能力差的太多,可能在有一些代码上阅读困难以及拓展困难 ## 可拓展的点 1.成员之间可组队 2.用户绑定邮箱在任务发送后发送给用户的邮箱 3.QQ机器人,加入机器人后可提醒用户 4.任务以及定时任务可编排为模板(在一些周期性的任务时这样做可减少发布任务的操作),我嫌懒没做 ## kkFileView项目更改代码的点 为了隐藏url,隐藏需要改kkFileView中的代码。传过来的是一个url,因此需要拆分并且拼接,以及默认图片如果是url则是直接打开并不是下载。 直接打开会导致暴露url OnlinePreviewController类中添加这三个参数 ```java private final static String bucketName = "your bucketName"; private final static String endpoint = "your endpoint"; private final static String OSSUrl = "https://" + bucketName + "." + endpoint + "/"; @GetMapping( "/onlinePreview") public String onlinePreview(String url, Model model, HttpServletRequest req) { String fileUrl; try { fileUrl = WebUtils.decodeUrl(url); } catch (Exception ex) { String errorMsg = String.format(BASE64_DECODE_ERROR_MSG, "url"); return otherFilePreview.notSupportedFile(model, errorMsg); } // 拼接url fileUrl = OSSUrl+fileUrl; FileAttribute fileAttribute = fileHandlerService.getFileAttribute(fileUrl, req); model.addAttribute("file", fileAttribute); FilePreview filePreview = previewFactory.get(fileAttribute); logger.info("预览文件url:{},previewType:{}", fileUrl, fileAttribute.getType()); return filePreview.filePreviewHandle(fileUrl, model, fileAttribute); } ``` PictureFilePreviewImpl类中filePreviewHandle() ```java @Override public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) { url= KkFileUtils.htmlEscape(url); List imgUrls = new ArrayList<>(); String fileKey = fileAttribute.getFileKey(); List zipImgUrls = fileHandlerService.getImgCache(fileKey); if (!CollectionUtils.isEmpty(zipImgUrls)) { imgUrls.addAll(zipImgUrls); } // 不是http开头,浏览器不能直接访问,需下载到本地 String filePath = super.filePreviewHandle(url, model, fileAttribute); imgUrls.add(filePath); model.addAttribute("imgUrls", imgUrls); return PICTURE_FILE_PREVIEW_PAGE; } ``` CommonPreviewImpl 类filePreviewHandle方法 ```java @Override public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) { // 不是http开头,浏览器不能直接访问,需下载到本地 ReturnResponse response = DownloadUtils.downLoad(fileAttribute, null); if (response.isFailure()) { return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg()); } else { String file = fileHandlerService.getRelativePath(response.getContent()); model.addAttribute("currentUrl", file); return file; } /*if (url != null && !url.toLowerCase().startsWith("http")) { } else { model.addAttribute("currentUrl", url); }*/ } ``` DownloadUtils 类downLoad() ```java public static ReturnResponse downLoad(FileAttribute fileAttribute, String fileName) { // 忽略ssl证书 try { SslUtils.ignoreSsl(); } catch (Exception e) { logger.error("忽略SSL证书异常:", e); } String urlStr = fileAttribute.getUrl().replaceAll("\\+", "%20"); ReturnResponse response = new ReturnResponse<>(0, "下载成功!!!", ""); String realPath = DownloadUtils.getRelFilePath(fileName, fileAttribute); if(!StringUtils.hasText(realPath)){ response.setCode(1); response.setContent(null); response.setMsg("下载失败:文件名不合法!" + urlStr); return response; } if(realPath.equals("cunzhai")){ response.setContent(fileDir + fileName); response.setMsg(fileName); return response; } try { URL url = new URL(urlStr); if (!fileAttribute.getSkipDownLoad()) { if (isHttpUrl(url)) { File realFile = new File(realPath); // 下载文件 在此修改了 WebUtils.getUrlFile(url, realFile); } else if (isFtpUrl(url)) { String ftpUsername = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_USERNAME); String ftpPassword = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_PASSWORD); String ftpControlEncoding = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_CONTROL_ENCODING); FtpUtils.download(fileAttribute.getUrl(), realPath, ftpUsername, ftpPassword, ftpControlEncoding); } else { response.setCode(1); response.setMsg("url不能识别url" + urlStr); } } response.setContent(realPath); response.setMsg(fileName); return response; } catch (IOException e) { e.printStackTrace(); logger.error("文件下载失败,url:{}", urlStr); response.setCode(1); response.setContent(null); if (e instanceof FileNotFoundException) { response.setMsg("文件不存在!!!"); } else { response.setMsg(e.getMessage()); } return response; } } ``` WebUtils类中getUrlFile()方法,该方法为新增方法 ```java public static void getUrlFile(URL url, File destination) throws IOException { HttpURLConnection connection=(HttpURLConnection)url.openConnection(); connection.setRequestMethod("GET") ; //设置为长连接 connection.setRequestProperty("Connection", "Keep-Alive"); connection.setRequestProperty("Accept", "*/*"); // 此处为oss防盗链 connection.setRequestProperty("Referer", "your referer"); FileUtils.copyToFile(connection.getInputStream(), destination); } ``` ## 最后(一定要看) 如果项目中功能或者代码有疑惑的地方可以发issues或者来b站评论,我都会回的! 如果这个项目对你有所帮助,能否给予处在于水深火热的java环境中的我一个star,你的star是对于我最大的鼓励