index.html 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. {extend name="app/shop/view/base.html" /}
  2. {block name="resources"}
  3. <style>
  4. .js-migrate-list {
  5. display: none;
  6. }
  7. .progress-bar-wrap .layui-input-block {
  8. padding-top: 11px;
  9. min-height: initial;
  10. }
  11. .progress-bar {
  12. height: 10px;
  13. background: #e8e8e8;
  14. width: 60%;
  15. border-radius: 4px;
  16. position: relative;
  17. }
  18. .progress-bar .curr {
  19. content: '';
  20. background: #FF6A00;
  21. display: block;
  22. width: 0;
  23. height: 10px;
  24. border-radius: 4px;
  25. }
  26. .progress-bar .value {
  27. position: absolute;
  28. right: -70px;
  29. top: -3px;
  30. line-height: initial;
  31. }
  32. .js-save[disabled] {
  33. background: #d2d2d2 !important;
  34. cursor: not-allowed;
  35. }
  36. .laytable-cell-1-0-3 {
  37. text-align: right;
  38. }
  39. </style>
  40. {/block}
  41. {block name="main"}
  42. <div class="layui-collapse tips-wrap">
  43. <div class="layui-colla-item">
  44. <h2 class="layui-colla-title">操作提示</h2>
  45. <ul class="layui-colla-content layui-show">
  46. <li>在迁移数据前,首先会备份原数据,SQL文件存放在upload/backup文件夹下</li>
  47. <li>迁移数据开始后,请不要关闭当前页面,以免造成未知错误</li>
  48. <li>文档参考:<a href="https://www.kancloud.cn/niucloud/niushop_b2c_v4/1852551" target="_blank" class="text-color">v3Tov4迁移数据说明文档</a>
  49. </li>
  50. </ul>
  51. </div>
  52. </div>
  53. <div class="layui-form form-wrap">
  54. <table lay-filter="migrate_list" lay-skin="line" class="js-migrate-list">
  55. <thead>
  56. <tr>
  57. <th lay-data="{checkbox:true,field:'key', width:'5%'}"></th>
  58. <th lay-data="{field:'name',width:'20%'}">迁移模块</th>
  59. <th lay-data="{field:'introduction',width:'65%'}">描述</th>
  60. <th lay-data="{field:'action',width:'10%'}" >迁移说明</th>
  61. </tr>
  62. </thead>
  63. <tbody>
  64. {foreach name="$task_class" item="vo" key="k"}
  65. {if $vo['is_show']}
  66. <tr>
  67. <td>{$k}</td>
  68. <td>{$vo['name']}</td>
  69. <td>{$vo['introduction']}</td>
  70. <td>
  71. <div class="table-btn">
  72. <a class="layui-btn js-select-desc" data-desc='{$vo["desc"]}'>详情</a>
  73. </div>
  74. </td>
  75. </tr>
  76. {/if}
  77. {/foreach}
  78. </tbody>
  79. </table>
  80. {foreach name="$task_class" item="vo" key="k"}
  81. <input type="hidden" name="migrate_data" title="{$vo['name']}" value="{$k}" lay-skin="primary">
  82. {/foreach}
  83. <div class="layui-form-item progress-bar-wrap">
  84. <label class="layui-form-label mid">迁移进度:</label>
  85. <div class="layui-input-block">
  86. <div class="progress-bar">
  87. <span class="curr"></span>
  88. <span class="value">0%</span>
  89. </div>
  90. </div>
  91. </div>
  92. <div class="form-row mid">
  93. <button class="layui-btn js-save" lay-submit lay-filter="save">迁移</button>
  94. </div>
  95. </div>
  96. {/block}
  97. {block name="script"}
  98. <script type="text/javascript">
  99. var form, table;
  100. var index = -1;// 当前页
  101. var migrate_data = [];// 已选迁移模块
  102. var total = 0;// 总页数
  103. var page_size = 0;//每页数量
  104. var last_table = "";
  105. var backup_index = 0;
  106. var series = 0;
  107. var is_backup_end = 0;// 是否备份完成
  108. var repeat_flag = false; //防重复标识
  109. layui.use(['form', 'table'], function () {
  110. form = layui.form;
  111. table = layui.table;
  112. table.init('migrate_list');
  113. table.on('checkbox(migrate_list)', function (obj) {
  114. if (obj.type == "all") {
  115. migrate_data = [];
  116. if (obj.checked) {
  117. $("input[name='migrate_data']").each(function () {
  118. migrate_data.push($(this).val());
  119. });
  120. }
  121. } else {
  122. if (obj.checked) {
  123. migrate_data.push(obj.data.key);
  124. } else {
  125. for (var i in migrate_data) {
  126. if (migrate_data[i] == obj.data.key) migrate_data.splice(i, 1);
  127. }
  128. }
  129. }
  130. });
  131. $("body").on("click", ".js-select-desc", function () {
  132. var desc = $(this).attr("data-desc");
  133. layer.open({
  134. title: '迁移说明',
  135. area: ['900px', '600px'],
  136. content: '<pre>' + desc + '</pre>'
  137. });
  138. });
  139. form.on("submit(save)", function (data) {
  140. if (!migrate_data.length) {
  141. layer.msg("请选择要迁移的数据");
  142. return false;
  143. }
  144. if (repeat_flag) return false;
  145. repeat_flag = true;
  146. checkModuleIsUpgrade(function () {
  147. execute();
  148. });
  149. })
  150. });
  151. function execute() {
  152. if (is_backup_end) {
  153. migrate();
  154. } else {
  155. $(".js-save").text("数据备份中...").attr("disabled", true);
  156. backupSql(function (res) {
  157. if (res.code >= 0) {
  158. $(".js-save").text("数据迁移中...").attr("disabled", true);
  159. migrate();
  160. }
  161. });
  162. }
  163. }
  164. /**
  165. * 迁移数据
  166. */
  167. function migrate() {
  168. $.ajax({
  169. url: ns.url("v3tov4://shop/upgrade/index"),
  170. dataType: 'JSON',
  171. type: 'POST',
  172. data: {index: index, 'class': migrate_data.toString()},
  173. success: function (res) {
  174. if (res.code >= 0) {
  175. var data = res.data;
  176. index = parseInt(data.index);
  177. total = parseInt(data.total);
  178. page_size = parseInt(data.page_size);
  179. var progress = 0;
  180. if (index > -1) {
  181. // 进度计算公式:(当前页 * 每页数量) / 总数量(每页数量 * 总页数) * 100
  182. progress = parseFloat(((index + 1) * page_size) / (page_size * total) * 100).toFixed(2);
  183. }
  184. $(".progress-bar .curr").css("width", progress + "%");
  185. $(".progress-bar .value").text(progress + "%");
  186. if ((parseInt(index) + 1) < total) {
  187. index++;
  188. execute();
  189. } else {
  190. updateLogStatus();
  191. $(".js-save").text("迁移完成").removeAttr("disabled");
  192. layer.msg("迁移完成");
  193. }
  194. } else {
  195. layer.msg(res.message);
  196. }
  197. }
  198. });
  199. }
  200. /**
  201. * 数据备份
  202. * @param callback
  203. */
  204. function backupSql(callback) {
  205. $.ajax({
  206. type: 'post',
  207. url: ns.url("v3tov4://shop/upgrade/backupSql"),
  208. dataType: 'json',
  209. data: {
  210. last_table: last_table,
  211. index: backup_index,
  212. series: series
  213. },
  214. success: function (res) {
  215. if (res.code >= 0) {
  216. var data = res.data;
  217. //判断是否备份完成
  218. if (data.is_backup_end) {
  219. is_backup_end = data.is_backup_end;
  220. if (callback) callback(res);
  221. } else {
  222. last_table = data.last_table;
  223. series = data.series;
  224. backup_index = data.index;
  225. backupSql(callback);
  226. }
  227. } else {
  228. if (callback) callback(res);
  229. is_backup_end = 0;
  230. layer.msg("备份发生错误:", res.message);
  231. }
  232. }
  233. });
  234. }
  235. /**
  236. * 获取最新的模块迁移状态,防止重复迁移
  237. * @param callback
  238. */
  239. function checkModuleIsUpgrade(callback) {
  240. $.ajax({
  241. type: 'post',
  242. url: ns.url("v3tov4://shop/upgrade/checkModuleIsUpgrade"),
  243. dataType: 'json',
  244. data: {
  245. module: migrate_data.toString()
  246. },
  247. success: function (res) {
  248. var data = res.data;
  249. var module = [];
  250. var message = '';
  251. for (var i = 0; i < data.length; i++) {
  252. if (data[i].count) {
  253. module.push(data[i].title);
  254. }
  255. }
  256. if (module.length) {
  257. message = "[ " + module.join(",") + ' ] 数据已迁移成功,确定要重新迁移吗?';
  258. var index = layer.confirm(message, {
  259. title: '操作提示',
  260. // btn: ['返回列表', '继续添加'],
  261. closeBtn: 0,
  262. yes: function () {
  263. if (callback) callback();
  264. layer.close(index);
  265. }, btn2: function () {
  266. repeat_flag = false;
  267. }
  268. })
  269. } else {
  270. if (callback) callback();
  271. }
  272. }
  273. });
  274. }
  275. /**
  276. * 更新迁移日志状态
  277. */
  278. function updateLogStatus() {
  279. $.ajax({
  280. type: 'post',
  281. url: ns.url("v3tov4://shop/upgrade/updateLogStatus"),
  282. dataType: 'json',
  283. data: {
  284. module: migrate_data.toString()
  285. },
  286. success: function (res) {
  287. }
  288. });
  289. }
  290. </script>
  291. {/block}