From 18a60f07f1840a8f4fda8ae0e8aa15ff65bdb239 Mon Sep 17 00:00:00 2001 From: ruibaby Date: Mon, 4 Jun 2018 22:49:24 +0800 Subject: [PATCH] =?UTF-8?q?:apple:=20=E6=96=B0=E5=A2=9E=E5=A4=87=E4=BB=BD?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=EF=BC=88=E8=B5=84=E6=BA=90=E6=96=87=E4=BB=B6?= =?UTF-8?q?=EF=BC=8C=E6=95=B0=E6=8D=AE=E5=BA=93=EF=BC=8C=E6=96=87=E7=AB=A0?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 6 +- .../java/cc/ryanc/halo/config/MvcConfig.java | 3 + .../java/cc/ryanc/halo/model/domain/User.java | 4 +- .../cc/ryanc/halo/model/dto/BackupDto.java | 39 +++ .../cc/ryanc/halo/service/MailService.java | 11 + .../halo/service/impl/MailServiceImpl.java | 33 ++ .../java/cc/ryanc/halo/utils/HaloUtils.java | 117 +++++-- .../web/controller/admin/AdminController.java | 13 +- .../admin/AttachmentController.java | 5 +- .../controller/admin/BackupController.java | 164 ++++++++-- .../controller/admin/CommentController.java | 3 +- .../web/controller/admin/PageController.java | 3 +- .../web/controller/admin/PostController.java | 5 +- .../web/controller/admin/ThemeController.java | 5 +- .../controller/core/InstallController.java | 3 +- .../front/FrontCommentController.java | 3 +- .../templates/admin/admin_backup.ftl | 301 +++++++++++++++++- .../templates/admin/module/_sidebar.ftl | 2 +- .../templates/common/mail/mail_attach.ftl | 15 + 19 files changed, 666 insertions(+), 69 deletions(-) create mode 100644 src/main/java/cc/ryanc/halo/model/dto/BackupDto.java create mode 100644 src/main/resources/templates/common/mail/mail_attach.ftl diff --git a/.gitignore b/.gitignore index 321851fc2..878f1cb8d 100755 --- a/.gitignore +++ b/.gitignore @@ -31,5 +31,7 @@ nbdist/ */.DS_Store ### VS Code ### -.project -.factorypath +*.project +*.factorypath + +~/ diff --git a/src/main/java/cc/ryanc/halo/config/MvcConfig.java b/src/main/java/cc/ryanc/halo/config/MvcConfig.java index 6c4346ec5..06a4f3c26 100644 --- a/src/main/java/cc/ryanc/halo/config/MvcConfig.java +++ b/src/main/java/cc/ryanc/halo/config/MvcConfig.java @@ -38,6 +38,7 @@ public class MvcConfig implements WebMvcConfigurer { public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loginInterceptor) .addPathPatterns("/admin/**") + .addPathPatterns("/backup/**") .excludePathPatterns("/admin/login") .excludePathPatterns("/admin/getLogin") .excludePathPatterns("/static/**"); @@ -63,5 +64,7 @@ public class MvcConfig implements WebMvcConfigurer { .addResourceLocations("classpath:/upload/"); registry.addResourceHandler("/favicon.ico") .addResourceLocations("classpath:/static/images/favicon.ico"); + registry.addResourceHandler("/backup/**") + .addResourceLocations("file:///"+System.getProperties().getProperty("user.home")+"/halo/backup/"); } } diff --git a/src/main/java/cc/ryanc/halo/model/domain/User.java b/src/main/java/cc/ryanc/halo/model/domain/User.java index 814333588..5826c884b 100755 --- a/src/main/java/cc/ryanc/halo/model/domain/User.java +++ b/src/main/java/cc/ryanc/halo/model/domain/User.java @@ -61,7 +61,7 @@ public class User implements Serializable { /** * 是否禁用登录 */ - private String loginEnable; + private String loginEnable = "true"; /** * 最后一次登录时间 @@ -71,5 +71,5 @@ public class User implements Serializable { /** * 登录错误次数记录 */ - private Integer loginError; + private Integer loginError = 0; } diff --git a/src/main/java/cc/ryanc/halo/model/dto/BackupDto.java b/src/main/java/cc/ryanc/halo/model/dto/BackupDto.java new file mode 100644 index 000000000..0495c82c8 --- /dev/null +++ b/src/main/java/cc/ryanc/halo/model/dto/BackupDto.java @@ -0,0 +1,39 @@ +package cc.ryanc.halo.model.dto; + +import lombok.Data; + +import java.util.Date; + +/** + * @author : RYAN0UP + * @version : 1.0 + * @date : 2018/6/4 + */ +@Data +public class BackupDto { + + /** + * 文件名 + */ + private String fileName; + + /** + * 创建时间 + */ + private Date createAt; + + /** + * 文件大小 + */ + private String fileSize; + + /** + * 文件类型 + */ + private String fileType; + + /** + * 备份类型 + */ + private String backupType; +} diff --git a/src/main/java/cc/ryanc/halo/service/MailService.java b/src/main/java/cc/ryanc/halo/service/MailService.java index 884330409..c7f2da97f 100644 --- a/src/main/java/cc/ryanc/halo/service/MailService.java +++ b/src/main/java/cc/ryanc/halo/service/MailService.java @@ -27,4 +27,15 @@ public interface MailService { * @param templateName 模板路径 */ void sendTemplateMail(String to, String subject, Map content, String templateName); + + /** + * 发送带有附件的邮件 + * + * @param to 接收者 + * @param subject 主题 + * @param content 内容 + * @param templateName 模板路径 + * @param attachSrc 附件路径 + */ + void sendAttachMail(String to, String subject, Map content, String templateName, String attachSrc); } diff --git a/src/main/java/cc/ryanc/halo/service/impl/MailServiceImpl.java b/src/main/java/cc/ryanc/halo/service/impl/MailServiceImpl.java index 1d67f7548..7439de194 100644 --- a/src/main/java/cc/ryanc/halo/service/impl/MailServiceImpl.java +++ b/src/main/java/cc/ryanc/halo/service/impl/MailServiceImpl.java @@ -10,6 +10,7 @@ import org.springframework.stereotype.Service; import org.springframework.ui.freemarker.FreeMarkerTemplateUtils; import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; +import java.io.File; import java.util.Map; /** @@ -76,4 +77,36 @@ public class MailServiceImpl implements MailService { e.printStackTrace(); } } + + /** + * 发送带有附件的邮件 + * + * @param to 接收者 + * @param subject 主题 + * @param content 内容 + * @param templateName 模板路径 + * @param attachSrc 附件路径 + */ + @Override + public void sendAttachMail(String to, String subject, Map content, String templateName, String attachSrc) { + //配置邮件服务器 + HaloUtils.configMail( + HaloConst.OPTIONS.get("mail_smtp_host"), + HaloConst.OPTIONS.get("mail_smtp_username"), + HaloConst.OPTIONS.get("mail_smtp_password")); + File file = new File(attachSrc); + String text = ""; + try{ + Template template = freeMarker.getConfiguration().getTemplate(templateName); + text = FreeMarkerTemplateUtils.processTemplateIntoString(template,content); + OhMyEmail.subject(subject) + .from(HaloConst.OPTIONS.get("mail_from_name")) + .to(to) + .html(text) + .attach(file,file.getName()) + .send(); + }catch (Exception e){ + e.printStackTrace(); + } + } } diff --git a/src/main/java/cc/ryanc/halo/utils/HaloUtils.java b/src/main/java/cc/ryanc/halo/utils/HaloUtils.java index 602afcba3..5732a6c29 100755 --- a/src/main/java/cc/ryanc/halo/utils/HaloUtils.java +++ b/src/main/java/cc/ryanc/halo/utils/HaloUtils.java @@ -1,8 +1,10 @@ package cc.ryanc.halo.utils; import cc.ryanc.halo.model.domain.Post; +import cc.ryanc.halo.model.dto.BackupDto; import cc.ryanc.halo.model.dto.HaloConst; import cc.ryanc.halo.model.dto.Theme; +import cn.hutool.core.io.FileUtil; import com.sun.syndication.feed.rss.Channel; import com.sun.syndication.feed.rss.Content; import com.sun.syndication.feed.rss.Item; @@ -17,13 +19,18 @@ import javax.imageio.ImageIO; import javax.imageio.ImageReadParam; import javax.imageio.ImageReader; import javax.imageio.stream.ImageInputStream; -import javax.servlet.http.HttpServletRequest; import java.awt.*; import java.awt.image.BufferedImage; import java.io.*; import java.net.URI; import java.net.URL; import java.net.URLConnection; +import java.nio.file.Files; +import java.nio.file.LinkOption; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.attribute.BasicFileAttributeView; +import java.nio.file.attribute.BasicFileAttributes; import java.text.SimpleDateFormat; import java.time.Instant; import java.time.ZoneId; @@ -104,6 +111,84 @@ public class HaloUtils { return FILE_LIST; } + /** + * 获取备份文件信息 + * + * @param dir dir + * @return List + */ + public static List getBackUps(String dir) { + String srcPathStr = System.getProperties().getProperty("user.home") + "/halo/backup/" + dir; + File srcPath = new File(srcPathStr); + File[] files = srcPath.listFiles(); + List backupDtos = new ArrayList<>(); + BackupDto backupDto = null; + //遍历文件 + for (File file : files) { + if (file.isFile()) { + if (StringUtils.equals(file.getName(), ".DS_Store")) { + continue; + } + backupDto = new BackupDto(); + backupDto.setFileName(file.getName()); + backupDto.setCreateAt(getCreateTime(file.getAbsolutePath())); + backupDto.setFileType(FileUtil.getType(file)); + backupDto.setFileSize(parseSize(file.length())); + backupDto.setBackupType(dir); + backupDtos.add(backupDto); + } + } + return backupDtos; + } + + /** + * 转换文件大小 + * + * @param size size + * @return string + */ + public static String parseSize(long size) { + if (size < 1024) { + return String.valueOf(size) + "B"; + } else { + size = size / 1024; + } + if (size < 1024) { + return String.valueOf(size) + "KB"; + } else { + size = size / 1024; + } + if (size < 1024) { + size = size * 100; + return String.valueOf((size / 100)) + "." + String.valueOf((size % 100)) + "MB"; + } else { + size = size * 100 / 1024; + return String.valueOf((size / 100)) + "." + String.valueOf((size % 100)) + "GB"; + } + } + + /** + * 获取文件创建时间 + * + * @param srcPath 文件绝对路径 + * @return 时间 + */ + public static Date getCreateTime(String srcPath) { + Path path = Paths.get(srcPath); + BasicFileAttributeView basicview = Files.getFileAttributeView(path, BasicFileAttributeView.class, LinkOption.NOFOLLOW_LINKS); + BasicFileAttributes attr; + try { + attr = basicview.readAttributes(); + Date createDate = new Date(attr.creationTime().toMillis()); + return createDate; + } catch (Exception e) { + e.printStackTrace(); + } + Calendar cal = Calendar.getInstance(); + cal.set(1970, 0, 1, 0, 0, 0); + return cal.getTime(); + } + /** * 获取所有主题 * @@ -215,26 +300,6 @@ public class HaloUtils { return Instant.ofEpochSecond(unixTime).atZone(ZoneId.systemDefault()).format(DateTimeFormatter.ofPattern(format)); } - /** - * 获取客户端ip地址 - * - * @param request request - * @return string - */ - public static String getIpAddr(HttpServletRequest request) { - String ip = request.getHeader("x-forwarded-for"); - if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { - ip = request.getHeader("Proxy-Client-IP"); - } - if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { - ip = request.getHeader("WL-Proxy-Client-IP"); - } - if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { - ip = request.getRemoteAddr(); - } - return ip; - } - /** * 备份数据库 * @@ -288,7 +353,14 @@ public class HaloUtils { return false; } - public static void dbToFile(String data,String filePath,String fileName){ + /** + * 导出为文件 + * + * @param data 内容 + * @param filePath 保存路径 + * @param fileName 文件名 + */ + public static void postToFile(String data, String filePath, String fileName) { try{ File file =new File(filePath); if(!file.exists()){ @@ -299,7 +371,6 @@ public class HaloUtils { BufferedWriter bufferWritter = new BufferedWriter(fileWritter); bufferWritter.write(data); bufferWritter.close(); - System.out.println("Done"); }catch (Exception e){ e.printStackTrace(); } diff --git a/src/main/java/cc/ryanc/halo/web/controller/admin/AdminController.java b/src/main/java/cc/ryanc/halo/web/controller/admin/AdminController.java index e86453c1f..681238436 100755 --- a/src/main/java/cc/ryanc/halo/web/controller/admin/AdminController.java +++ b/src/main/java/cc/ryanc/halo/web/controller/admin/AdminController.java @@ -18,6 +18,7 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.lang.Validator; import cn.hutool.core.util.ObjectUtil; import cn.hutool.crypto.SecureUtil; +import cn.hutool.extra.servlet.ServletUtil; import cn.hutool.http.HtmlUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -126,9 +127,11 @@ public class AdminController extends BaseController { //已注册账号,单用户,只有一个 User aUser = userService.findUser(); //首先判断是否已经被禁用已经是否已经过了10分钟 - Date loginLast = aUser.getLoginLast(); + Date loginLast = DateUtil.date(); + if(null!=aUser.getLoginLast()){ + loginLast = aUser.getLoginLast(); + } Long between = DateUtil.between(loginLast, DateUtil.date(), DateUnit.MINUTE); - log.info(between+""); if (StringUtils.equals(aUser.getLoginEnable(), "false") && (between < 10)) { return new JsonResult(0, "已禁止登录,请10分钟后再试"); } @@ -145,7 +148,7 @@ public class AdminController extends BaseController { session.setAttribute(HaloConst.USER_SESSION_KEY, aUser); //重置用户的登录状态为正常 userService.updateUserNormal(); - logsService.saveByLogs(new Logs(LogsRecord.LOGIN, LogsRecord.LOGIN_SUCCESS, HaloUtils.getIpAddr(request), DateUtil.date())); + logsService.saveByLogs(new Logs(LogsRecord.LOGIN, LogsRecord.LOGIN_SUCCESS, ServletUtil.getClientIP(request), DateUtil.date())); return new JsonResult(1, "登录成功!"); } else { //更新失败次数 @@ -158,7 +161,7 @@ public class AdminController extends BaseController { new Logs( LogsRecord.LOGIN, LogsRecord.LOGIN_ERROR + "[" + HtmlUtil.encode(loginName) + "," + HtmlUtil.encode(loginPwd) + "]", - HaloUtils.getIpAddr(request), + ServletUtil.getClientIP(request), DateUtil.date() ) ); @@ -175,7 +178,7 @@ public class AdminController extends BaseController { @GetMapping(value = "/logOut") public String logOut(HttpSession session) { User user = (User) session.getAttribute(HaloConst.USER_SESSION_KEY); - logsService.saveByLogs(new Logs(LogsRecord.LOGOUT, user.getUserName(), HaloUtils.getIpAddr(request), DateUtil.date())); + logsService.saveByLogs(new Logs(LogsRecord.LOGOUT, user.getUserName(), ServletUtil.getClientIP(request), DateUtil.date())); session.invalidate(); log.info("用户[" + user.getUserName() + "]退出登录"); return "redirect:/admin/login"; diff --git a/src/main/java/cc/ryanc/halo/web/controller/admin/AttachmentController.java b/src/main/java/cc/ryanc/halo/web/controller/admin/AttachmentController.java index b28f7d2a1..885c1d944 100755 --- a/src/main/java/cc/ryanc/halo/web/controller/admin/AttachmentController.java +++ b/src/main/java/cc/ryanc/halo/web/controller/admin/AttachmentController.java @@ -9,6 +9,7 @@ import cc.ryanc.halo.service.AttachmentService; import cc.ryanc.halo.service.LogsService; import cc.ryanc.halo.utils.HaloUtils; import cn.hutool.core.date.DateUtil; +import cn.hutool.extra.servlet.ServletUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -174,7 +175,7 @@ public class AttachmentController { updateConst(); log.info("上传文件[" + fileName + "]到[" + mediaPath.getAbsolutePath() + "]成功"); logsService.saveByLogs( - new Logs(LogsRecord.UPLOAD_FILE, fileName, HaloUtils.getIpAddr(request), DateUtil.date()) + new Logs(LogsRecord.UPLOAD_FILE, fileName, ServletUtil.getClientIP(request), DateUtil.date()) ); result.put("success", 1); @@ -246,7 +247,7 @@ public class AttachmentController { updateConst(); log.info("删除文件[" + delFileName + "]成功!"); logsService.saveByLogs( - new Logs(LogsRecord.REMOVE_FILE, delFileName, HaloUtils.getIpAddr(request), DateUtil.date()) + new Logs(LogsRecord.REMOVE_FILE, delFileName, ServletUtil.getClientIP(request), DateUtil.date()) ); } else { log.error("删除附件[" + delFileName + "]失败!"); diff --git a/src/main/java/cc/ryanc/halo/web/controller/admin/BackupController.java b/src/main/java/cc/ryanc/halo/web/controller/admin/BackupController.java index 5969687bc..79560998f 100644 --- a/src/main/java/cc/ryanc/halo/web/controller/admin/BackupController.java +++ b/src/main/java/cc/ryanc/halo/web/controller/admin/BackupController.java @@ -1,18 +1,31 @@ package cc.ryanc.halo.web.controller.admin; import cc.ryanc.halo.model.domain.Post; +import cc.ryanc.halo.model.domain.User; +import cc.ryanc.halo.model.dto.BackupDto; import cc.ryanc.halo.model.dto.HaloConst; +import cc.ryanc.halo.model.dto.JsonResult; +import cc.ryanc.halo.service.MailService; import cc.ryanc.halo.service.PostService; import cc.ryanc.halo.utils.HaloUtils; +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.ZipUtil; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; import org.springframework.util.ResourceUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import javax.servlet.http.HttpSession; import java.io.File; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * @author : RYAN0UP @@ -28,6 +41,10 @@ public class BackupController { @Autowired private PostService postService; + @Autowired + private MailService mailService; + + /** * 渲染备份页面 * @@ -35,55 +52,162 @@ public class BackupController { * @return 模板路径admin/admin_backup */ @GetMapping - public String backup() { + public String backup(Model model) { + List resourcesBackup = HaloUtils.getBackUps("resources"); + List databasesBackup = HaloUtils.getBackUps("databases"); + List postsBackup = HaloUtils.getBackUps("posts"); + model.addAttribute("resourcesBackup", resourcesBackup); + model.addAttribute("databasesBackup", databasesBackup); + model.addAttribute("postsBackup", postsBackup); return "admin/admin_backup"; } + /** + * 执行备份 + * + * @param type 备份类型 + * @return JsonResult + */ + @GetMapping(value = "doBackup") + @ResponseBody + public JsonResult doBackup(@RequestParam("type") String type) { + if (StringUtils.equals("resources", type)) { + return this.backupResources(); + } else if (StringUtils.equals("db", type)) { + return this.backupDatabase(); + } else if (StringUtils.equals("posts", type)) { + return this.backupPosts(); + } else { + return new JsonResult(0, "备份失败!"); + } + } + /** * 备份数据库 * * @return 重定向到/admin/backup */ - @GetMapping(value = "/backupDb") - public String backupDatabase() { - String fileName = "db_backup_" + HaloUtils.getStringDate("yyyy_MM_dd_HH_mm_ss") + ".sql"; + public JsonResult backupDatabase() { try { - File path = new File(ResourceUtils.getURL("classpath:").getPath()); - String savePath = path.getAbsolutePath() + "/backup/database"; - HaloUtils.exportDatabase("localhost", "root", "123456", savePath, fileName, "testdb"); + String srcPath = System.getProperties().getProperty("user.home") + "/halo"; + String distName = "databases_backup_" + HaloUtils.getStringDate("yyyyMMddHHmmss"); + ZipUtil.zip(srcPath + "/halo.mv.db", System.getProperties().getProperty("user.home") + "/halo/backup/databases/" + distName + ".zip"); + return new JsonResult(1, "备份成功!"); } catch (Exception e) { - log.error("未知错误:{0}", e.getMessage()); + log.error("未知错误:", e.getMessage()); + return new JsonResult(0, "备份失败!"); } - return "redirect:/admin/backup"; } /** * 备份资源文件 重要 * - * @return return + * @return JsonResult */ - @GetMapping(value = "/backupRe") - public String backupResources() { - return null; + public JsonResult backupResources() { + try { + File path = new File(ResourceUtils.getURL("classpath:").getPath()); + String srcPath = path.getAbsolutePath(); + String distName = "resources_backup_" + HaloUtils.getStringDate("yyyyMMddHHmmss"); + //执行打包 + ZipUtil.zip(srcPath, System.getProperties().getProperty("user.home") + "/halo/backup/resources/" + distName + ".zip"); + return new JsonResult(1, "备份成功!"); + } catch (Exception e) { + e.printStackTrace(); + return new JsonResult(0, "备份失败!"); + } } /** * 备份文章,导出markdown文件 * - * @return 重定向到/admin/backup + * @return JsonResult */ - @GetMapping(value = "/backupPost") - public String backupPosts() { + public JsonResult backupPosts() { List posts = postService.findAllPosts(HaloConst.POST_TYPE_POST); + posts.addAll(postService.findAllPosts(HaloConst.POST_TYPE_PAGE)); try { - File path = new File(ResourceUtils.getURL("classpath:").getPath()); - String savePath = path.getAbsolutePath() + "/backup/posts/posts_backup_" + HaloUtils.getStringDate("yyyy_MM_dd_HH_mm_ss"); + //打包好的文件名 + String distName = "posts_backup_" + HaloUtils.getStringDate("yyyyMMddHHmmss"); + String srcPath = System.getProperties().getProperty("user.home") + "/halo/backup/posts/" + distName; for (Post post : posts) { - HaloUtils.dbToFile(post.getPostContentMd(), savePath, post.getPostTitle() + ".md"); + HaloUtils.postToFile(post.getPostContentMd(), srcPath, post.getPostTitle() + ".md"); } + //打包导出好的文章 + ZipUtil.zip(srcPath, System.getProperties().getProperty("user.home") + "/halo/backup/posts/" + distName + ".zip"); + FileUtil.del(srcPath); + return new JsonResult(1, "备份成功!"); } catch (Exception e) { e.printStackTrace(); + return new JsonResult(0, "备份失败!"); + } + } + + /** + * 删除备份 + * + * @param fileName 文件名 + * @param type 备份类型 + * @return JsonResult + */ + @GetMapping(value = "delBackup") + @ResponseBody + public JsonResult delBackup(@RequestParam("fileName") String fileName, + @RequestParam("type") String type) { + String srcPath = System.getProperties().getProperty("user.home") + "/halo/backup/" + type + "/" + fileName; + try { + FileUtil.del(srcPath); + return new JsonResult(1, "删除成功!"); + } catch (Exception e) { + return new JsonResult(0, "删除失败!"); + } + } + + /** + * 将备份发送到邮箱 + * + * @param fileName 文件名 + * @param type 备份类型 + * @return JsonResult + */ + @GetMapping(value = "sendToEmail") + @ResponseBody + public JsonResult sendToEmail(@RequestParam("fileName") String fileName, + @RequestParam("type") String type, + HttpSession session) { + String srcPath = System.getProperties().getProperty("user.home") + "/halo/backup/" + type + "/" + fileName; + User user = (User) session.getAttribute(HaloConst.USER_SESSION_KEY); + if (null == user.getUserEmail() || StringUtils.equals(user.getUserEmail(), "")) { + return new JsonResult(0, "博主邮箱没有配置!"); + } + if (StringUtils.equals(HaloConst.OPTIONS.get("smtp_email_enable"), "false")) { + return new JsonResult(0, "发信邮箱没有配置!"); + } + new EmailToAdmin(srcPath, user).start(); + return new JsonResult(1, "邮件发送成功!"); + } + + class EmailToAdmin extends Thread { + private String srcPath; + private User user; + + public EmailToAdmin(String srcPath, User user) { + this.srcPath = srcPath; + this.user = user; + } + + @Override + public void run() { + File file = new File(srcPath); + Map content = new HashMap<>(); + try { + content.put("fileName", file.getName()); + content.put("createAt", HaloUtils.getCreateTime(srcPath)); + content.put("size", HaloUtils.parseSize(file.length())); + mailService.sendAttachMail(user.getUserEmail(), "有新的备份!", content, "common/mail/mail_attach.ftl", srcPath); + } catch (Exception e) { + log.error("邮件服务器未配置:", e.getMessage()); + } } - return "redirect:/admin/backup"; } } diff --git a/src/main/java/cc/ryanc/halo/web/controller/admin/CommentController.java b/src/main/java/cc/ryanc/halo/web/controller/admin/CommentController.java index ccd85643b..688bf51ab 100755 --- a/src/main/java/cc/ryanc/halo/web/controller/admin/CommentController.java +++ b/src/main/java/cc/ryanc/halo/web/controller/admin/CommentController.java @@ -13,6 +13,7 @@ import cc.ryanc.halo.web.controller.core.BaseController; import cn.hutool.core.date.DateUtil; import cn.hutool.core.lang.Validator; import cn.hutool.crypto.SecureUtil; +import cn.hutool.extra.servlet.ServletUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -195,7 +196,7 @@ public class CommentController extends BaseController{ comment.setCommentAuthor(user.getUserDisplayName()); comment.setCommentAuthorEmail(user.getUserEmail()); comment.setCommentAuthorUrl(HaloConst.OPTIONS.get("blog_url")); - comment.setCommentAuthorIp(HaloUtils.getIpAddr(request)); + comment.setCommentAuthorIp(ServletUtil.getClientIP(request)); comment.setCommentAuthorAvatarMd5(SecureUtil.md5(user.getUserEmail())); comment.setCommentDate(DateUtil.date()); String lastContent = " //@"+lastComment.getCommentAuthor()+":"+lastComment.getCommentContent(); diff --git a/src/main/java/cc/ryanc/halo/web/controller/admin/PageController.java b/src/main/java/cc/ryanc/halo/web/controller/admin/PageController.java index a866c4269..bddd5be33 100755 --- a/src/main/java/cc/ryanc/halo/web/controller/admin/PageController.java +++ b/src/main/java/cc/ryanc/halo/web/controller/admin/PageController.java @@ -10,6 +10,7 @@ import cc.ryanc.halo.service.LogsService; import cc.ryanc.halo.service.PostService; import cc.ryanc.halo.utils.HaloUtils; import cn.hutool.core.date.DateUtil; +import cn.hutool.extra.servlet.ServletUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -232,7 +233,7 @@ public class PageController { post.setPostUpdate(DateUtil.date()); } postService.saveByPost(post); - logsService.saveByLogs(new Logs(LogsRecord.PUSH_PAGE, post.getPostTitle(), HaloUtils.getIpAddr(request), DateUtil.date())); + logsService.saveByLogs(new Logs(LogsRecord.PUSH_PAGE, post.getPostTitle(), ServletUtil.getClientIP(request), DateUtil.date())); return new JsonResult(1,msg); } catch (Exception e) { log.error("未知错误:{0}", e.getMessage()); diff --git a/src/main/java/cc/ryanc/halo/web/controller/admin/PostController.java b/src/main/java/cc/ryanc/halo/web/controller/admin/PostController.java index 0a0f83237..37cd5b0b6 100755 --- a/src/main/java/cc/ryanc/halo/web/controller/admin/PostController.java +++ b/src/main/java/cc/ryanc/halo/web/controller/admin/PostController.java @@ -11,6 +11,7 @@ import cc.ryanc.halo.service.TagService; import cc.ryanc.halo.utils.HaloUtils; import cc.ryanc.halo.web.controller.core.BaseController; import cn.hutool.core.date.DateUtil; +import cn.hutool.extra.servlet.ServletUtil; import cn.hutool.http.HtmlUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -193,7 +194,7 @@ public class PostController extends BaseController{ } post.setPostUrl(urlFilter(post.getPostUrl())); postService.saveByPost(post); - logsService.saveByLogs(new Logs(LogsRecord.PUSH_POST,post.getPostTitle(),HaloUtils.getIpAddr(request),DateUtil.date())); + logsService.saveByLogs(new Logs(LogsRecord.PUSH_POST,post.getPostTitle(),ServletUtil.getClientIP(request),DateUtil.date())); return new JsonResult(1,msg); }catch (Exception e){ log.error("未知错误:", e.getMessage()); @@ -298,7 +299,7 @@ public class PostController extends BaseController{ try{ Optional post = postService.findByPostId(postId); postService.removeByPostId(postId); - logsService.saveByLogs(new Logs(LogsRecord.REMOVE_POST,post.get().getPostTitle(),HaloUtils.getIpAddr(request),DateUtil.date())); + logsService.saveByLogs(new Logs(LogsRecord.REMOVE_POST,post.get().getPostTitle(),ServletUtil.getClientIP(request),DateUtil.date())); }catch (Exception e){ log.error("未知错误:{0}",e.getMessage()); } diff --git a/src/main/java/cc/ryanc/halo/web/controller/admin/ThemeController.java b/src/main/java/cc/ryanc/halo/web/controller/admin/ThemeController.java index 23242a814..93b722a30 100755 --- a/src/main/java/cc/ryanc/halo/web/controller/admin/ThemeController.java +++ b/src/main/java/cc/ryanc/halo/web/controller/admin/ThemeController.java @@ -11,6 +11,7 @@ import cc.ryanc.halo.web.controller.core.BaseController; import cn.hutool.core.date.DateUtil; import cn.hutool.core.io.FileUtil; import cn.hutool.core.util.ZipUtil; +import cn.hutool.extra.servlet.ServletUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -78,7 +79,7 @@ public class ThemeController extends BaseController { BaseController.THEME = siteTheme; log.info("已将主题改变为:" + siteTheme); logsService.saveByLogs( - new Logs(LogsRecord.CHANGE_THEME, "更换为" + siteTheme, HaloUtils.getIpAddr(request), DateUtil.date()) + new Logs(LogsRecord.CHANGE_THEME, "更换为" + siteTheme, ServletUtil.getClientIP(request), DateUtil.date()) ); return new JsonResult(1,"主题已设置为"+siteTheme); } catch (Exception e) { @@ -106,7 +107,7 @@ public class ThemeController extends BaseController { file.transferTo(themePath); log.info("上传主题成功,路径:" + themePath.getAbsolutePath()); logsService.saveByLogs( - new Logs(LogsRecord.UPLOAD_THEME, file.getOriginalFilename(), HaloUtils.getIpAddr(request), DateUtil.date()) + new Logs(LogsRecord.UPLOAD_THEME, file.getOriginalFilename(), ServletUtil.getClientIP(request), DateUtil.date()) ); ZipUtil.unzip(themePath,new File(basePath.getAbsolutePath(), "templates/themes/")); FileUtil.del(themePath); diff --git a/src/main/java/cc/ryanc/halo/web/controller/core/InstallController.java b/src/main/java/cc/ryanc/halo/web/controller/core/InstallController.java index 73bd8c9b1..39eed0613 100644 --- a/src/main/java/cc/ryanc/halo/web/controller/core/InstallController.java +++ b/src/main/java/cc/ryanc/halo/web/controller/core/InstallController.java @@ -7,6 +7,7 @@ import cc.ryanc.halo.service.*; import cc.ryanc.halo.utils.HaloUtils; import cn.hutool.core.date.DateUtil; import cn.hutool.crypto.SecureUtil; +import cn.hutool.extra.servlet.ServletUtil; import freemarker.template.Configuration; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -177,7 +178,7 @@ public class InstallController { new Logs( LogsRecord.INSTALL, "安装成功,欢迎使用Halo。", - HaloUtils.getIpAddr(request), + ServletUtil.getClientIP(request), DateUtil.date() ) ); diff --git a/src/main/java/cc/ryanc/halo/web/controller/front/FrontCommentController.java b/src/main/java/cc/ryanc/halo/web/controller/front/FrontCommentController.java index 2cc1597a3..4722357d1 100644 --- a/src/main/java/cc/ryanc/halo/web/controller/front/FrontCommentController.java +++ b/src/main/java/cc/ryanc/halo/web/controller/front/FrontCommentController.java @@ -11,6 +11,7 @@ import cc.ryanc.halo.service.UserService; import cc.ryanc.halo.utils.HaloUtils; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.URLUtil; +import cn.hutool.extra.servlet.ServletUtil; import cn.hutool.http.HtmlUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -103,7 +104,7 @@ public class FrontCommentController { comment.setCommentAuthorEmail(HtmlUtil.encode(comment.getCommentAuthorEmail()).toLowerCase()); comment.setPost(post); comment.setCommentDate(DateUtil.date()); - comment.setCommentAuthorIp(HaloUtils.getIpAddr(request)); + comment.setCommentAuthorIp(ServletUtil.getClientIP(request)); comment.setIsAdmin(0); comment.setCommentAuthor(HtmlUtil.encode(comment.getCommentAuthor())); if(comment.getCommentParent()>0){ diff --git a/src/main/resources/templates/admin/admin_backup.ftl b/src/main/resources/templates/admin/admin_backup.ftl index 9ef7ba2f2..0f65bc170 100644 --- a/src/main/resources/templates/admin/admin_backup.ftl +++ b/src/main/resources/templates/admin/admin_backup.ftl @@ -7,21 +7,310 @@ <#include "module/_sidebar.ftl">
-

正在开发中...

+

博客备份

- +
<#include "module/_footer.ftl"> diff --git a/src/main/resources/templates/admin/module/_sidebar.ftl b/src/main/resources/templates/admin/module/_sidebar.ftl index 2ef162c28..627a9773e 100755 --- a/src/main/resources/templates/admin/module/_sidebar.ftl +++ b/src/main/resources/templates/admin/module/_sidebar.ftl @@ -101,7 +101,7 @@ diff --git a/src/main/resources/templates/common/mail/mail_attach.ftl b/src/main/resources/templates/common/mail/mail_attach.ftl new file mode 100644 index 000000000..110c96f6a --- /dev/null +++ b/src/main/resources/templates/common/mail/mail_attach.ftl @@ -0,0 +1,15 @@ +
+
+
+

+ 您有新的备份,请按需下载附件。 +

+
+ 备份详情:
+ 文件名:${fileName}
+ 备份时间:${createAt?string("yyyy-MM-dd HH:mm")}
+ 文件大小:${size} +
+
+
+
\ No newline at end of file