仰望星辰工作室

better-staridc-MNBT

better-staridc-MNBT/ app_plugins/auto_deploy/bootstrap.php 7.7 KB · 224 行 原始文件
Z zfhsh first commit 1 天前
1<?php
2if (!defined('IN_CRONLITE')) {
3 exit;
4}
5
6// ===================================================================
7// 插件注册
8// ===================================================================
9
10mnbt_plugin_register('auto_deploy', [
11 'name' => '高级自动部署',
12]);
13
14// ===================================================================
15// 用户端菜单(插件核心:用户自主部署网站)
16// ===================================================================
17
18mnbt_register_menu('user', [
19 'title' => '一键部署',
20 'icon' => 'mdi-package-variant',
21 'order' => 30,
22 'children' => [
23 ['title' => '软件商店', 'page' => 'index', 'icon' => 'mdi-monitor-dashboard', 'multitabs' => true],
24 ['title' => '部署记录', 'page' => 'history', 'icon' => 'mdi-history', 'multitabs' => true],
25 ],
26]);
27
28mnbt_register_page('user', 'index', 'user/index.php', '软件商店');
29mnbt_register_page('user', 'history', 'user/history.php', '部署记录');
30
31// ===================================================================
32// 管理端菜单(仅只读查看所有用户部署记录,不提供部署操作)
33// ===================================================================
34
35mnbt_register_menu('admin', [
36 'title' => '自动部署',
37 'icon' => 'mdi-package-variant',
38 'order' => 25,
39 'children' => [
40 ['title' => '部署记录', 'page' => 'history', 'icon' => 'mdi-history', 'multitabs' => true],
41 ],
42]);
43
44mnbt_register_page('admin', 'history', 'admin/history.php', '部署记录');
45
46// ===================================================================
47// 辅助函数
48// ===================================================================
49
50/**
51 * 根据 MN_bt.id 创建 bt_api 实例
52 */
53function auto_deploy_init_api($nodeId)
54{
55 global $DB;
56
57 $node = $DB->get_row_prepare("SELECT * FROM MN_bt WHERE id=? AND qk<>'false' LIMIT 1", [(int)$nodeId]);
58 if (!$node) {
59 return ['api' => null, 'node' => null, 'error' => '节点不存在或已禁用'];
60 }
61
62 $ptl = ($node['ptl'] == 'true') ? 'https' : 'http';
63 $btipe = $ptl . '://' . $node['btip'] . ':' . $node['btdk'];
64
65 if (!class_exists('bt_api')) {
66 require_once SYSTEM_ROOT . 'bt_api.php';
67 }
68
69 $api = new bt_api($btipe, $node['btmy']);
70 return ['api' => $api, 'node' => $node, 'error' => ''];
71}
72
73/**
74 * 获取当前用户绑定的主机(系统设计:一个用户对应一个主机,取第一条)
75 * 主机 = MN_zj 中的一条记录,对应宝塔面板上的一个网站(sqldz 为网站名)
76 * 附带节点信息与密钥,返回 null 表示无可用主机
77 */
78function auto_deploy_get_my_host()
79{
80 global $DB, $yhc;
81
82 if (empty($yhc['user'])) {
83 return null;
84 }
85
86 return $DB->get_row_prepare(
87 "SELECT z.id, z.ssbt, z.sqldz, z.ymbds, z.btid, z.datae,
88 b.id AS node_id, b.btdh, b.btip, b.btdk, b.btos, b.ptl, b.btmy
89 FROM MN_zj z INNER JOIN MN_bt b ON b.btdh = z.ssbt
90 WHERE z.user=? AND z.qk<>'false' AND b.qk<>'false'
91 ORDER BY z.id ASC LIMIT 1",
92 [$yhc['user']]
93 ) ?: null;
94}
95
96/**
97 * 记录部署日志
98 */
99function auto_deploy_log($nodeId, $nodeName, $dname, $siteName, $projectType, $result, $operator, $adminPwd = '', $successUrl = '')
100{
101 global $DB;
102 $DB->query_prepare(
103 "INSERT INTO plg_auto_deploy_log (node_id, node_name, dname, site_name, project_type, result, admin_username, admin_password, success_url, admin_user, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
104 [(int)$nodeId, $nodeName, $dname, $siteName, $projectType, $result, $operator, $adminPwd, $successUrl, $operator, date('Y-m-d H:i:s')]
105 );
106}
107
108// ===================================================================
109// 用户端 AJAX
110// ===================================================================
111
112// --- 我的主机信息(含节点) ---
113mnbt_register_ajax('user', 'p_auto_deploy_hosts', function () {
114 mnbt_plugin_require_user();
115 $host = auto_deploy_get_my_host();
116 json_exit_success('ok', ['host' => $host]);
117});
118
119// --- 软件包列表(按节点,节点须属于当前用户主机) ---
120mnbt_register_ajax('user', 'p_auto_deploy_packages', function () {
121 mnbt_plugin_require_user();
122 $nodeId = isset($_POST['node_id']) ? (int)$_POST['node_id'] : 0;
123 $host = auto_deploy_get_my_host();
124 if (!$host || (int)$host['node_id'] !== $nodeId) {
125 json_exit_error('参数错误');
126 }
127 $r = auto_deploy_init_api($nodeId);
128 if ($r['error'] !== '') {
129 json_exit_error($r['error']);
130 }
131 $result = $r['api']->deployment_get_list();
132 if (!$result || empty($result['list'])) {
133 json_exit_success('ok', ['packages' => []]);
134 return;
135 }
136 json_exit_success('ok', ['packages' => $result['list']]);
137});
138
139// --- 一键部署到我的主机 ---
140mnbt_register_ajax('user', 'p_auto_deploy_setup', function () {
141 mnbt_plugin_require_user();
142 global $yhc;
143
144 $dname = isset($_POST['dname']) ? trim((string)$_POST['dname']) : '';
145 $projectType = isset($_POST['project_type']) ? trim((string)$_POST['project_type']) : 'php';
146
147 if ($dname === '') json_exit_error('请选择软件包');
148
149 $host = auto_deploy_get_my_host();
150 if (!$host) json_exit_error('未找到可用的主机');
151
152 $siteName = $host['sqldz'];
153 if ($siteName === '') json_exit_error('主机未绑定网站');
154
155 $ptl = ($host['ptl'] == 'true') ? 'https' : 'http';
156 $btipe = $ptl . '://' . $host['btip'] . ':' . $host['btdk'];
157 if (!class_exists('bt_api')) {
158 require_once SYSTEM_ROOT . 'bt_api.php';
159 }
160 $api = new bt_api($btipe, $host['btmy']);
161
162 $result = $api->deployment_setup_package($dname, $siteName, $projectType);
163
164 if (!$result || empty($result['status'])) {
165 $errMsg = is_array($result) ? ($result['msg'] ?? '部署失败') : '部署失败:面板返回内容无法解析,请检查节点面板的「一键部署」功能是否可用';
166 auto_deploy_log((int)$host['node_id'], $host['btdh'] ?? '', $dname, $siteName, $projectType, 'fail', $yhc['user']);
167 json_exit_error($errMsg);
168 }
169
170 $msg = $result['msg'] ?? [];
171 $adminUser = is_array($msg) ? ($msg['admin_username'] ?? '') : '';
172 $adminPwd = is_array($msg) ? ($msg['admin_password'] ?? '') : '';
173 $successUrl = is_array($msg) ? ($msg['success_url'] ?? '') : '';
174
175 auto_deploy_log((int)$host['node_id'], $host['btdh'] ?? '', $dname, $siteName, $projectType, 'success', $yhc['user'], $adminPwd, $successUrl);
176
177 json_exit_success('部署成功', [
178 'admin_username' => $adminUser,
179 'admin_password' => $adminPwd,
180 'success_url' => $successUrl,
181 ]);
182});
183
184// --- 我的部署记录 ---
185mnbt_register_ajax('user', 'p_auto_deploy_history', function () {
186 mnbt_plugin_require_user();
187 global $DB, $yhc;
188 $page = isset($_POST['page']) ? max(1, (int)$_POST['page']) : 1;
189 $limit = 20;
190 $offset = ($page - 1) * $limit;
191
192 $total = $DB->get_row_prepare("SELECT COUNT(*) AS cnt FROM plg_auto_deploy_log WHERE admin_user=?", [$yhc['user']])['cnt'] ?? 0;
193 $rows = $DB->get_all_prepare("SELECT * FROM plg_auto_deploy_log WHERE admin_user=? ORDER BY id DESC LIMIT ?, ?", [$yhc['user'], $offset, $limit]) ?: [];
194
195 json_exit_success('ok', [
196 'rows' => $rows,
197 'total' => (int)$total,
198 'page' => $page,
199 'pages' => max(1, ceil($total / $limit)),
200 ]);
201});
202
203// ===================================================================
204// 管理端 AJAX
205// ===================================================================
206
207// --- 全部用户的部署记录(只读) ---
208mnbt_register_ajax('admin', 'p_auto_deploy_history', function () {
209 mnbt_plugin_require_admin();
210 global $DB;
211 $page = isset($_POST['page']) ? max(1, (int)$_POST['page']) : 1;
212 $limit = 20;
213 $offset = ($page - 1) * $limit;
214
215 $total = $DB->get_row_prepare("SELECT COUNT(*) AS cnt FROM plg_auto_deploy_log")['cnt'] ?? 0;
216 $rows = $DB->get_all_prepare("SELECT * FROM plg_auto_deploy_log ORDER BY id DESC LIMIT ?, ?", [$offset, $limit]) ?: [];
217
218 json_exit_success('ok', [
219 'rows' => $rows,
220 'total' => (int)$total,
221 'page' => $page,
222 'pages' => max(1, ceil($total / $limit)),
223 ]);
224});