Database.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2021 勾股工作室
  4. * @license https://opensource.org/licenses/Apache-2.0
  5. * @link https://www.gougucms.com
  6. */
  7. declare (strict_types = 1);
  8. namespace app\admin\controller;
  9. use app\admin\BaseController;
  10. use backup\Backup;
  11. use think\facade\Session;
  12. use think\facade\Db;
  13. use think\facade\View;
  14. class Database extends BaseController
  15. {
  16. //数据表列表
  17. public function database()
  18. {
  19. if (request()->isAjax()) {
  20. // 数据信息
  21. $db = new Backup();
  22. $list = $db->dataList();
  23. // 计算总大小
  24. $total = 0;
  25. foreach ($list as $k => $v) {
  26. $total += $v['data_length'];
  27. $list[$k]['data_size'] = $v['data_length'];
  28. $list[$k]['data_length'] = format_bytes($v['data_length']);
  29. }
  30. // 提示信息
  31. $dataTips = '数据库中共有<strong> ' . count($list) . '</strong> 张表,共计 <strong>' . format_bytes($total) . '</strong>大小。';
  32. $data['data'] = $list;
  33. return table_assign(0, $dataTips, $data);
  34. }
  35. return view();
  36. }
  37. //备份数据
  38. public function backup()
  39. {
  40. $db= new Backup();
  41. if(request()->isPost()){
  42. $tables=get_params('tables');
  43. $fileinfo =$db->getFile();
  44. //检查是否有正在执行的任务
  45. $lock = "{$fileinfo['filepath']}backup.lock";
  46. if(is_file($lock)){
  47. return to_assign(2, '检测到有一个备份任务未完成');
  48. } else {
  49. //创建锁文件
  50. file_put_contents($lock,time());
  51. }
  52. // 检查备份目录是否可写
  53. if(!is_writeable($fileinfo['filepath'])){
  54. return to_assign(1, '备份目录不存在或不可写,请检查后重试!');
  55. }
  56. //缓存锁文件
  57. Session::set('lock', $lock);
  58. //缓存备份文件信息
  59. Session::set('backup_file', $fileinfo['file']);
  60. //缓存要备份的表
  61. Session::set('backup_tables', $tables);
  62. //创建备份文件
  63. if(false !== $db->Backup_Init()){
  64. return to_assign(0, '初始化成功,开始备份...',['tab'=>['id' => 0, 'start' => 0,'table'=>$tables[0]]]);
  65. }else{
  66. return to_assign(1, '初始化失败,备份文件创建失败');
  67. }
  68. }else if(request()->isGet()){
  69. $tables = Session::get('backup_tables');
  70. $file=Session::get('backup_file');
  71. $id=get_params('id');
  72. $start=get_params('start');
  73. $start= $db->setFile($file)->backup($tables[$id], $start);
  74. if(false === $start){
  75. return to_assign(1, '备份出错');
  76. }else if(0 === $start){
  77. if(isset($tables[++$id])){
  78. return to_assign(0, '备份完成',['tab'=>['id' => $id, 'start' => 0,'table'=>$tables[$id-1]]]);
  79. } else { //备份完成,清空缓存
  80. unlink(Session::get('lock'));
  81. Session::delete('backup_tables');
  82. Session::delete('backup_file');
  83. add_log('bak');
  84. return to_assign(0, '备份完成',['tab'=>['start' => 'ok','table'=>$tables[$id-1]]]);
  85. }
  86. }
  87. }else{
  88. return to_assign(1, '参数错误!');
  89. }
  90. }
  91. //优化表
  92. public function optimize($tables= null)
  93. {
  94. $db= new Backup();
  95. //return to_assign(0, $db->optimize($tables));
  96. if($db->optimize($tables)){
  97. add_log('optimize');
  98. return to_assign(0, '数据表优化完成');
  99. }else{
  100. return to_assign(1, '数据表优化出错请重试');
  101. }
  102. }
  103. //修复表
  104. public function repair($tables= null)
  105. {
  106. $db= new Backup();
  107. //return to_assign(0, $db->repair($tables));
  108. if($db->repair($tables)){
  109. add_log('repair');
  110. return to_assign(0, '数据表修复完成');
  111. }else{
  112. return to_assign(1, '数据表修复出错请重试');
  113. }
  114. }
  115. //备份文件列表
  116. public function backuplist()
  117. {
  118. $db= new Backup();
  119. $list = $db->fileList();
  120. $fileinfo =$db->getFile();
  121. $lock = "{$fileinfo['filepath']}backup.lock";
  122. $lock_time = 0;
  123. if(is_file($lock)){
  124. $lock_time = file_get_contents($lock);
  125. }
  126. $listNew = [];
  127. $indx = 0;
  128. foreach ($list as $k => $v) {
  129. $listNew[$indx]['time'] = $k;
  130. $listNew[$indx]['timespan'] = $v['time'];
  131. $listNew[$indx]['data'] = $v;
  132. $indx++;
  133. }
  134. $list = $listNew;
  135. array_multisort(array_column($list, 'time'), SORT_DESC, $list);
  136. return view('',['list'=>$list,'lock_time' => $lock_time]);
  137. }
  138. //数据还原
  139. public function import($time = 0, $part = null, $start = null)
  140. {
  141. $db= new Backup();
  142. $time =(int)$time;
  143. if(is_numeric($time) && is_null($part) && is_null($start)){
  144. $list = $db->getFile('timeverif',$time);
  145. if(is_array($list)){
  146. Session::set('backup_list', $list);
  147. return to_assign(0, '初始化完成,开始还原...',array('part' => 1, 'start' => 0,'time' => $time));
  148. }else{
  149. return to_assign(1, '备份文件可能已经损坏,请检查');
  150. }
  151. }else if(is_numeric($part) && is_numeric($start)){
  152. $list=Session::get('backup_list');
  153. $part =(int)$part;
  154. $start =(int)$start;
  155. $start= $db->setFile($list)->import($start,$time,$part);
  156. if(false===$start){
  157. return to_assign(1, '还原数据出错,请重试');
  158. }elseif(0 === $start){
  159. if(isset($list[++$part])){
  160. $data = array('part' => $part, 'start' => 0,'time' => $time);
  161. return to_assign(0, "正在还原...卷{$part},请勿关闭当前页面",$data);
  162. } else {
  163. Session::delete('backup_list');
  164. return to_assign(0, '还原数据成功');
  165. }
  166. }else{
  167. $data = array('part' => $part, 'start' => $start[0],'time' => $time);
  168. if($start[1]){
  169. $rate = floor(100 * ($start[0] / $start[1]));
  170. return to_assign(0, "正在还原...卷{$part} ({$rate}%),请勿关闭当前页面",$data);
  171. } else {
  172. $data['gz'] = 1;
  173. return to_assign(0, "正在还原...卷{$part},请勿关闭当前页面",$data);
  174. }
  175. return to_assign(0, "正在还原...卷{$part},请勿关闭当前页面");
  176. }
  177. }else{
  178. return to_assign(1, "参数错误");
  179. }
  180. }
  181. /**
  182. * 删除备份文件
  183. */
  184. public function del($time = 0,$lock=0){
  185. $db= new Backup();
  186. if($lock==1){
  187. $fileinfo =$db->getFile();
  188. $lock = "{$fileinfo['filepath']}backup.lock";
  189. if(is_file($lock)){
  190. $time = file_get_contents($lock);
  191. unlink($lock);
  192. }
  193. }
  194. if($db->delFile((int)$time)){
  195. add_log('delete');
  196. return to_assign(0, '删除成功');
  197. }else{
  198. return to_assign(0, '删除失败,请检查权限');
  199. }
  200. }
  201. /**
  202. * 下载备份文件
  203. */
  204. public function downfile($time = 0,$part=0){
  205. $db= new Backup();
  206. add_log('down');
  207. $db->downloadFile((int)$time,$part-1);
  208. }
  209. }