addon.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. define(['jquery', 'backend', 'table', 'form', 'layui', 'upload'], function($, Backend, Table, Form, layui, Upload) {
  2. var table = layui.table;
  3. var Controller = {
  4. index: function() {
  5. Table.init = {
  6. table_elem: '#currentTable',
  7. table_render_id: 'currentTable',
  8. layFilter: 'currentTable_LayFilter',
  9. };
  10. var area = Yzn.config.openArea != undefined ? Yzn.config.openArea : [$(window).width() > 800 ? '800px' : '95%', $(window).height() > 600 ? '600px' : '95%'];
  11. var switch_local = function() {
  12. Layer.confirm('插件市场暂不可用,是否切换到本地插件?', {
  13. title: '温馨提示',
  14. btn: ['切换到本地插件', '重新尝试加载']
  15. }, function(index) {
  16. Layer.close(index);
  17. $(".btn-switch[data-type='local']")[0].click();
  18. }, function(index) {
  19. Layer.close(index);
  20. table.reload(Table.init.table_render_id);
  21. });
  22. return false;
  23. };
  24. var button_online = Config.addon.type == 'online' ? "layui-btn-normal" : "layui-btn-primary layui-border-blue";
  25. var button_local = Config.addon.type == 'local' ? "layui-btn-normal" : "layui-btn-primary layui-border-blue";
  26. Table.render({
  27. init: Table.init,
  28. toolbar: ['refresh',
  29. {
  30. text: '本地安装',
  31. url:"",
  32. icon: 'iconfont icon-upload-fill',
  33. class: 'layui-btn layui-btn-sm faupload',
  34. extend: 'id="faupload-addon" data-type="file" data-url="addon/local" data-chunking="false" data-mimetype="zip" data-multiple="false"',
  35. },{
  36. text: '全部',
  37. url:"addon/index",
  38. icon: 'iconfont icon-list-unordered',
  39. class: 'layui-btn layui-btn-sm btn-switch ' + button_online,
  40. extend: 'data-type="all" style="margin-left: 10px !important;"',
  41. },{
  42. text: '本地插件',
  43. url:"addon/index?type=local",
  44. icon: 'iconfont icon-apps-line',
  45. class: 'layui-btn layui-btn-sm btn-switch ' + button_local,
  46. extend: 'data-type="local"',
  47. },{
  48. text: '会员信息',
  49. icon: 'iconfont icon-user-line',
  50. class: 'layui-btn layui-bg-black layui-btn-sm btn-userinfo',
  51. extend: 'style="margin-left: 10px !important;"',
  52. },
  53. ],
  54. url: 'addon/index' + (Config.addon.type == "local" ? "?type=local" : ""),
  55. css: '.layui-table-tool-temp{padding-right: 85px;}',
  56. showSearch: false,
  57. cols: [
  58. [
  59. { field: 'title', width: 200, title: '名称', templet: '#titleTpl' },
  60. { field: 'name', width: 150, title: '标识' },
  61. { field: 'description', minWidth:250, title: '描述' },
  62. { field: 'author', width: 100, title: '作者' },
  63. {
  64. field: 'price',
  65. width: 95,
  66. title: '价格',
  67. hide: (Config.addon.type == "local" ? true : false),
  68. templet: function(d) {
  69. if (isNaN(d.price)) {
  70. return d.price;
  71. }
  72. return parseFloat(d.price) == 0 ? '<span class="text-success">' + '免费' + '</span>' : '<span class="text-danger">¥' + d.price + '</span>';
  73. }
  74. },
  75. { field: 'downloads', width: 90, title: '下载', hide: (Config.addon.type == "local" ? true : false) },
  76. {
  77. field: 'version',
  78. width: 80,
  79. title: '版本',
  80. templet: function(d) {
  81. return d.addon && d.addon.version != d.version ? '<a href="javascript:;"><span class="releasetips text-primary" lay-tips="发现新版本:' + d.version + '">' + d.addon.version + '<i></i></span></a>' : d.version;
  82. }
  83. },
  84. { field: 'status', width: 90, title: '状态', templet: '#statusTpl' },
  85. { fixed: 'right', width: 180, title: '操作', templet: '#operateTpl' }
  86. ]
  87. ],
  88. page: { limit: 20 },
  89. before() {
  90. let userinfo = Yzn.cache.get('yzncms_userinfo');
  91. this.where.uid = userinfo ? userinfo.id : '';
  92. this.where.token = userinfo ? userinfo.token : '';
  93. this.where.category_id = $('input[name="category_id"]').val();
  94. },
  95. done: function(res, curr, count) {
  96. if (res && typeof res.category != 'undefined' && $(".nav-category li").length == 1) {
  97. $.each(res.category, function(i, j) {
  98. $("<li data-id='" + j.id + "'>" + j.title + "</li>").insertAfter($(".nav-category li:first"));
  99. });
  100. }
  101. if (count == -1) {
  102. switch_local();
  103. }
  104. $("#faupload-addon").data("params", function (files, xhr) {
  105. return {
  106. force: (files[0].force || false) ? 1 : 0
  107. };
  108. })
  109. Upload.api.upload("#faupload-addon", function(data, ret) {
  110. //上传完毕回调
  111. var addon = data.addon;
  112. var testdata = data.addon.testdata;
  113. operate(addon.name, 'enable', false, function(data, ret) {
  114. Layer.alert('安装成功!清除浏览器缓存和框架缓存后生效!' + (testdata ? '<br>你还可以继续导入测试数据!' : ""), {
  115. btn: testdata ? ['导入测试数据', '暂不导入'] : ['确定'],
  116. title: '温馨提示',
  117. yes: function(index) {
  118. if (testdata) {
  119. Yzn.api.ajax({
  120. url: 'addon/testdata',
  121. data: {
  122. name: addon.name,
  123. }
  124. }, function(data, res) {
  125. Layer.close(index);
  126. });
  127. } else {
  128. Layer.close(index);
  129. }
  130. },
  131. icon: 1
  132. });
  133. });
  134. return false;
  135. }, function(data, ret, up, file) {
  136. if (ret.msg && ret.msg.match(/(login|登录)/g)) {
  137. return Layer.alert(ret.msg, {
  138. title: '温馨提示',
  139. btn: ['立即登录'],
  140. yes: function(index, layero) {
  141. $(".btn-userinfo").trigger("click");
  142. }
  143. });
  144. } else if (ret.code === -1) {
  145. Layer.confirm('确认升级<b>《' + data.title + '》</b>?<p class="text-danger">1、请务必做好代码和数据库备份!备份!备份!<br>2、升级后如出现冗余数据,请根据需要移除即可!<br>3、不建议在生产环境升级,请在本地完成升级测试</p>如有重要数据请备份后再操作!', { title: '温馨提示' },
  146. function(index, layero) {
  147. up.removeFile(file);
  148. file.force = true;
  149. up.uploadFile(file);
  150. Layer.close(index);
  151. });
  152. return false;
  153. } else if (ret && ret.code === -3) {
  154. //插件目录发现影响全局的文件
  155. Layer.open({
  156. content: layui.laytpl($("#conflicttpl").html()).render({ list: ret.data }),
  157. shade: 0.8,
  158. area: area,
  159. title: '温馨提示',
  160. btn: ['继续操作', '取消'],
  161. end: function() {
  162. },
  163. yes: function() {
  164. up.removeFile(file);
  165. file.force = true;
  166. up.uploadFile(file);
  167. Layer.close(index);
  168. }
  169. });
  170. } else {
  171. Layer.alert(ret.msg, { title: '温馨提示', icon: 0 });
  172. }
  173. })
  174. }
  175. });
  176. Table.api.bindevent();
  177. // 检测是否登录
  178. $(document).on("mousedown", "#faupload-addon", function(e) {
  179. if (!isLogin()) return
  180. });
  181. table.on('tool(' + Table.init.layFilter + ')', function(obj) {
  182. var that = this;
  183. jsondata = $(this).data('value');
  184. var name = $(this).data("name");
  185. var title = $(this).data("title");
  186. const arr = jsondata.map(({ id, version }) => ({ id, title: version }))
  187. layui.dropdown.render({
  188. elem: that,
  189. show: true, // 外部事件触发即显示
  190. data: arr,
  191. click: function(data, othis) {
  192. if (!isLogin()) return
  193. if (obj.event === 'install') {
  194. Layer.confirm(title, function(index) {
  195. install(name, data.title, false);
  196. });
  197. }
  198. if (obj.event === 'upgrade') {
  199. Layer.confirm('确认升级<b>《' + title + '》</b>?<p class="text-danger">1、请务必做好代码和数据库备份!备份!备份!<br>2、升级后如出现冗余数据,请根据需要移除即可!<br>3、不建议在生产环境升级,请在本地完成升级测试</p>如有重要数据请备份后再操作!', function(index, layero) {
  200. upgrade(name, data.title);
  201. });
  202. }
  203. }
  204. })
  205. })
  206. layui.tabs.on(`afterChange(tabswitch)`, function(data) {
  207. var value = $(this).data("id");
  208. $('input[name="category_id"]').val(value);
  209. table.reload(Table.init.table_render_id,{
  210. page: {
  211. curr: 1 // 重置到第一页
  212. }
  213. });
  214. })
  215. // 会员信息
  216. $(document).on("click", ".btn-userinfo", function(e, name, version) {
  217. var that = this;
  218. var area = [$(window).width() > 800 ? '500px' : '95%', $(window).height() > 600 ? '400px' : '95%'];
  219. var userinfo = Yzn.cache.get('yzncms_userinfo');
  220. if (!userinfo) {
  221. Layer.open({
  222. content: layui.laytpl($("#logintpl").html()).render({}),
  223. zIndex: 99,
  224. area: area,
  225. title: '登录',
  226. resize: false,
  227. btn: ['登录', '注册'],
  228. yes: function(index, layero) {
  229. Yzn.api.ajax({
  230. url: Config.addon.api_url + '/user/login',
  231. type: 'post',
  232. data: {
  233. account: $("#inputAccount", layero).val(),
  234. password: $("#inputPassword", layero).val(),
  235. }
  236. }, function(data, ret) {
  237. Yzn.cache.set('yzncms_userinfo', data.userinfo);
  238. Layer.closeAll();
  239. Layer.alert(ret.msg, { title: '温馨提示', icon: 1 });
  240. return false;
  241. }, function(data, ret) {
  242. });
  243. },
  244. btn2: function() {
  245. return false;
  246. },
  247. success: function(layero, index) {
  248. this.checkEnterKey = function(event) {
  249. if (event.keyCode === 13) {
  250. $(".layui-layer-btn0").trigger("click");
  251. return false;
  252. }
  253. };
  254. $(document).on('keydown', this.checkEnterKey);
  255. $(".layui-layer-btn1", layero).prop("href", "https://www.yzncms.com/index/user/register.html").prop("target", "_blank");
  256. },
  257. end: function() {
  258. $(document).off('keydown', this.checkEnterKey);
  259. }
  260. });
  261. } else {
  262. Yzn.api.ajax({
  263. url: Config.addon.api_url + '/user/index',
  264. data: {
  265. uid: userinfo.id,
  266. token: userinfo.token,
  267. }
  268. }, function(data) {
  269. Layer.open({
  270. content: layui.laytpl($("#userinfotpl").html()).render(userinfo),
  271. area: area,
  272. title: '会员信息',
  273. resize: false,
  274. btn: ['退出登录', '关闭'],
  275. yes: function() {
  276. Yzn.api.ajax({
  277. url: Config.addon.api_url + '/user/logout',
  278. data: { uid: userinfo.id, token: userinfo.token }
  279. }, function(data, ret) {
  280. Yzn.cache.delete('yzncms_userinfo');
  281. Layer.closeAll();
  282. Layer.alert(ret.msg, { title: '温馨提示', icon: 0 });
  283. }, function(data, ret) {
  284. Yzn.cache.delete('yzncms_userinfo');
  285. Layer.closeAll();
  286. Layer.alert(ret.msg, { title: '温馨提示', icon: 0 });
  287. });
  288. }
  289. });
  290. return false;
  291. }, function(data) {
  292. Yzn.cache.delete('yzncms_userinfo');
  293. $(that).trigger('click');
  294. return false;
  295. });
  296. }
  297. });
  298. var install = function(name, version, force) {
  299. var userinfo = Yzn.cache.get('yzncms_userinfo');
  300. var uid = userinfo ? userinfo.id : 0;
  301. var token = userinfo ? userinfo.token : '';
  302. Yzn.api.ajax({
  303. url: 'addon/install',
  304. data: {
  305. name: name,
  306. force: force ? 1 : 0,
  307. uid: uid,
  308. token: token,
  309. version: version
  310. },
  311. }, function(data, res) {
  312. Layer.closeAll();
  313. Layer.alert('安装成功!清除浏览器缓存和框架缓存后生效!' + (data.addon.testdata ? '<br>你还可以继续导入测试数据!' : ""), {
  314. btn: data.addon.testdata ? ['导入测试数据', '暂不导入'] : ['确定'],
  315. title: '温馨提示',
  316. yes: function(index) {
  317. if (data.addon.testdata) {
  318. Yzn.api.ajax({
  319. url: 'addon/testdata',
  320. data: {
  321. name: name,
  322. }
  323. }, function(data, res) {
  324. Layer.close(index);
  325. });
  326. } else {
  327. Layer.close(index);
  328. }
  329. },
  330. icon: 1
  331. });
  332. Controller.api.refresh();
  333. }, function(data, res) {
  334. var area = [$(window).width() > 650 ? '650px' : '95%', $(window).height() > 710 ? '710px' : '95%'];
  335. if (res && res.code === -2) {
  336. Layer.closeAll();
  337. top.Yzn.api.open(res.data.payurl,'立即支付',{
  338. area: area,
  339. end: function() {
  340. Yzn.api.ajax({
  341. url: 'addon/isbuy',
  342. data: {
  343. name: name,
  344. force: force ? 1 : 0,
  345. uid: uid,
  346. token: token,
  347. version: version
  348. }
  349. }, function() {
  350. top.Layer.alert('购买成功!请点击继续安装按钮完成安装!', {
  351. btn: ['继续安装'],
  352. title: '温馨提示',
  353. icon: 1,
  354. yes: function(index) {
  355. top.Layer.close(index);
  356. install(name, version);
  357. }
  358. });
  359. return false;
  360. }, function() {
  361. console.log('已取消');
  362. return false;
  363. });
  364. }
  365. });
  366. } else if (res && res.code === -3) {
  367. //插件目录发现影响全局的文件
  368. Layer.open({
  369. content: layui.laytpl($("#conflicttpl").html()).render({ list: res.data }),
  370. shade: 0.8,
  371. area: area,
  372. title: '温馨提示',
  373. btn: ['继续操作', '取消'],
  374. end: function() {
  375. },
  376. yes: function() {
  377. install(name, version, true);
  378. }
  379. });
  380. } else if (res && res.code === 401) {
  381. Yzn.cache.delete('yzncms_userinfo');
  382. Layer.alert('登录已经失效,请重新登录后操作!', {
  383. title: '温馨提示',
  384. btn: ['立即登录'],
  385. yes: function(index, layero) {
  386. $(".btn-userinfo").trigger("click");
  387. },
  388. });
  389. } else {
  390. Layer.alert(res.msg, { title: '温馨提示', icon: 0 });
  391. }
  392. return false;
  393. })
  394. }
  395. var uninstall = function(name, force, droptables) {
  396. Yzn.api.ajax({
  397. url: 'addon/uninstall',
  398. data: { name: name, force: force ? 1 : 0, droptables: droptables ? 1 : 0 }
  399. }, function(data, res) {
  400. Layer.closeAll();
  401. Controller.api.refresh();
  402. }, function(data, res) {
  403. if (res && res.code === -3) {
  404. //插件目录发现影响全局的文件
  405. Layer.open({
  406. content: layui.laytpl($("#conflicttpl").html()).render({ list: res.data }),
  407. shade: 0.8,
  408. area: area,
  409. title: '温馨提示',
  410. btn: ['继续操作', '取消'],
  411. end: function() {
  412. },
  413. yes: function() {
  414. uninstall(name, true, droptables);
  415. }
  416. });
  417. } else {
  418. Layer.alert(res.msg, { title: '温馨提示', icon: 0 });
  419. }
  420. return false;
  421. });
  422. };
  423. // 点击升级
  424. $(document).on("click", ".btn-upgrade", function() {
  425. var name = $(this).data('name');
  426. var version = $(this).data("version");
  427. var title = $(this).data("title");
  428. if (!isLogin()) return
  429. Layer.confirm('确认升级<b>《' + title + '》</b>?<p class="text-danger">1、请务必做好代码和数据库备份!备份!备份!<br>2、升级后如出现冗余数据,请根据需要移除即可!<br>3、不建议在生产环境升级,请在本地完成升级测试</p>如有重要数据请备份后再操作!', function(index, layero) {
  430. upgrade(name, version);
  431. });
  432. });
  433. var upgrade = function(name, version) {
  434. var userinfo = Yzn.cache.get('yzncms_userinfo');
  435. var uid = userinfo ? userinfo.id : 0;
  436. var token = userinfo ? userinfo.token : '';
  437. Yzn.api.ajax({
  438. url: 'addon/upgrade',
  439. data: {
  440. name: name,
  441. uid: uid,
  442. token: token,
  443. version: version
  444. }
  445. }, function(data, ret) {
  446. Controller.api.refresh();
  447. Layer.closeAll();
  448. }, function(data, ret) {
  449. Layer.alert(ret.msg, { title: '温馨提示' });
  450. return false;
  451. });
  452. };
  453. var operate = function(name, action, force, success, error) {
  454. Yzn.api.ajax({
  455. url: 'addon/state',
  456. data: { name: name, action: action, force: force ? 1 : 0 }
  457. }, function(data, res) {
  458. Layer.closeAll();
  459. if (typeof success === 'function') {
  460. success(res);
  461. }
  462. Controller.api.refresh();
  463. return false;
  464. }, function(data, res) {
  465. if (typeof error === "function") {
  466. error(res);
  467. }
  468. if (res && res.code === -3) {
  469. //插件目录发现影响全局的文件
  470. Layer.open({
  471. content: layui.laytpl($("#conflicttpl").html()).render({ list: res.data }),
  472. shade: 0.8,
  473. area: area,
  474. title: '温馨提示',
  475. btn: ['继续操作', '取消'],
  476. end: function() {
  477. },
  478. yes: function() {
  479. operate(name, action, true, success);
  480. }
  481. });
  482. } else {
  483. Layer.alert(res.msg, { title: '温馨提示', icon: 0 });
  484. }
  485. })
  486. };
  487. var isLogin = function() {
  488. var userinfo = Yzn.cache.get('yzncms_userinfo');
  489. var uid = userinfo ? userinfo.id : 0;
  490. if (parseInt(uid) === 0) {
  491. Layer.alert('你当前未登录Yzncms,请登录后操作!', {
  492. title: '温馨提示',
  493. btn: ['立即登录'],
  494. yes: function(index, layero) {
  495. $(".btn-userinfo").trigger("click");
  496. },
  497. });
  498. return false;
  499. }
  500. return true;
  501. }
  502. var tables = [];
  503. $(document).on("click", "#droptables", function() {
  504. if ($(this).prop("checked")) {
  505. Yzn.api.ajax({
  506. url: 'addon/get_table_list',
  507. async: false,
  508. data: { name: $(this).data("name") }
  509. }, function(res) {
  510. tables = res.tables;
  511. return false;
  512. });
  513. var html;
  514. html = tables.length > 0 ? '<div class="alert alert-warning-light droptablestips" style="max-width:480px;max-height:300px;overflow-y: auto;">以下插件数据表将会被删除:<br>' + tables.join("<br>") + '<br>注意:部分插件还同时会删除演示数据和关联表等</div>' :
  515. '<div class="alert alert-warning-light droptablestips">注意:部分插件还同时会删除演示数据和关联表等</div>';
  516. $(html).insertAfter($(this).closest("p"));
  517. } else {
  518. $(".droptablestips").remove();
  519. }
  520. $(window).resize();
  521. });
  522. // 点击安装
  523. $(document).on("click", ".btn-install", function() {
  524. var name = $(this).data("name");
  525. var title = $(this).data("title");
  526. var version = $(this).data("version");
  527. if (!isLogin()) return
  528. Layer.confirm(title, function(index) {
  529. install(name, version, false);
  530. });
  531. });
  532. // 点击启用/禁用
  533. layui.form.on('switch(templet-status)', function(obj) {
  534. var checked = obj.elem.checked ? 1 : 0;
  535. var name = $(this).data("name");
  536. var action = $(this).data("action");
  537. operate(name, action, false, '', function(data, ret) {
  538. obj.elem.checked = !checked;
  539. });
  540. })
  541. // 点击卸载
  542. $(document).on("click", ".btn-uninstall", function() {
  543. var name = $(this).data('name');
  544. var title = $(this).data('title');
  545. if ($(this).data('status') == 1) {
  546. Layer.alert('请先禁用插件再进行卸载', { icon: 7 });
  547. return false;
  548. }
  549. Layer.confirm(layui.laytpl($("#uninstalltpl").html()).render({ name: name, title: title }), function(index, layero) {
  550. uninstall(name, false, $("input[name='droptables']", layero).prop("checked"));
  551. });
  552. });
  553. },
  554. config: function() {
  555. Controller.api.bindevent();
  556. },
  557. api: {
  558. bindevent: function() {
  559. Form.api.bindevent($("form.layui-form"));
  560. },
  561. refresh: function () {
  562. //刷新左侧边栏
  563. Yzn.api.refreshmenu();
  564. table.reload(Table.init.table_render_id);
  565. }
  566. }
  567. };
  568. return Controller;
  569. });