You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

281 lines
9.6 KiB

2 years ago
2 days ago
2 years ago
2 years ago
7 months ago
2 years ago
2 years ago
  1. {extend name="admin/layout" /}
  2. {block name="title"}插件列表{/block}
  3. {block name="main"}
  4. <style>
  5. td{overflow: hidden;text-overflow: ellipsis;white-space: nowrap;max-width:340px;}
  6. .bt-ico-ask {
  7. border: 1px solid #fb7d00;
  8. border-radius: 8px;
  9. color: #fb7d00;
  10. cursor: help;
  11. display: inline-block;
  12. font-family: arial;
  13. font-size: 11px;
  14. font-style: normal;
  15. height: 16px;
  16. line-height: 16px;
  17. margin-left: 5px;
  18. text-align: center;
  19. width: 16px
  20. }
  21. .bt-ico-ask:hover {
  22. background-color: #fb7d00;
  23. color: #fff
  24. }
  25. </style>
  26. <div class="modal fade" id="help" tabindex="-1" role="dialog">
  27. <div class="modal-dialog" role="document">
  28. <div class="modal-content">
  29. <div class="modal-header">
  30. <button type="button" class="close" data-dismiss="modal" aria-label="Close">
  31. <span aria-hidden="true">&times;</span>
  32. </button>
  33. <h4 class="modal-title">帮助</h4>
  34. </div>
  35. <div class="modal-body">
  36. <p>“版本与状态”一列中,红色的按钮代表本地不存在该版本插件包,需要点击下载;绿色的按钮代表已存在。</p>
  37. <p>官方插件包本地存储路径是/data/plugins/package/软件标识-版本号.zip,第三方插件包路径是/data/plugins/other/other/,对于部分包含二次验证的插件可以自行修改。</p>
  38. <p>若对接的服务器网速较慢,可能会导致下载失败,提示"服务器错误",可稍等一会,进入对接服务器/tmp/plugins目录下载插件包,将_改成-,并上传到本站/data/plugins/package目录下。</p>
  39. </div>
  40. <div class="modal-footer">
  41. <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
  42. </div>
  43. </div>
  44. </div>
  45. </div>
  46. <div class="container" style="padding-top:70px;">
  47. <div class="col-xs-12 center-block" style="float: none;">
  48. <div id="searchToolbar">
  49. <form onsubmit="return searchSubmit()" method="GET" class="form-inline">
  50. <div class="form-group">
  51. <label>搜索</label>
  52. <input type="text" class="form-control" name="keyword" placeholder="应用名称">
  53. </div>
  54. <div class="form-group">
  55. <select name="type" class="form-control"><option value="0">全部插件</option>
  56. {foreach $typelist as $k=>$v}<option value="{$k}">{$v}</option>{/foreach} </select>
  57. </div>
  58. <div class="form-group">
  59. <button class="btn btn-primary" type="submit"><i class="fa fa-search"></i> 搜索</button>&nbsp;
  60. <a href="javascript:searchClear()" class="btn btn-default"><i class="fa fa-repeat"></i> 重置</a>&nbsp;
  61. <a href="javascript:refresh_plugins()" class="btn btn-success"><i class="fa fa-refresh"></i> 刷新列表</a>&nbsp;
  62. <a href="javascript:download_plugins()" class="btn btn-warning" id="batch_down" style="display:none;"><i class="fa fa-download"></i> 批量下载</a>&nbsp;
  63. <button type="button" class="btn btn-default" data-toggle="modal" data-target="#help"><i class="fa fa-info-circle"></i> 帮助</button>
  64. </div>
  65. </form>
  66. </div>
  67. <table id="listTable">
  68. </table>
  69. </div>
  70. </div>
  71. <script src="{$cdnpublic}layer/3.5.1/layer.js"></script>
  72. <script src="{$cdnpublic}bootstrap-table/1.19.1/bootstrap-table.min.js"></script>
  73. <script src="{$cdnpublic}bootstrap-table/1.19.1/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
  74. <script src="/static/js/custom.js"></script>
  75. <script>
  76. function download_version(name, version, status){
  77. if(status == true){
  78. var confirm = layer.confirm('是否确定重新下载'+version+'版本插件包?', {
  79. btn: ['确定','取消']
  80. }, function(){
  81. download_plugin(name, version)
  82. }, function(){
  83. layer.close(confirm)
  84. });
  85. }else{
  86. download_plugin(name, version)
  87. }
  88. }
  89. function download_plugin(name, version){
  90. var ii = layer.msg('正在下载,请稍候...', {icon: 16, shade:0.1, time: 0});
  91. $.ajax({
  92. type : 'POST',
  93. url : '/admin/download_plugin',
  94. data: { name:name, version:version},
  95. dataType : 'json',
  96. success : function(data) {
  97. layer.close(ii)
  98. if(data.code == 0){
  99. layer.alert(data.msg, {icon:1}, function(){layer.closeAll();searchSubmit();});
  100. }else{
  101. layer.alert(data.msg, {icon:2});
  102. }
  103. },
  104. error:function(data){
  105. layer.close(ii)
  106. layer.msg('服务器错误', {icon:2});
  107. }
  108. });
  109. }
  110. function refresh_plugins(){
  111. var confirm = layer.confirm('是否确定从宝塔官方获取最新插件列表?', {
  112. btn: ['确定','取消']
  113. }, function(){
  114. layer.close(confirm)
  115. var ii = layer.msg('正在获取插件列表,请稍候...', {icon: 16, shade:0.1, time: 0});
  116. $.ajax({
  117. type : 'GET',
  118. url : '/admin/refresh_plugins',
  119. dataType : 'json',
  120. success : function(data) {
  121. layer.close(ii)
  122. if(data.code == 0){
  123. layer.alert(data.msg, {icon:1}, function(){layer.closeAll();searchSubmit();});
  124. }else{
  125. layer.alert(data.msg, {icon:2});
  126. }
  127. },
  128. error:function(data){
  129. layer.close(ii)
  130. layer.msg('服务器错误', {icon:2});
  131. }
  132. });
  133. }, function(){
  134. layer.close(confirm)
  135. });
  136. }
  137. function download_plugins(){
  138. var confirm = layer.confirm('批量下载当前分类下未下载的插件包', {
  139. btn: ['确定','取消']
  140. }, function(){
  141. layer.close(confirm)
  142. $.downloadCount = 0;
  143. $.preDownloadCount = $.preDownload.length;
  144. download_item();
  145. }, function(){
  146. layer.close(confirm)
  147. });
  148. }
  149. function download_item(){
  150. if($.preDownload.length == 0){
  151. layer.alert('成功下载'+$.downloadCount+'个插件包!', {icon:1}, function(){layer.closeAll();searchSubmit();});
  152. return;
  153. }
  154. var plugin = $.preDownload[0];
  155. if(plugin.name == 'firewall'){
  156. $.preDownload.shift();
  157. download_item();
  158. return;
  159. }
  160. $.downloadCount++;
  161. var ii = layer.msg('['+$.downloadCount+'/'+$.preDownloadCount+']正在下载'+plugin.name+'-'+plugin.version, {icon: 16, shade:0.1, time: 0});
  162. $.ajax({
  163. type : 'POST',
  164. url : '/admin/download_plugin',
  165. data: { name:plugin.name, version:plugin.version},
  166. dataType : 'json',
  167. success : function(data) {
  168. layer.close(ii)
  169. if(data.code == 0){
  170. $.preDownload.shift();
  171. download_item();
  172. }else{
  173. layer.alert(data.msg, {icon:2});
  174. }
  175. },
  176. error:function(data){
  177. layer.close(ii)
  178. layer.msg('服务器错误', {icon:2});
  179. }
  180. });
  181. }
  182. function searchByType(type){
  183. $("input[name=keyword]").val('');
  184. $("select[name=type]").val(type);
  185. searchSubmit()
  186. }
  187. $(document).ready(function(){
  188. updateToolbar();
  189. const defaultPageSize = 20;
  190. $("#listTable").bootstrapTable({
  191. url: '/admin/plugins_data',
  192. pageNumber: 1,
  193. pageSize: 15,
  194. sidePagination: 'client',
  195. classes: 'table table-striped table-hover table-bottom-border',
  196. columns: [
  197. {
  198. field: 'name',
  199. title: '软件标识',
  200. formatter: function(value, row, index) {
  201. return '<b>'+value+'</b>';
  202. }
  203. },
  204. {
  205. field: 'title',
  206. title: '软件名称'
  207. },
  208. {
  209. field: 'type',
  210. title: '软件分类',
  211. formatter: function(value, row, index) {
  212. return '<a href="javascript:searchByType('+value+')" title="查看该分类下的插件">'+row.typename+'</a>';
  213. }
  214. },
  215. {
  216. field: 'desc',
  217. title: '说明',
  218. },
  219. {
  220. field: 'price',
  221. title: '价格',
  222. formatter: function(value, row, index) {
  223. return value > 0 ? '<span style="color:#fc6d26">¥'+value+'</span>' : '免费';
  224. }
  225. },
  226. {
  227. field: 'author',
  228. title: '开发商'
  229. },
  230. {
  231. field: 'versions',
  232. title: '版本与状态',
  233. formatter: function(value, row, index) {
  234. var html = '';
  235. if(row.type == 5){
  236. html += '<a href="javascript:" class="btn btn-xs btn-success" disabled>无需下载</a>';
  237. }else{
  238. $.each(value, function(index,item){
  239. if(item.status)
  240. html += '<a href="javascript:download_version(\''+row.name+'\',\''+item.version+'\','+item.status+')" class="btn btn-xs btn-success">'+item.version+'</a>&nbsp;';
  241. else
  242. html += '<a href="javascript:download_version(\''+row.name+'\',\''+item.version+'\','+item.status+')" class="btn btn-xs btn-danger">'+item.version+'</a>&nbsp;';
  243. })
  244. }
  245. return html
  246. }
  247. },
  248. ],
  249. onLoadSuccess: function(data){
  250. $.preDownload = [];
  251. var type = $("select[name=type] option:selected").text();
  252. if(type != '全部插件' && type != '运行环境' && type != '第三方应用'){
  253. $("#batch_down").show();
  254. if(data.length > 0){
  255. $.each(data, function(index, plugin){
  256. if(plugin.versions.length > 0){
  257. $.each(plugin.versions, function(index, version){
  258. if(!version.status){
  259. $.preDownload.push({name:plugin.name, version:version.version})
  260. }
  261. });
  262. }
  263. });
  264. }
  265. }else{
  266. $("#batch_down").hide();
  267. }
  268. }
  269. })
  270. })
  271. </script>
  272. {/block}