mirror of https://github.com/halo-dev/halo
parent
3c1f251b88
commit
86d0eee96e
|
@ -7,6 +7,7 @@ import cc.ryanc.halo.service.AttachmentService;
|
|||
import cc.ryanc.halo.service.OptionsService;
|
||||
import cc.ryanc.halo.utils.HaloUtils;
|
||||
import cc.ryanc.halo.web.controller.core.BaseController;
|
||||
import cn.hutool.cron.CronUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -38,6 +39,9 @@ public class StartupConfig implements ApplicationListener<ContextRefreshedEvent>
|
|||
this.loadOptions();
|
||||
this.loadFiles();
|
||||
this.loadThemes();
|
||||
//启动定时任务
|
||||
CronUtil.start();
|
||||
log.info("定时任务启动成功!");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,6 +8,7 @@ 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.date.DateUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.ZipUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
@ -23,6 +24,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
|||
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -52,13 +54,19 @@ public class BackupController {
|
|||
* @return 模板路径admin/admin_backup
|
||||
*/
|
||||
@GetMapping
|
||||
public String backup(Model model) {
|
||||
List<BackupDto> resourcesBackup = HaloUtils.getBackUps("resources");
|
||||
List<BackupDto> databasesBackup = HaloUtils.getBackUps("databases");
|
||||
List<BackupDto> postsBackup = HaloUtils.getBackUps("posts");
|
||||
model.addAttribute("resourcesBackup", resourcesBackup);
|
||||
model.addAttribute("databasesBackup", databasesBackup);
|
||||
model.addAttribute("postsBackup", postsBackup);
|
||||
public String backup(@RequestParam(value = "type",defaultValue = "resources") String type,Model model) {
|
||||
List<BackupDto> backups = null;
|
||||
if(StringUtils.equals(type,"resources")){
|
||||
backups = HaloUtils.getBackUps("resources");
|
||||
}else if(StringUtils.equals(type,"databases")){
|
||||
backups = HaloUtils.getBackUps("databases");
|
||||
}else if(StringUtils.equals(type,"posts")){
|
||||
backups = HaloUtils.getBackUps("posts");
|
||||
}else{
|
||||
backups = new ArrayList<>();
|
||||
}
|
||||
model.addAttribute("backups", backups);
|
||||
model.addAttribute("type", type);
|
||||
return "admin/admin_backup";
|
||||
}
|
||||
|
||||
|
@ -73,7 +81,7 @@ public class BackupController {
|
|||
public JsonResult doBackup(@RequestParam("type") String type) {
|
||||
if (StringUtils.equals("resources", type)) {
|
||||
return this.backupResources();
|
||||
} else if (StringUtils.equals("db", type)) {
|
||||
} else if (StringUtils.equals("databases", type)) {
|
||||
return this.backupDatabase();
|
||||
} else if (StringUtils.equals("posts", type)) {
|
||||
return this.backupPosts();
|
||||
|
@ -89,9 +97,14 @@ public class BackupController {
|
|||
*/
|
||||
public JsonResult backupDatabase() {
|
||||
try {
|
||||
String srcPath = System.getProperties().getProperty("user.home") + "/halo";
|
||||
if(HaloUtils.getBackUps("databases").size()>10){
|
||||
FileUtil.del(System.getProperties().getProperty("user.home") + "/halo/backup/databases/");
|
||||
}
|
||||
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");
|
||||
//压缩文件
|
||||
ZipUtil.zip(srcPath + "halo.mv.db", System.getProperties().getProperty("user.home") + "/halo/backup/databases/" + distName + ".zip");
|
||||
log.info("当前时间:"+DateUtil.now()+",执行了数据库备份。");
|
||||
return new JsonResult(1, "备份成功!");
|
||||
} catch (Exception e) {
|
||||
log.error("未知错误:", e.getMessage());
|
||||
|
@ -106,11 +119,15 @@ public class BackupController {
|
|||
*/
|
||||
public JsonResult backupResources() {
|
||||
try {
|
||||
if(HaloUtils.getBackUps("resources").size()>10){
|
||||
FileUtil.del(System.getProperties().getProperty("user.home") + "/halo/backup/resources/");
|
||||
}
|
||||
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");
|
||||
log.info("当前时间:"+DateUtil.now()+",执行了资源文件备份。");
|
||||
return new JsonResult(1, "备份成功!");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
@ -127,6 +144,9 @@ public class BackupController {
|
|||
List<Post> posts = postService.findAllPosts(HaloConst.POST_TYPE_POST);
|
||||
posts.addAll(postService.findAllPosts(HaloConst.POST_TYPE_PAGE));
|
||||
try {
|
||||
if(HaloUtils.getBackUps("posts").size()>10){
|
||||
FileUtil.del(System.getProperties().getProperty("user.home") + "/halo/backup/posts/");
|
||||
}
|
||||
//打包好的文件名
|
||||
String distName = "posts_backup_" + HaloUtils.getStringDate("yyyyMMddHHmmss");
|
||||
String srcPath = System.getProperties().getProperty("user.home") + "/halo/backup/posts/" + distName;
|
||||
|
@ -134,8 +154,9 @@ public class BackupController {
|
|||
HaloUtils.postToFile(post.getPostContentMd(), srcPath, post.getPostTitle() + ".md");
|
||||
}
|
||||
//打包导出好的文章
|
||||
ZipUtil.zip(srcPath, System.getProperties().getProperty("user.home") + "/halo/backup/posts/" + distName + ".zip");
|
||||
ZipUtil.zip(srcPath, srcPath + ".zip");
|
||||
FileUtil.del(srcPath);
|
||||
log.info("当前时间:"+DateUtil.now()+",执行了文章备份。");
|
||||
return new JsonResult(1, "备份成功!");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
cc.ryanc.halo.web.controller.admin.BackupController.backupResources = 0 0 1 * * ?
|
||||
cc.ryanc.halo.web.controller.admin.BackupController.backupDatabase = 0 0 1 * * ?
|
||||
cc.ryanc.halo.web.controller.admin.BackupController.backupPosts = 0 0 1 * * ?
|
|
@ -6,6 +6,9 @@
|
|||
<!-- 菜单栏模块 -->
|
||||
<#include "module/_sidebar.ftl">
|
||||
<div class="content-wrapper">
|
||||
<style type="text/css" rel="stylesheet">
|
||||
.resourceType,.databaseType,.postType{list-style:none;float:left;margin:0;padding-bottom:10px}
|
||||
</style>
|
||||
<section class="content-header">
|
||||
<h1 style="display: inline-block;">博客备份</h1>
|
||||
<ol class="breadcrumb">
|
||||
|
@ -18,143 +21,57 @@
|
|||
</section>
|
||||
<section class="content container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="nav-tabs-custom">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active">
|
||||
<a href="#resources" data-toggle="tab">资源目录备份</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#database" data-toggle="tab">数据库备份</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#post" data-toggle="tab">文章备份</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="resources">
|
||||
<form method="post" class="form-horizontal" id="resourcesBackup">
|
||||
<div class="box-body table-responsive" style="padding: 10px 0;">
|
||||
<table class="table table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>文件名称</th>
|
||||
<th>备份时间</th>
|
||||
<th>文件大小</th>
|
||||
<th>文件类型</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<#if resourcesBackup?size gt 0>
|
||||
<#list resourcesBackup as resource>
|
||||
<tr>
|
||||
<td>${resource.fileName}</td>
|
||||
<td>${resource.createAt?string("yyyy-MM-dd HH:mm")}</td>
|
||||
<td>${resource.fileSize}</td>
|
||||
<td>${resource.fileType}</td>
|
||||
<td>
|
||||
<a href="/backup/resources/${resource.fileName}" class="btn btn-xs btn-primary" download="${resource.fileName}">下载</a>
|
||||
<button type="button" class="btn btn-xs btn-info" onclick="sendToEmail('${resource.fileName}','${resource.backupType}')">发送到邮箱</button>
|
||||
<button type="button" class="btn btn-xs btn-danger" onclick="delBackup('${resource.fileName}','${resource.backupType}')">删除</button>
|
||||
</td>
|
||||
</tr>
|
||||
</#list>
|
||||
<#else>
|
||||
<tr>
|
||||
<td colspan="5" style="text-align: center">暂无备份</td>
|
||||
</tr>
|
||||
</#if>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="button" class="btn btn-primary btn-sm " onclick="btn_backup('resources')">备份</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="tab-pane" id="database">
|
||||
<form method="post" class="form-horizontal" id="databaseBackup">
|
||||
<div class="box-body table-responsive" style="padding: 10px 0;">
|
||||
<table class="table table-bordered table-hover">
|
||||
<thead>
|
||||
<div class="col-xs-12">
|
||||
<ul style="list-style: none;padding-left: 0">
|
||||
<li class="resourceType">
|
||||
<a data-pjax="true" href="/admin/backup?type=resources" <#if type=='resources'>style="color: #000" </#if>>资源文件备份</a> |
|
||||
</li>
|
||||
<li class="databaseType">
|
||||
<a data-pjax="true" href="/admin/backup?type=databases" <#if type=='databases'>style="color: #000" </#if>>数据库备份</a> |
|
||||
</li>
|
||||
<li class="postType">
|
||||
<a data-pjax="true" href="/admin/backup?type=posts" <#if type=='posts'>style="color: #000" </#if>>文章备份</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-xs-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-body table-responsive">
|
||||
<table class="table table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>文件名称</th>
|
||||
<th>备份时间</th>
|
||||
<th>文件大小</th>
|
||||
<th>文件类型</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<#if backups?size gt 0>
|
||||
<#list backups as backup>
|
||||
<tr>
|
||||
<th>文件名称</th>
|
||||
<th>备份时间</th>
|
||||
<th>文件大小</th>
|
||||
<th>文件类型</th>
|
||||
<th>操作</th>
|
||||
<td>${backup.fileName}</td>
|
||||
<td>${backup.createAt?string("yyyy-MM-dd HH:mm")}</td>
|
||||
<td>${backup.fileSize}</td>
|
||||
<td>${backup.fileType}</td>
|
||||
<td>
|
||||
<a href="/backup/${type}/${backup.fileName}" class="btn btn-xs btn-primary" download="${backup.fileName}">下载</a>
|
||||
<button type="button" class="btn btn-xs btn-info" onclick="sendToEmail('${backup.fileName}','${backup.backupType}')">发送到邮箱</button>
|
||||
<button type="button" class="btn btn-xs btn-danger" onclick="delBackup('${backup.fileName}','${backup.backupType}')">删除</button>
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<#if databasesBackup?size gt 0>
|
||||
<#list databasesBackup as database>
|
||||
<tr>
|
||||
<td>${database.fileName}</td>
|
||||
<td>${database.createAt?string("yyyy-MM-dd HH:mm")}</td>
|
||||
<td>${database.fileSize}</td>
|
||||
<td>${database.fileType}</td>
|
||||
<td>
|
||||
<a href="/backup/databases/${database.fileName}" class="btn btn-xs btn-primary" download="${database.fileName}">下载</a>
|
||||
<button type="button" class="btn btn-xs btn-info" onclick="sendToEmail('${database.fileName}','${database.backupType}')">发送到邮箱</button>
|
||||
<button type="button" class="btn btn-xs btn-danger" onclick="delBackup('${database.fileName}','${database.backupType}')">删除</button>
|
||||
</td>
|
||||
</tr>
|
||||
</#list>
|
||||
<#else>
|
||||
<tr>
|
||||
<td colspan="5" style="text-align: center">暂无备份</td>
|
||||
</tr>
|
||||
</#if>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="button" class="btn btn-primary btn-sm " onclick="btn_backup('db')">备份</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="tab-pane" id="post">
|
||||
<form method="post" class="form-horizontal" id="postBackup">
|
||||
<div class="box-body table-responsive" style="padding: 10px 0;">
|
||||
<table class="table table-bordered table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>文件名称</th>
|
||||
<th>备份时间</th>
|
||||
<th>文件大小</th>
|
||||
<th>文件类型</th>
|
||||
<th>操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<#if postsBackup?size gt 0>
|
||||
<#list postsBackup as post>
|
||||
<tr>
|
||||
<td>${post.fileName}</td>
|
||||
<td>${post.createAt?string("yyyy-MM-dd HH:mm")}</td>
|
||||
<td>${post.fileSize}</td>
|
||||
<td>${post.fileType}</td>
|
||||
<td>
|
||||
<a href="/backup/posts/${post.fileName}" class="btn btn-xs btn-primary" download="${post.fileName}">下载</a>
|
||||
<button type="button" class="btn btn-xs btn-info" onclick="sendToEmail('${post.fileName}','${post.backupType}')">发送到邮箱</button>
|
||||
<button type="button" class="btn btn-xs btn-danger" onclick="delBackup('${post.fileName}','${post.backupType}')">删除</button>
|
||||
</td>
|
||||
</tr>
|
||||
</#list>
|
||||
<#else>
|
||||
<tr>
|
||||
<td colspan="5" style="text-align: center">暂无备份</td>
|
||||
</tr>
|
||||
</#if>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="box-footer">
|
||||
<button type="button" class="btn btn-primary btn-sm " onclick="btn_backup('posts')">备份</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</#list>
|
||||
<#else>
|
||||
<tr>
|
||||
<th colspan="5" style="text-align: center">暂无备份</th>
|
||||
</tr>
|
||||
</#if>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="box-footer clearfix">
|
||||
<button type="button" class="btn btn-primary btn-sm " onclick="btn_backup('${type}')">备份</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -238,10 +155,7 @@
|
|||
position: 'top-center',
|
||||
textAlign: 'left',
|
||||
loader: true,
|
||||
loaderBg: '#ffffff',
|
||||
afterHidden: function () {
|
||||
window.location.reload();
|
||||
}
|
||||
loaderBg: '#ffffff'
|
||||
});
|
||||
}else{
|
||||
$.toast({
|
||||
|
|
Loading…
Reference in New Issue