This commit is contained in:
2025-12-17 10:18:58 +08:00
commit ad4cb058fc
4112 changed files with 750772 additions and 0 deletions

View File

@@ -0,0 +1,10 @@
<div class="fixed-bar">
<div class="item-title">
<a class="back" href="{:url('Index/switch_map')}" title="返回列表"><i class="fa fa-angle-double-left"></i>返回</a>
<ul class="tab-base nc-row">
<li><a href="{:url("Tools/index")}" class="tab {eq name="$Request.action" value="index"}current{/eq}"><span>数据备份</span></a></li>
<li><a href="{:url("Tools/restore")}" class="tab {if condition="in_array($Request.action, array('restore'))"}current{/if}"><span>数据还原</span></a></li>
</ul>
</div>
</div>

View File

@@ -0,0 +1,233 @@
{include file="public/layout" /}
<body class="bodystyle" style="cursor: default; -moz-user-select: inherit;">
<div id="append_parent"></div>
<div id="ajaxwaitid"></div>
<div class="page">
{include file="tools/bar" /}
<!-- 操作说明 -->
<div id="explanation" class="explanation" style="color: rgb(44, 188, 163); background-color: rgb(237, 251, 248); width: 99%; height: 100%;">
<div id="checkZoom" class="title"><i class="fa fa-lightbulb-o"></i>
<h4 title="提示相关设置操作时应注意的要点">提示</h4>
<span title="收起提示" id="explanationZoom" style="display: block;"></span>
</div>
<ul>
<li>数据备份功能根据你的选择备份全部数据或指定数据,导出的数据文件可用“数据恢复”功能或 phpMyAdmin 导入</li>
<li>建议定期备份数据库</li>
</ul>
</div>
<div class="flexigrid">
<div class="mDiv">
{eq name="$Think.const.CONTROLLER_NAME.'@export'|is_check_access" value="1"}
<div class="fbutton">
<a id="ing_btn">
<div class="add" title="数据备份" onclick="$('.export_btn').trigger('click');">
<span><i class="fa fa-book"></i><span>数据备份</span></span>
</div>
</a>
</div>
{/eq}
</div>
<div class="hDiv">
<div class="hDivBox">
<table cellspacing="0" cellpadding="0" style="width: 100%">
<thead>
<tr>
<th class="sign w40" axis="col0">
<div class="tc"><input type="checkbox" onclick="javascript:$('input[name*=tables]').prop('checked',this.checked);" checked="checked"></div>
</th>
<th abbr="article_title" axis="col3">
<div style="padding-left: 10px;" class="">数据库表</div>
</th>
<th abbr="ac_id" axis="col4" class="w80">
<div class="tc">记录条数</div>
</th>
<th abbr="article_show" axis="col5" class="w80">
<div class="tc">占用空间</div>
</th>
<th abbr="article_time" axis="col6" class="w120">
<div class="tc">编码</div>
</th>
<th abbr="article_time" axis="col6" class="w160">
<div class="tc">创建时间</div>
</th>
<th abbr="article_time" axis="col6" class="w80">
<div class="tc">备份状态</div>
</th>
<th axis="col1" class="w80">
<div class="tc">操作</div>
</th>
</tr>
</thead>
</table>
</div>
</div>
<div class="bDiv" style="height: auto;">
<div id="flexigrid" cellpadding="0" cellspacing="0" border="0">
<form method="post" id="export-form" action="{:url('Tools/export')}">
<table id="tb_flexigrid" style="width: 100%">
<tbody>
{empty name="list"}
<tr>
<td class="no-data" align="center" axis="col0" colspan="50">
<i class="fa fa-exclamation-circle"></i>没有符合条件的记录
</td>
</tr>
{else/}
{foreach name="list" item="vo" key="k" }
<tr data-id="{$vo.Name}">
<td class="sign">
<div class="w40 tc"><input type="checkbox" name="tables[]" value="{$vo.Name}" checked="checked"></div>
</td>
<td style="width: 100%">
<div style="padding-left: 10px;">{$vo.Name}</div>
</td>
<td>
<div class="w80 tc">{$vo.Rows}</div>
</td>
<td>
<div class="w80 tc">{$vo.Data_length|format_bytes}</div>
</td>
<td>
<div class="w120 tc">{$vo.Collation}</div>
</td>
<td>
<div class="w160 tc">{$vo.Create_time}</div>
</td>
<td>
<div class="info w80 tc">未备份</div>
</td>
<td>
<div class="w80 tc">
{eq name="$Think.const.CONTROLLER_NAME.'@optimize'|is_check_access" value="1"}
<!-- <a href="{:url('Tools/optimize',array('tablename'=>$vo['Name']))}" class="btn blue"><i class="fa fa-magic"></i>优化</a> -->
{/eq}
{eq name="$Think.const.CONTROLLER_NAME.'@repair'|is_check_access" value="1"}
<a class="btn green" href="{:url('Tools/repair',array('tablename'=>$vo['Name']))}"><i class="fa fa-wrench"></i>修复</a>
{/eq}
</div>
</td>
</tr>
{/foreach}
{/empty}
</tbody>
</table>
</form>
</div>
<div class="iDiv" style="display: none;"></div>
</div>
<div class="tDiv">
<div class="tDiv2">
<div class="fbutton checkboxall">
<input type="checkbox" onclick="javascript:$('input[name*=tables]').prop('checked',this.checked);" checked="checked">
</div>
{eq name="$Think.const.CONTROLLER_NAME.'@export'|is_check_access" value="1"}
<div class="fbutton export_btn">
<a id="ing_btn" class="layui-btn layui-btn-primary">
<span>数据备份</span>
</a>
</div>
{/eq}
<div class="fbuttonr" style="margin-right: 15px;">
<div class="total">
<h5>共{$tableNum}条数据,共计{$total}</h5>
</div>
</div>
</div>
<div style="clear:both"></div>
</div>
</div>
</div>
<script>
$(document).ready(function(){
// 表格行点击选中切换
$('#tb_flexigrid >tbody >tr').click(function(){
$(this).toggleClass('trSelected');
});
// 点击刷新数据
$('.fa-refresh').click(function(){
location.href = location.href;
});
});
(function($){
var $form = $("#export-form"), $export = $(".export_btn"), tables
$export.click(function(){
if($("input[name^='tables']:checked").length == 0){
layer.alert('请选中要备份的数据表', {icon: 5, title:false, closeBtn:false});
return false;
}
$export.addClass("disabled");
$export.find('a').html("正在发送备份请求...");
$.post(
"{:url('Tools/export', ['_ajax'=>1])}",
$form.serialize(),
function(res){
if(res.code){
tables = res.tables;
var loading = layer.msg('正在备份表(<font id="upgrade_backup_table">'+res.tab.table+'</font>)……<font id="upgrade_backup_speed">0.01</font>%',
{
icon: 1,
time: 3600000, //1小时后后自动关闭
shade: [0.2] //0.1透明度的白色背景
});
$export.find('a').html(res.msg + "开始备份,请不要关闭本页面!");
backup(res.tab);
window.onbeforeunload = function(){ return "正在备份数据库,请不要关闭!" }
} else {
layer.alert(res.msg, {icon: 5, title:false, closeBtn:false});
$export.removeClass("disabled");
$export.find('a').html("立即备份");
}
},
"json"
);
return false;
});
function backup(tab, status){
status && showmsg(tab.id, "开始备份……(0%)");
$.post("{:url('Tools/export', ['_ajax'=>1])}", tab, function(res){
if(res.code){
if (tab.table) {
showmsg(tab.id, res.msg);
$('#upgrade_backup_table').html(tab.table);
$('#upgrade_backup_speed').html(tab.speed);
$export.find('a').html('初始化成功!正在备份表('+tab.table+')……'+tab.speed+'%,请不要关闭本页面!');
} else {
$export.find('a').html('初始化成功!开始备份……,请不要关闭本页面!');
}
if(!$.isPlainObject(res.tab)){
var loading = layer.msg('备份完成……100%,请不要关闭本页面!',
{
icon: 1,
time: 2000, //1小时后后自动关闭
shade: [0.2] //0.1透明度的白色背景
});
$export.removeClass("disabled");
$export.find('a').html("备份完成……100%,点击重新备份");
setTimeout(function(){
layer.closeAll();
layer.alert('备份成功!', {icon: 6, title:false, closeBtn:false});
}, 1000);
window.onbeforeunload = function(){ return null }
return;
}
backup(res.tab, tab.id != res.tab.id);
} else {
layer.closeAll();
$export.removeClass("disabled");
$export.find('a').html("立即备份");
}
}, "json");
}
function showmsg(id, msg){
$form.find("input[value=" + tables[id] + "]").closest("tr").find(".info").html(msg);
}
})(jQuery);
</script>
{include file="public/footer" /}

View File

@@ -0,0 +1,209 @@
{include file="public/layout" /}
<body class="bodystyle" style="cursor: default; -moz-user-select: inherit;">
<div id="append_parent"></div>
<div id="ajaxwaitid"></div>
<div class="page">
{include file="tools/bar" /}
<!-- 操作说明 -->
<div id="explanation" class="explanation" style="color: rgb(44, 188, 163); background-color: rgb(237, 251, 248); width: 99%; height: 100%;">
<div id="checkZoom" class="title"><i class="fa fa-lightbulb-o"></i>
<h4 title="提示相关设置操作时应注意的要点">提示</h4>
<span title="收起提示" id="explanationZoom" style="display: block;"></span>
</div>
<ul>
<li> 数据还原, 点击恢复选项进行数据库导入.</li>
<li> 导入的SQL文件语句必须按照MYSQL的语法编写</li>
</ul>
</div>
<div class="flexigrid">
<div class="hDiv">
<div class="hDivBox">
<table cellspacing="0" cellpadding="0" style="width: 100%">
<thead>
<tr>
<th class="sign w40" axis="col0">
<div class="tc"><input type="checkbox" class="checkAll"></div>
</th>
<th abbr="article_title" axis="col3" class="">
<div class="tl text-l10">文件名称</div>
</th>
<th abbr="article_show" axis="col5" class="w100">
<div class="tc">系统版本</div>
</th>
<th abbr="ac_id" axis="col4" class="w40">
<div class="tc">卷号</div>
</th>
<th abbr="article_show" axis="col5" class="w60">
<div class="tc">压缩</div>
</th>
<th abbr="article_time" axis="col6" class="w100">
<div class="tc">数据大小</div>
</th>
<th abbr="article_show" axis="col7" class="w160">
<div class="tc">备份时间</div>
</th>
<th axis="col1" class="w160">
<div class="tc">操作</div>
</th>
</tr>
</thead>
</table>
</div>
</div>
<div class="bDiv" style="height: auto;">
<div id="flexigrid" cellpadding="0" cellspacing="0" border="0">
<table style="width: 100%">
<tbody>
{empty name="list"}
<tr>
<td class="no-data" align="center" axis="col0" colspan="50">
<i class="fa fa-exclamation-circle"></i>没有符合条件的记录
</td>
</tr>
{else/}
{foreach name="list" item="vo" key="k" }
<tr data-id="{$vo.basename}">
<td class="sign">
<div class="w40 tc"><input type="checkbox" name="ids[]" value="{$vo.time}"></div>
</td>
<td style="width: 100%">
<div class="tl text-l10" >{$vo.basename}</div>
</td>
<td>
<div class="w100 tc">{$vo.version}</div>
</td>
<td class="">
<div class="w40 tc">{$vo.part}</div>
</td>
<td>
<div class="w60 tc">{$vo.compress}</div>
</td>
<td>
<div class="w100 tc">{$vo.size|format_bytes}</div>
</td>
<td>
<div class="w160 tc">{$vo.time|date="Y-m-d H:i:s",###}</div>
</td>
<td class="operation">
<div class="w160 tc">
{eq name="$Think.const.CONTROLLER_NAME.'@new_import'|is_check_access" value="1"}
<a href="javascript:void(0);" data-url="{:U('Tools/new_import', array('time'=>$vo['time']))}" class="btn blue db-import">恢复</a>
{/eq}
{eq name="$Think.const.CONTROLLER_NAME.'@downFile'|is_check_access" value="1"}
<i></i>
<a href="{:U('Tools/downFile',array('time'=>$vo['time']))}" class="btn green">下载</a>
{/eq}
{eq name="$Think.const.CONTROLLER_NAME.'@del'|is_check_access" value="1"}
<i></i>
<a class="btn red" href="javascript:void(0);" data-url="{:U('Tools/del')}" data-id="{$vo.time}" onClick="delfun(this);">删除</a>
{/eq}
</div>
</td>
</tr>
{/foreach}
{/empty}
</tbody>
</table>
</div>
<div class="iDiv" style="display: none;"></div>
</div>
<div class="tDiv">
<div class="tDiv2">
<div class="fbutton checkboxall">
<input type="checkbox" class="checkAll">
</div>
{eq name="$Think.const.CONTROLLER_NAME.'@del'|is_check_access" value="1"}
<div class="fbutton">
<a onclick="batch_del(this, 'ids');" data-url="{:U('Tools/del')}" class="layui-btn layui-btn-primary">
<span>批量删除</span>
</a>
</div>
{/eq}
{eq name="$Think.const.CONTROLLER_NAME.'@restoreUpload'|is_check_access" value="1"}
<div class="fbutton" style="display: none;">
<form class="navbar-form form-inline" action="{:U('Tools/restoreUpload')}" name="change_System" id="change_System" method="post" enctype="multipart/form-data">
<a href="javascript:void(0);" class="a-upload"><input type="file" name="sqlfile" id="sqlfile" title="请选择…"><i class="fa fa-upload"></i>上传执行sql文件</a>
</form>
</div>
{/eq}
<div class="fbuttonr" style="margin-right: 15px;">
<div class="total">
<h5>备份文件数量:{$filenum},占空间大小:{$total|format_bytes}</h5>
</div>
</div>
</div>
<div style="clear:both"></div>
</div>
</div>
</div>
<form class="none" name="form_tmp" id="form_tmp" action="" method="POST">
</form>
<script>
$(function(){
$('input[name*=ids]').click(function(){
if ($('input[name*=ids]').length == $('input[name*=ids]:checked').length) {
$('.checkAll').prop('checked','checked');
} else {
$('.checkAll').prop('checked', false);
}
});
$('input[type=checkbox].checkAll').click(function(){
$('input[type=checkbox]').prop('checked',this.checked);
});
});
$(document).ready(function(){
// 表格行点击选中切换
$('#flexigrid > table>tbody >tr').click(function(){
$(this).toggleClass('trSelected');
});
// 点击刷新数据
$('.fa-refresh').click(function(){
location.href = location.href;
});
$('#sqlfile').change(function(){
restoreUpload();
});
function restoreUpload()
{
var sqlfile = $('input[name=sqlfile]').val();
var ext = sqlfile.substr(sqlfile.lastIndexOf('.')).toLowerCase();
if ($.trim(sqlfile) == '' || ext != '.sql') {
showErrorMsg('请上传sql文件');
return false;
}
layer.confirm('此操作不可恢复,确认执行?', {
title: false,//'<font color="red">重要提示</font>',
btn: ['确定', '取消'] //按钮
}, function () {
layer_loading('正在处理');
$('#change_System').submit();
return false;
}, function (index) {
$('#sqlfile').val('');
layer.closeAll();
return false;
});
}
});
$(".db-import").click(function(){
var url = $(this).attr('data-url');
$('#form_tmp').attr('action', url);
layer_loading('正在处理');
$('#form_tmp').submit();
});
</script>
{include file="public/footer" /}