better-staridc-MNBT
1<?php mnbt_admin_include('head'); ?>
2<script type="text/javascript" src="<?=mnbt_asset_url('js/jquery-confirm/jquery-confirm.min.js')?>"></script>
3<link href="<?=mnbt_asset_url('js/jquery-confirm/jquery-confirm.min.css')?>" rel="stylesheet">
4
5<div class="container-fluid p-t-15">
6<?php if (!empty($plugin_error)): ?>
7 <div class="alert alert-warning"><?=htmlspecialchars($plugin_error, ENT_QUOTES, 'UTF-8')?></div>
8<?php endif; ?>
9<?php
10$settingsTabs = function_exists('mnbt_plugin_settings_tabs') ? mnbt_plugin_settings_tabs() : [];
11if ($settingsTabs):
12?>
13 <div class="card mb-3">
14 <div class="card-header"><h4>已启用插件设置</h4></div>
15 <div class="card-body">
16 <?php foreach ($settingsTabs as $tab): ?>
17 <a class="btn btn-outline-primary btn-sm m-1 multitabs" href="<?=htmlspecialchars($tab['url'] ?? '#', ENT_QUOTES, 'UTF-8')?>">
18 <?=htmlspecialchars($tab['title'] ?? '', ENT_QUOTES, 'UTF-8')?>
19 </a>
20 <?php endforeach; ?>
21 </div>
22 </div>
23<?php endif; ?>
24 <div class="card">
25 <div class="card-header">
26 <h4>插件管理</h4>
27 <small class="text-muted">插件目录:app_plugins/{标识}/ ,需包含 plugin.json 与 bootstrap.php</small>
28 </div>
29 <div class="card-body">
30 <div class="table-responsive">
31 <table class="table table-bordered table-hover" id="plugin-table">
32 <thead>
33 <tr>
34 <th>标识</th>
35 <th>名称</th>
36 <th>版本</th>
37 <th>作者</th>
38 <th>状态</th>
39 <th>说明</th>
40 <th style="width:220px">操作</th>
41 </tr>
42 </thead>
43 <tbody id="plugin-tbody">
44 <tr><td colspan="7" class="text-center text-muted">加载中…</td></tr>
45 </tbody>
46 </table>
47 </div>
48 </div>
49 </div>
50</div>
51
52<script>
53function loadPlugins() {
54 $.post('ajax.php', {gn: 'plugin_list'}, function (res) {
55 var data;
56 try { data = typeof res === 'string' ? JSON.parse(res) : res; } catch (e) { data = null; }
57 var rows = (data && data.rows) ? data.rows : [];
58 var html = '';
59 if (!rows.length) {
60 html = '<tr><td colspan="7" class="text-center text-muted">未发现插件。请将插件放到 app_plugins/ 目录。</td></tr>';
61 } else {
62 rows.forEach(function (r) {
63 var st = r.enabled ? '<span class="badge badge-success">已启用</span>' : (r.installed ? '<span class="badge badge-secondary">已安装</span>' : '<span class="badge badge-light">未安装</span>');
64 html += '<tr>';
65 html += '<td><code>' + $('<div>').text(r.slug).html() + '</code></td>';
66 html += '<td>' + $('<div>').text(r.name || '').html() + '</td>';
67 html += '<td>' + $('<div>').text(r.version || '').html() + '</td>';
68 html += '<td>' + $('<div>').text(r.author || '-').html() + '</td>';
69 html += '<td>' + st + '</td>';
70 html += '<td class="small">' + $('<div>').text(r.description || '').html() + '</td>';
71 html += '<td>';
72 if (!r.installed) {
73 html += '<button type="button" class="btn btn-sm btn-primary m-1" data-act="install" data-slug="' + r.slug + '">安装</button>';
74 }
75 if (r.enabled) {
76 html += '<button type="button" class="btn btn-sm btn-warning m-1" data-act="disable" data-slug="' + r.slug + '">禁用</button>';
77 } else {
78 html += '<button type="button" class="btn btn-sm btn-success m-1" data-act="enable" data-slug="' + r.slug + '">启用</button>';
79 }
80 if (r.installed) {
81 html += '<button type="button" class="btn btn-sm btn-outline-danger m-1" data-act="uninstall" data-slug="' + r.slug + '">卸载</button>';
82 }
83 html += '</td></tr>';
84 });
85 }
86 $('#plugin-tbody').html(html);
87 }).fail(function () {
88 $('#plugin-tbody').html('<tr><td colspan="7" class="text-danger text-center">加载失败</td></tr>');
89 });
90}
91
92function pluginAct(act, slug) {
93 var gn = 'plugin_enable';
94 var post = {slug: slug};
95 if (act === 'install') {
96 gn = 'plugin_install';
97 } else if (act === 'uninstall') {
98 gn = 'plugin_uninstall';
99 } else if (act === 'enable') {
100 post.enabled = 'true';
101 } else if (act === 'disable') {
102 post.enabled = 'false';
103 }
104 post.gn = gn;
105 $.post('ajax.php', post, function (res) {
106 var data;
107 try { data = typeof res === 'string' ? JSON.parse(res) : res; } catch (e) { data = {code: res}; }
108 var ok = data && (data.qk == 1 || data.success === true || (data.code && String(data.code).indexOf('成功') >= 0) || (data.code && String(data.code).indexOf('启用') >= 0) || (data.code && String(data.code).indexOf('禁用') >= 0) || (data.code && String(data.code).indexOf('安装') >= 0) || (data.code && String(data.code).indexOf('卸载') >= 0));
109 if (typeof $.notify === 'function') {
110 $.notify({message: data.msg || data.code || '完成'}, {type: ok ? 'success' : 'danger'});
111 } else {
112 alert(data.msg || data.code || '完成');
113 }
114 loadPlugins();
115 });
116}
117
118$(function () {
119 loadPlugins();
120 $('#plugin-tbody').on('click', 'button[data-act]', function () {
121 var act = $(this).data('act');
122 var slug = $(this).data('slug');
123 if (act === 'uninstall') {
124 if (!confirm('确定卸载插件 ' + slug + ' ?将删除数据库记录与插件配置,文件仍保留。')) return;
125 }
126 pluginAct(act, slug);
127 });
128});
129</script>