SystemDatabackup.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. <?php
  2. namespace app\admin\controller\system;
  3. use app\admin\controller\AuthController;
  4. use crmeb\services\JsonService as Json;
  5. use \crmeb\services\MysqlBackupService as Backup;
  6. use think\facade\Config;
  7. use think\facade\Session;
  8. use think\facade\Db;
  9. /**
  10. * 文件校验控制器
  11. * Class SystemDatabackup
  12. * @package app\admin\controller\system
  13. *
  14. */
  15. class SystemDatabackup extends AuthController
  16. {
  17. /**
  18. * @var Backup
  19. */
  20. protected $DB;
  21. public function initialize()
  22. {
  23. parent::initialize();
  24. $config = array(
  25. //数据库备份卷大小
  26. 'compress' => 1,
  27. //数据库备份文件是否启用压缩 0不压缩 1 压缩
  28. 'level' => 5,
  29. );
  30. $this->DB = new Backup($config);
  31. }
  32. /**
  33. * 数据类表列表
  34. */
  35. public function index()
  36. {
  37. return $this->fetch();
  38. }
  39. /**
  40. * 获取数据库表
  41. */
  42. public function tablelist()
  43. {
  44. $db = $this->DB;
  45. return Json::result(0, 'sucess', $db->dataList(), count($db->dataList()));
  46. }
  47. /**
  48. * 查看表结构
  49. */
  50. public function seetable()
  51. {
  52. request()->filter(['strip_tags', 'trim', 'htmlspecialchars']);
  53. $database = Config::get("database.connections." . Config::get('database.default') . '.database');
  54. $tablename = request()->param('tablename');
  55. $res = Db::query("select * from information_schema.columns where table_name = '" . $tablename . "' and table_schema = '" . $database . "'");
  56. $html = '';
  57. $html .= '<table border="1" cellspacing="0" cellpadding="0" align="center">';
  58. $html .= '<tbody><tr><th>字段名</th><th>数据类型</th><th>默认值</th><th>允许非空</th><th>自动递增</th><th>备注</th></tr>';
  59. $html .= '';
  60. foreach ($res AS $f) {
  61. $html .= '<td class="c1">' . $f['COLUMN_NAME'] . '</td>';
  62. $html .= '<td class="c2">' . $f['COLUMN_TYPE'] . '</td>';
  63. $html .= '<td class="c3">' . $f['COLUMN_DEFAULT'] . '</td>';
  64. $html .= '<td class="c4">' . $f['IS_NULLABLE'] . '</td>';
  65. $html .= '<td class="c5">' . ($f['EXTRA'] == 'auto_increment' ? '是' : ' ') . '</td>';
  66. $html .= '<td class="c6">' . $f['COLUMN_COMMENT'] . '</td>';
  67. $html .= '</tr>';
  68. }
  69. $html .= '</tbody></table></p>';
  70. $html .= '<p style="text-align:left;margin:20px auto;">总共:' . count($res) . '个字段</p>';
  71. $html .= '</body></html>';
  72. echo '<style>
  73. body,td,th {font-family:"宋体"; font-size:12px;}
  74. table,h1,p{width:960px;margin:0px auto;}
  75. table{border-collapse:collapse;border:1px solid #CCC;background:#efefef;}
  76. table caption{text-align:left; background-color:#fff; line-height:2em; font-size:14px; font-weight:bold; }
  77. table th{text-align:left; font-weight:bold;height:26px; line-height:26px; font-size:12px; border:1px solid #CCC;padding-left:5px;}
  78. table td{height:20px; font-size:12px; border:1px solid #CCC;background-color:#fff;padding-left:5px;}
  79. .c1{ width: 150px;}
  80. .c2{ width: 150px;}
  81. .c3{ width: 80px;}
  82. .c4{ width: 100px;}
  83. .c5{ width: 100px;}
  84. .c6{ width: 300px;}
  85. </style>';
  86. echo $html;
  87. }
  88. /**
  89. * 优化表
  90. */
  91. public function optimize()
  92. {
  93. $tables = request()->post('tables/a');
  94. $db = $this->DB;
  95. try {
  96. $db->optimize($tables);
  97. return Json::successful('优化成功');
  98. } catch (\Exception $e) {
  99. return Json::fail($e->getMessage());
  100. }
  101. }
  102. /**
  103. * 修复表
  104. */
  105. public function repair()
  106. {
  107. $tables = request()->post('tables/a');
  108. $db = $this->DB;
  109. try {
  110. $db->repair($tables);
  111. return Json::successful('修复成功');
  112. } catch (\Exception $e) {
  113. return Json::fail($e->getMessage());
  114. }
  115. }
  116. /**
  117. * 备份表
  118. */
  119. public function backup()
  120. {
  121. $tables = request()->post('tables/a');
  122. $db = $this->DB;
  123. $data = '';
  124. foreach ($tables as $t) {
  125. $res = $db->backup($t, 0);
  126. if ($res == false && $res != 0) {
  127. $data .= $t . '|';
  128. }
  129. }
  130. return Json::successful($data ? '备份失败' . $data : '备份成功');
  131. }
  132. /**
  133. * 获取备份记录表
  134. */
  135. public function fileList()
  136. {
  137. $db = $this->DB;
  138. $files = $db->fileList();
  139. $data = [];
  140. foreach ($files as $key => $t) {
  141. $data[$key]['filename'] = $t['filename'];
  142. $data[$key]['part'] = $t['part'];
  143. $data[$key]['size'] = $t['size'] . 'B';
  144. $data[$key]['compress'] = $t['compress'];
  145. $data[$key]['backtime'] = $key;
  146. $data[$key]['time'] = $t['time'];
  147. }
  148. krsort($data);//根据时间降序
  149. return Json::result(0, 'sucess', $data, count($data));
  150. }
  151. /**
  152. * @param string|null $msg
  153. * @param string|null $url
  154. * @param array|null $data
  155. */
  156. public function success(?string $msg = null, ?string $url = null, ?array $data = [])
  157. {
  158. return Json::success($msg, $data);
  159. }
  160. /**
  161. * @param string|null $msg
  162. */
  163. public function error(?string $msg = null)
  164. {
  165. return Json::fail($msg);
  166. }
  167. /**
  168. * 删除备份记录表
  169. */
  170. public function delFile()
  171. {
  172. $feilname = intval(request()->post('feilname'));
  173. $files = $this->DB->delFile($feilname);
  174. return Json::result(0, 'sucess');
  175. }
  176. /**
  177. * 导入备份记录表
  178. */
  179. public function import()
  180. {
  181. $part = request()->post('part') != '' ? intval(request()->post('part')) : null;
  182. $start = request()->post('start') != '' ? intval(request()->post('start')) : null;
  183. $time = intval(request()->post('time'));
  184. $db = $this->DB;
  185. if (is_numeric($time) && is_null($part) && is_null($start)) {
  186. $list = $db->getFile('timeverif', $time);
  187. if (is_array($list)) {
  188. session::set('backup_list', $list);
  189. $this->success('初始化完成!', '', array('part' => 1, 'start' => 0));
  190. } else {
  191. $this->error('备份文件可能已经损坏,请检查!');
  192. }
  193. } else if (is_numeric($part) && is_numeric($start)) {
  194. $list = session::get('backup_list');
  195. $start = $db->setFile($list)->import($start);
  196. if (false === $start) {
  197. $this->error('还原数据出错!');
  198. } elseif (0 === $start) {
  199. if (isset($list[++$part])) {
  200. $data = array('part' => $part, 'start' => 0);
  201. $this->success("正在还原...#{$part}", '', $data);
  202. } else {
  203. session::delete('backup_list');
  204. $this->success('还原完成!');
  205. }
  206. } else {
  207. $data = array('part' => $part, 'start' => $start[0]);
  208. if ($start[1]) {
  209. $rate = floor(100 * ($start[0] / $start[1]));
  210. $this->success("正在还原...#{$part}({$rate}%)", '', $data);
  211. } else {
  212. $data['gz'] = 1;
  213. $this->success("正在还原...#{$part}", '', $data);
  214. }
  215. $this->success("正在还原...#{$part}", '');
  216. }
  217. } else {
  218. $this->error('参数错误!');
  219. }
  220. }
  221. /**
  222. * 下载备份记录表
  223. */
  224. public function downloadFile()
  225. {
  226. $time = intval(request()->param('feilname'));
  227. $this->DB->downloadFile($time);
  228. }
  229. }