Upgrade.php 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. <?php
  2. /**
  3. * Niushop商城系统 - 团队十年电商经验汇集巨献!
  4. * =========================================================
  5. * Copy right 2019-2029 杭州牛之云科技有限公司, 保留所有权利。
  6. * ----------------------------------------------
  7. * 官方网址: https://www.niushop.com
  8. * =========================================================
  9. */
  10. namespace addon\v3tov4\shop\controller;
  11. use addon\v3tov4\model\Log;
  12. use app\model\system\Database;
  13. use app\shop\controller\BaseShop;
  14. use addon\v3tov4\model\Upgrade as UpgradeModel;
  15. use addon\v3tov4\model\Log as LogModel;
  16. use think\facade\Cache;
  17. /**
  18. * 升级
  19. * @author Administrator
  20. *
  21. */
  22. class Upgrade extends BaseShop
  23. {
  24. protected $replace = []; //视图输出字符串内容替换 相当于配置文件中的'view_replace_str'
  25. /**
  26. * 数据迁移
  27. */
  28. public function index()
  29. {
  30. $log = new LogModel();
  31. $upgrade = new UpgradeModel();
  32. $task_class = $upgrade->getTaskClass();
  33. if (request()->isAjax()) {
  34. $index = input('index', -1);
  35. $class = input('class', '');
  36. if ($index == -1) {
  37. // 添加迁移日志
  38. $class_array = explode(',', $class);
  39. $log_data = [];
  40. foreach ($class_array as $k => $v) {
  41. if ($task_class[ $v ][ 'is_show' ]) {
  42. $log_data[] = [
  43. 'module' => $v,
  44. 'title' => $task_class[ $v ][ 'name' ],
  45. 'remark' => $task_class[ $v ][ 'introduction' ],
  46. 'create_time' => time()
  47. ];
  48. }
  49. }
  50. $log->addLogList($log_data);
  51. $task_list = $upgrade->getSyncTask($class);
  52. if (empty($task_list[ 'code' ])) {
  53. Cache::set('upgrade_error_task', '');
  54. }
  55. Cache::set('upgrade_task', $task_list);
  56. } else {
  57. $task_list = Cache::get('upgrade_task');
  58. $run_res = $upgrade->run($task_list[ $index ]);
  59. if ($run_res[ 'code' ] < 0) {
  60. $task_error_list = Cache::get('upgrade_error_task');
  61. if (empty($task_error_list)) {
  62. $task_error_list = [
  63. 'data' => $task_list[ $index ],
  64. 'error' => $run_res[ 'message' ]
  65. ];
  66. } else {
  67. array_push($task_error_list, [ 'data' => $task_list[ $index ], 'error' => $run_res[ 'message' ] ]);
  68. }
  69. Cache::set('upgrade_error_task', $task_error_list);
  70. }
  71. }
  72. $task_error_list = Cache::get('upgrade_error_task');
  73. if (!empty($task_list[ 'code' ])) {
  74. return error(-1, $task_list[ 'message' ]);
  75. } elseif (!empty($task_error_list)) {
  76. $count = 0;
  77. foreach ($task_error_list as $k => $v) {
  78. if (!empty($v[ 'error' ])) {
  79. return error(-1, $v[ 'error' ]);
  80. } else {
  81. $count++;
  82. }
  83. }
  84. if ($count == count($task_error_list)) {
  85. return success(0, '', [ 'index' => $index, 'total' => count($task_list), 'page_size' => $upgrade->getPageSize() ]);
  86. }
  87. } else {
  88. return success(0, '', [ 'index' => $index, 'total' => count($task_list), 'page_size' => $upgrade->getPageSize() ]);
  89. }
  90. } else {
  91. $this->assign('task_class', $task_class);
  92. return $this->fetch("upgrade/index");
  93. }
  94. }
  95. /**
  96. * 备份数据库
  97. */
  98. public function backupSql()
  99. {
  100. if (request()->isAjax()) {
  101. try {
  102. $upgrade_no = date('YmdHi');
  103. $database = new Database();
  104. ini_set('memory_limit', '500M');
  105. $size = 300;
  106. $volumn = 1024 * 1024 * 2;
  107. $dump = '';
  108. $last_table = input('last_table', '');
  109. $series = max(1, input('series', 1));
  110. if (empty($last_table)) {
  111. $catch = true;
  112. } else {
  113. $catch = false;
  114. }
  115. $back_sql_root = "upload/backup/{$upgrade_no}/sql";
  116. if (!is_dir($back_sql_root)) {
  117. dir_mkdir($back_sql_root);
  118. }
  119. $tables = $database->getDatabaseList();
  120. if (empty($tables)) {
  121. return success();
  122. }
  123. foreach ($tables as $table) {
  124. $table = array_shift($table);
  125. if (!empty($last_table) && $table == $last_table) {
  126. $catch = true;
  127. }
  128. if (!$catch) {
  129. continue;
  130. }
  131. if (!empty($dump)) {
  132. $dump .= "\n\n";
  133. }
  134. if ($table != $last_table) {
  135. $row = $database->getTableSchemas($table);
  136. $dump .= $row;
  137. }
  138. $index = 0;
  139. if (!empty(input('index'))) {
  140. $index = input('index');
  141. }
  142. //枚举所有表的INSERT语句
  143. while (true) {
  144. $start = $index * $size;
  145. $result = $database->getTableInsertSql($table, $start, $size);
  146. if (!empty($result)) {
  147. $dump .= $result[ 'data' ];
  148. if (strlen($dump) > $volumn) {
  149. $bakfile = "{$back_sql_root}/backup-{$series}.sql";
  150. $dump .= "\n\n";
  151. file_put_contents($bakfile, $dump);
  152. ++$series;
  153. ++$index;
  154. $current = array (
  155. 'is_backup_end' => 0,
  156. 'last_table' => $table,
  157. 'index' => $index,
  158. 'series' => $series,
  159. );
  160. $current_series = $series - 1;
  161. return success(0, '正在导出数据, 请不要关闭浏览器, 当前第 ' . $current_series . ' 卷.', $current);
  162. }
  163. }
  164. if (empty($result) || count($result[ 'result' ]) < $size) {
  165. break;
  166. }
  167. ++$index;
  168. }
  169. }
  170. $back_file = "{$back_sql_root}/backup-{$series}.sql";
  171. $dump .= "\n\n----MySQL Dump End";
  172. file_put_contents($back_file, $dump);
  173. return success(0, '数据库备份完成', [ 'is_backup_end' => 1 ]);
  174. } catch (\Exception $e) {
  175. return error(-1, $e->getMessage());
  176. }
  177. }
  178. }
  179. /**
  180. * 获取最新的模块迁移状态,防止重复迁移
  181. * @return array
  182. */
  183. public function checkModuleIsUpgrade()
  184. {
  185. if (request()->isAjax()) {
  186. $log = new LogModel();
  187. $upgrade = new UpgradeModel();
  188. $task_class = $upgrade->getTaskClass();
  189. $module = input('module', '');
  190. if (!empty($module)) {
  191. $module_arr = explode(",", $module);
  192. $res = [];
  193. foreach ($module_arr as $k => $v) {
  194. if ($task_class[ $v ][ 'is_show' ]) {
  195. $item = $log->getLogFirstData($v, 1);
  196. $res[] = [
  197. 'module' => $v,
  198. 'title' => $task_class[ $v ][ 'name' ],
  199. 'count' => (int) ( $item[ 'data' ] )
  200. ];
  201. }
  202. }
  203. return success(0, '', $res);
  204. }
  205. }
  206. }
  207. /**
  208. * 更新迁移日志状态
  209. * @return array
  210. */
  211. public function updateLogStatus()
  212. {
  213. if (request()->isAjax()) {
  214. $log = new LogModel();
  215. $upgrade = new UpgradeModel();
  216. $task_class = $upgrade->getTaskClass();
  217. $module = input('module', '');
  218. if (!empty($module)) {
  219. $module_arr = explode(",", $module);
  220. $res = success(0, '', 0);
  221. foreach ($module_arr as $k => $v) {
  222. if ($task_class[ $v ][ 'is_show' ]) {
  223. $log_info = $log->getLogFirstData($v, 0);
  224. $log_info = $log_info[ 'data' ];
  225. if (!empty($log_info)) {
  226. $edit_res = $log->editLog([ 'status' => 1 ], [ [ 'id', '=', $log_info[ 'id' ] ] ]);
  227. $res[ 'data' ] = $edit_res[ 'data' ];
  228. }
  229. }
  230. }
  231. return $res;
  232. }
  233. }
  234. }
  235. public function log()
  236. {
  237. if (request()->isAjax()) {
  238. $log = new LogModel();
  239. $page = input('page', 1);
  240. $page_size = input('page_size', PAGE_LIST_ROWS);
  241. $condition = [];
  242. $list = $log->getLogPageList($condition, $page, $page_size);
  243. return $list;
  244. } else {
  245. return $this->fetch("upgrade/log");
  246. }
  247. }
  248. public function deleteLog()
  249. {
  250. if (request()->isAjax()) {
  251. $ids = input('ids', '');
  252. if (!empty($ids)) {
  253. $log = new LogModel();
  254. $res = $log->deleteLog($ids);
  255. return $res;
  256. }
  257. }
  258. }
  259. }