diff --git a/pear-common/pom.xml b/pear-common/pom.xml index dec6d49dd95c129ff805e298faf65dbd3c82a471..a3c196aec5595c4875d9e870d1b4dd182a3a2862 100644 --- a/pear-common/pom.xml +++ b/pear-common/pom.xml @@ -97,6 +97,12 @@ org.jsoup jsoup + + commons-net + commons-net + 3.8.0 + compile + diff --git a/pear-common/src/main/java/com/pearadmin/common/config/proprety/TemplateProperty.java b/pear-common/src/main/java/com/pearadmin/common/config/proprety/TemplateProperty.java index 5e898911d84fe8825b49b0cb086d5a68f1b1f574..48a7bae230598598cde770b4bb2ae68542d7f6a0 100644 --- a/pear-common/src/main/java/com/pearadmin/common/config/proprety/TemplateProperty.java +++ b/pear-common/src/main/java/com/pearadmin/common/config/proprety/TemplateProperty.java @@ -26,6 +26,31 @@ public class TemplateProperty { * */ private String linuxPath; + /** + * 是否启用ftp服务器 + */ + private boolean ftpUse; + + /** + * ftp服务器url + */ + private String hostname; + + /** + * ftp服务器端口号 + */ + private int port; + + /** + * ftp服务器用户名 + */ + private String username; + + /** + * ftp服务器密码 + */ + private String password; + /** * upload path 根据系统环境获取上传路径 * */ diff --git a/pear-common/src/main/java/com/pearadmin/common/tools/common/FTPUtil.java b/pear-common/src/main/java/com/pearadmin/common/tools/common/FTPUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..7628a0529624288b4b7337925a6be7fb580de955 --- /dev/null +++ b/pear-common/src/main/java/com/pearadmin/common/tools/common/FTPUtil.java @@ -0,0 +1,94 @@ +package com.pearadmin.common.tools.common; + +import org.apache.commons.net.ftp.FTPClient; +import org.apache.commons.net.ftp.FTPReply; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; + +public class FTPUtil { + + private static final Logger logger = LoggerFactory.getLogger(FTPUtil.class); + + private FTPUtil() { + } + + public static FTPClient open(String hostname, String username, String password){ + return open(hostname, 21, username, password, "UTF-8"); + } + + public static FTPClient open(String hostname, int port, String username, String password, String controlEncoding) { + FTPClient ftpClient = new FTPClient(); + ftpClient.setControlEncoding(controlEncoding); + ftpClient.setDataTimeout(60000); + try { + ftpClient.connect(hostname, port); + ftpClient.login(username, password); + if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) { + ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); + ftpClient.enterLocalPassiveMode(); + } else { + logger.error("Failed to login the FTP server. Please check your username and password"); + ftpClient.disconnect(); + } + } catch (IOException e) { + e.printStackTrace(); + } + return ftpClient; + } + + public static void close(FTPClient ftpClient) { + try { + if (ftpClient != null && ftpClient.isConnected()) { + ftpClient.logout(); + ftpClient.disconnect(); + } + } catch (IOException e) { + logger.error("unknow failed.{}", e.getMessage()); + } + } + + public static void upload(FTPClient ftpClient, String path, String fileName, InputStream is) { + try { + if (!ftpClient.changeWorkingDirectory(path)) { + mkdirs(ftpClient, path); + } + ftpClient.storeFile("/" + path + "/" + fileName, is); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void download(FTPClient ftpClient, String path, OutputStream os){ + try { + ftpClient.retrieveFile(path, os); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void remove(FTPClient ftpClient, String path){ + try{ + ftpClient.deleteFile(path); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void mkdirs(FTPClient ftpClient, String path) { + path = path.replace('\\', '/'); + StringBuffer sb = new StringBuffer(); + String[] dirs = path.split("/"); + try { + for (int i = 0; i < dirs.length; i++) { + if (!"".equals(dirs[i])) { + sb.append(dirs[i] + "/"); + ftpClient.makeDirectory(sb.toString()); + } + } + }catch (Exception e){ + logger.error("please check your path. {}", e.getMessage()); + } + } +} diff --git a/pear-entrance/src/main/resources/application.yml b/pear-entrance/src/main/resources/application.yml index 204d76af5f9a602b4804c75ff4f87ba09c4f3b75..7232d5fb1f7859e8c9fdfc25901156cf28436919 100644 --- a/pear-entrance/src/main/resources/application.yml +++ b/pear-entrance/src/main/resources/application.yml @@ -82,6 +82,16 @@ pear: windows-path: D:\home\uploads\ # linux 上传路径 linux-path: /home/uploads/ + # 是否使用ftp服务器 + ftp-use: false + # ftp服务器地址 + hostname: + # ftp服务器端口 + port: + # ftp服务器用户名 + username: + # ftp服务器密码 + password: # Page Helper 分页配置 pagehelper: diff --git a/pear-modules/pear-system/src/main/java/com/pearadmin/system/controller/SysFileController.java b/pear-modules/pear-system/src/main/java/com/pearadmin/system/controller/SysFileController.java index 11ef421988395196d00cbb0a9b6dbb865c7c4f82..423ef0f3e2e86dd70ce5e0b2ca40982d7f1fcfa2 100644 --- a/pear-modules/pear-system/src/main/java/com/pearadmin/system/controller/SysFileController.java +++ b/pear-modules/pear-system/src/main/java/com/pearadmin/system/controller/SysFileController.java @@ -2,6 +2,7 @@ package com.pearadmin.system.controller; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; +import com.pearadmin.common.config.proprety.TemplateProperty; import com.pearadmin.common.constant.ControllerConstant; import com.pearadmin.system.domain.SysFile; import com.pearadmin.system.service.ISysFileService; @@ -11,12 +12,15 @@ import com.pearadmin.common.web.domain.response.Result; import com.pearadmin.common.web.domain.response.module.ResultTable; import io.swagger.annotations.Api; import org.apache.logging.log4j.util.Strings; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.ModelAndView; + import javax.annotation.Resource; +import java.util.Map; /** * Describe: 文件控制器 @@ -30,23 +34,43 @@ public class SysFileController extends BaseController { /** * 系 统 文 件 - * */ + */ private String MODULE_PATH = "system/file/"; /** - * 移 除 服 务 - * */ + * 配置文件 + */ @Resource - private ISysFileService fileService; + private TemplateProperty uploadProperty; + + /** + * 移 除 服 务 + */ + @Autowired + private Map fileServiceMap; + + /** + * 根据配置文件选择实现类 + * @return + */ + private ISysFileService getFileService() { + ISysFileService fileService = null; + if (uploadProperty.isFtpUse()) { + fileService = this.fileServiceMap.get("SysFileFTPServiceImpl"); + } else { + fileService = this.fileServiceMap.get("SysFileServiceImpl"); + } + return fileService; + } /** * Describe: 文件管理页面 * Param: null * Return: ModelAndView - * */ + */ @GetMapping("main") @PreAuthorize("hasPermission('/system/file/main','sys:file:main')") - public ModelAndView main(){ + public ModelAndView main() { return jumpPage(MODULE_PATH + "main"); } @@ -54,23 +78,23 @@ public class SysFileController extends BaseController { * Describe: 文件资源数据 * Param: PageDomain * Return: 文件资源列表 - * */ + */ @GetMapping("data") @PreAuthorize("hasPermission('/system/file/data','sys:file:data')") - public ResultTable data(PageDomain pageDomain){ - PageHelper.startPage(pageDomain.getPage(),pageDomain.getLimit()); - PageInfo pageInfo = new PageInfo<>(fileService.data()); - return pageTable(pageInfo.getList(),pageInfo.getTotal()); + public ResultTable data(PageDomain pageDomain) { + PageHelper.startPage(pageDomain.getPage(), pageDomain.getLimit()); + PageInfo pageInfo = new PageInfo<>(getFileService().data()); + return pageTable(pageInfo.getList(), pageInfo.getTotal()); } /** * Describe: 文件上传视图 * Param: null * Return: 执行结果 - * */ + */ @GetMapping("add") @PreAuthorize("hasPermission('/system/file/add','sys:file:add')") - public ModelAndView add(){ + public ModelAndView add() { return jumpPage(MODULE_PATH + "add"); } @@ -78,13 +102,13 @@ public class SysFileController extends BaseController { * Describe: 文件上传接口 * Param: SysUser * Return: Result - * */ + */ @PostMapping("upload") - public Result upload(@RequestParam("file") MultipartFile file){ - String result = fileService.upload(file); - if(Strings.isNotBlank(result)){ - return Result.success(0,"上传成功",result); - }else{ + public Result upload(@RequestParam("file") MultipartFile file) { + String result = getFileService().upload(file); + if (Strings.isNotBlank(result)) { + return Result.success(0, "上传成功", result); + } else { return Result.failure("上传失败"); } } @@ -93,35 +117,35 @@ public class SysFileController extends BaseController { * Describe: 文件获取接口 * Param: id * Return: 文件流 - * */ + */ @GetMapping("download/{id}") - public void download(@PathVariable("id") String id){ - fileService.download(id); + public void download(@PathVariable("id") String id) { + getFileService().download(id); } /** * Describe: 文件删除接口 * Param: id * Return: 文件流 - * */ + */ @DeleteMapping("remove/{id}") @PreAuthorize("hasPermission('/system/file/remove','sys:file:remove')") - public Result remove(@PathVariable("id") String id){ - boolean result = fileService.remove(id); - return Result.decide(result,"删除成功","删除失败"); + public Result remove(@PathVariable("id") String id) { + boolean result = getFileService().remove(id); + return Result.decide(result, "删除成功", "删除失败"); } /** * Describe: 文件删除接口 * Param: id * Return: 文件流 - * */ + */ @Transactional @DeleteMapping("batchRemove/{ids}") @PreAuthorize("hasPermission('/system/file/remove','sys:file:remove')") - public Result batchRemove(@PathVariable("ids") String ids){ - for (String id: ids.split(",")) { - fileService.remove(id); + public Result batchRemove(@PathVariable("ids") String ids) { + for (String id : ids.split(",")) { + getFileService().remove(id); } return Result.success("删除成功"); } diff --git a/pear-modules/pear-system/src/main/java/com/pearadmin/system/service/impl/SysFileFTPServiceImpl.java b/pear-modules/pear-system/src/main/java/com/pearadmin/system/service/impl/SysFileFTPServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..ca2afe183bab6bc0347eb4db40744b23a219b3fc --- /dev/null +++ b/pear-modules/pear-system/src/main/java/com/pearadmin/system/service/impl/SysFileFTPServiceImpl.java @@ -0,0 +1,128 @@ +package com.pearadmin.system.service.impl; + +import com.pearadmin.common.config.proprety.TemplateProperty; +import com.pearadmin.common.tools.common.FTPUtil; +import com.pearadmin.common.tools.sequence.SequenceUtil; +import com.pearadmin.common.tools.servlet.ServletUtil; +import com.pearadmin.system.domain.SysFile; +import com.pearadmin.system.mapper.SysFileMapper; +import com.pearadmin.system.service.ISysFileService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.net.ftp.FTPClient; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@Service("SysFileFTPServiceImpl") +public class SysFileFTPServiceImpl implements ISysFileService { + + /** + * 引 入 服 务 + */ + @Resource + private SysFileMapper fileMapper; + + /** + * 上 传 可 读 配 置 + */ + @Resource + private TemplateProperty uploadProperty; + + @Override + public String upload(MultipartFile file) { + String result = ""; + FTPClient ftpClient = null; + try { + String fileId = SequenceUtil.makeStringId(); + String name = file.getOriginalFilename(); + String suffixName = name.substring(name.lastIndexOf(".")); + String fileName = fileId + suffixName; + String path = LocalDate.now().toString(); + + ftpClient = FTPUtil.open(uploadProperty.getHostname(), uploadProperty.getUsername(), uploadProperty.getPassword()); + if (ftpClient.isConnected()) { + FTPUtil.upload(ftpClient, path, fileName, file.getInputStream()); + } + + SysFile fileDomain = new SysFile(); + fileDomain.setId(fileId); + fileDomain.setFileDesc(name); + fileDomain.setFileName(fileName); + fileDomain.setTargetDate(LocalDate.now()); + fileDomain.setFilePath(path + "/" + fileName); + fileDomain.setCreateTime(LocalDateTime.now()); + fileDomain.setFileSize(String.valueOf(file.getSize())); + fileDomain.setFileType(suffixName.replace(".", "")); + int flag = fileMapper.insert(fileDomain); + if (flag > 0) { + result = fileId; + } else { + result = ""; + } + } catch (Exception e) { + log.error("failed to upload file.detail message:{}", e.getMessage()); + } finally { + FTPUtil.close(ftpClient); + } + return result; + } + + @Override + public void download(String id) { + FTPClient ftpClient = null; + try { + SysFile file = fileMapper.selectById(id); + String path = file.getFilePath(); + ftpClient = FTPUtil.open(uploadProperty.getHostname(), uploadProperty.getUsername(), uploadProperty.getPassword()); + FTPUtil.download(ftpClient, path, ServletUtil.getResponse().getOutputStream()); + } catch (Exception e) { + e.printStackTrace(); + } finally { + FTPUtil.close(ftpClient); + } + } + + @Override + public List data() { + return fileMapper.selectList(); + } + + @Override + public boolean remove(String id) { + SysFile file = fileMapper.selectById(id); + //如果文件不存在 + if (file != null && file.getFilePath() != null) { + FTPClient ftpClient = FTPUtil.open(uploadProperty.getHostname(), uploadProperty.getUsername(), uploadProperty.getPassword()); + if (ftpClient.isConnected()){ + FTPUtil.remove(ftpClient,file.getFilePath()); + } + FTPUtil.close(ftpClient); + } else { + log.warn("fileId:{} ,need delete file:{} not exists ", id, file.getFilePath()); + } + return fileMapper.deleteById(id) > 0; + } + + @Override + public List fileDirs() { + List fileDirs = new ArrayList<>(); + java.io.File file = new java.io.File("/home/upload"); + if (file.isDirectory()) { + java.io.File[] files = file.listFiles(); + for (int i = 0; i < files.length; i++) { + if (files[i].isDirectory()) { + String dirName = files[i].getName(); + fileDirs.add(dirName); + } + } + } + return fileDirs; + } +} diff --git a/pear-modules/pear-system/src/main/java/com/pearadmin/system/service/impl/ISysFileServiceImpl.java b/pear-modules/pear-system/src/main/java/com/pearadmin/system/service/impl/SysFileServiceImpl.java similarity index 88% rename from pear-modules/pear-system/src/main/java/com/pearadmin/system/service/impl/ISysFileServiceImpl.java rename to pear-modules/pear-system/src/main/java/com/pearadmin/system/service/impl/SysFileServiceImpl.java index d12c5bc2d1c7724bcde55d5d56dea4f301d480fa..46123d2b73ccbf993760dbf4d08575d9dc56e5c5 100644 --- a/pear-modules/pear-system/src/main/java/com/pearadmin/system/service/impl/ISysFileServiceImpl.java +++ b/pear-modules/pear-system/src/main/java/com/pearadmin/system/service/impl/SysFileServiceImpl.java @@ -27,8 +27,8 @@ import java.util.List; * CreateTime: 2019/10/23 */ @Slf4j -@Service -public class ISysFileServiceImpl implements ISysFileService { +@Service("SysFileServiceImpl") +public class SysFileServiceImpl implements ISysFileService { /** * 引 入 服 务 @@ -71,6 +71,7 @@ public class ISysFileServiceImpl implements ISysFileService { @Override @Transactional public String upload(MultipartFile file) { + String result = ""; try { String fileId = SequenceUtil.makeStringId(); String name = file.getOriginalFilename(); @@ -82,8 +83,9 @@ public class ISysFileServiceImpl implements ISysFileService { if (!filepath.getParentFile().exists()) { filepath.getParentFile().mkdirs(); } - SysFile fileDomain = new SysFile(); file.transferTo(filepath); + + SysFile fileDomain = new SysFile(); fileDomain.setId(fileId); fileDomain.setFileDesc(name); fileDomain.setFileName(fileName); @@ -92,16 +94,16 @@ public class ISysFileServiceImpl implements ISysFileService { fileDomain.setCreateTime(LocalDateTime.now()); fileDomain.setFileSize(FileUtil.getPrintSize(filepath.length())); fileDomain.setFileType(suffixName.replace(".", "")); - int result = fileMapper.insert(fileDomain); - if (result > 0) { - return fileId; + int flag = fileMapper.insert(fileDomain); + if (flag > 0) { + result = fileId; } else { - return ""; + result = ""; } } catch (Exception e) { - e.printStackTrace(); - return ""; + log.error("failed to upload file.detail message:{}", e.getMessage()); } + return result; } /** @@ -145,10 +147,10 @@ public class ISysFileServiceImpl implements ISysFileService { //如果文件不存在 if (file != null && file.getFilePath() != null) { File deleteFile; - if((deleteFile=new File(file.getFilePath())).exists()){ - fileDeleteResult=deleteFile.delete(); - }else { - fileDeleteResult=false; + if ((deleteFile = new File(file.getFilePath())).exists()) { + fileDeleteResult = deleteFile.delete(); + } else { + fileDeleteResult = false; } } else { fileDeleteResult = false; diff --git a/pear-modules/pear-system/src/main/java/com/pearadmin/system/service/impl/ISysMailServiceImpl.java b/pear-modules/pear-system/src/main/java/com/pearadmin/system/service/impl/SysMailServiceImpl.java similarity index 94% rename from pear-modules/pear-system/src/main/java/com/pearadmin/system/service/impl/ISysMailServiceImpl.java rename to pear-modules/pear-system/src/main/java/com/pearadmin/system/service/impl/SysMailServiceImpl.java index fa64d780ae7b9d9654dcabafb10704d27b922e17..6a184e53abb0bcee9e6f9d2c9e461a54e100309e 100644 --- a/pear-modules/pear-system/src/main/java/com/pearadmin/system/service/impl/ISysMailServiceImpl.java +++ b/pear-modules/pear-system/src/main/java/com/pearadmin/system/service/impl/SysMailServiceImpl.java @@ -22,7 +22,7 @@ import java.util.ArrayList; import java.util.List; @Service -public class ISysMailServiceImpl implements ISysMailService { +public class SysMailServiceImpl implements ISysMailService { @Resource private SysMailMapper sysMailMapper; @@ -35,7 +35,7 @@ public class ISysMailServiceImpl implements ISysMailService { public Integer save(SysMail sysMail) { if (sendMail(sysMail)) { sysMail.setMailId(SequenceUtil.makeStringId()); - sysMail.setCreateBy(((SysUser)SecurityUtil.currentUserObj()).getUsername()); + sysMail.setCreateBy(((SysUser) SecurityUtil.currentUserObj()).getUsername()); return sysMailMapper.insert(sysMail); } else { return 0; diff --git a/pom.xml b/pom.xml index e71cc6edfc1a537094f4e0db634a72836375849b..ebd39e7e942e1a2e9ecbddc249aac08fc5ca9110 100644 --- a/pom.xml +++ b/pom.xml @@ -82,8 +82,8 @@ 1.9.2 - 11 - 11 + 8 + 8