Commit 28dc84a3462ae45fdb2841f44897c1a55f935f0b
1 parent
b2a37eb2
feat: add device list to admin portal for easy binding
Showing
1 changed file
with
89 additions
and
20 deletions
| @@ -65,7 +65,23 @@ if ($pdo && $_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && | @@ -65,7 +65,23 @@ if ($pdo && $_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && | ||
| 65 | } | 65 | } |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | -// 获取设备列表 | 68 | +// 获取所有设备列表 (含绑定信息) |
| 69 | +$devices = []; | ||
| 70 | +if ($pdo) { | ||
| 71 | + try { | ||
| 72 | + $devices = $pdo->query(" | ||
| 73 | + SELECT d.id, d.name, d.status, d.last_seen, u.phone AS bound_phone, u.nickname AS bound_user | ||
| 74 | + FROM devices d | ||
| 75 | + LEFT JOIN user_device_bindings b ON d.id = b.device_id | ||
| 76 | + LEFT JOIN users u ON b.user_id = u.id | ||
| 77 | + ORDER BY d.created_at DESC | ||
| 78 | + ")->fetchAll(PDO::FETCH_ASSOC); | ||
| 79 | + } catch (Exception $e) { | ||
| 80 | + // Silent fail or log | ||
| 81 | + } | ||
| 82 | +} | ||
| 83 | + | ||
| 84 | +// 获取绑定历史 (已有的逻辑) | ||
| 69 | $bindings = []; | 85 | $bindings = []; |
| 70 | if ($pdo) { | 86 | if ($pdo) { |
| 71 | try { | 87 | try { |
| @@ -92,6 +108,12 @@ if ($pdo) { | @@ -92,6 +108,12 @@ if ($pdo) { | ||
| 92 | <title>Moltbot 管理后台</title> | 108 | <title>Moltbot 管理后台</title> |
| 93 | <link rel="stylesheet" href="style.css"> | 109 | <link rel="stylesheet" href="style.css"> |
| 94 | <link rel="icon" href="data:,"> | 110 | <link rel="icon" href="data:,"> |
| 111 | + <script> | ||
| 112 | + function fillBind(deviceId) { | ||
| 113 | + document.querySelector('input[name="device_id"]').value = deviceId; | ||
| 114 | + document.querySelector('input[name="phone"]').focus(); | ||
| 115 | + } | ||
| 116 | + </script> | ||
| 95 | </head> | 117 | </head> |
| 96 | 118 | ||
| 97 | <body> | 119 | <body> |
| @@ -120,8 +142,7 @@ if ($pdo) { | @@ -120,8 +142,7 @@ if ($pdo) { | ||
| 120 | <div style="display: flex; gap: 20px;"> | 142 | <div style="display: flex; gap: 20px;"> |
| 121 | <div class="form-group" style="flex: 1;"> | 143 | <div class="form-group" style="flex: 1;"> |
| 122 | <label class="form-label">设备 ID</label> | 144 | <label class="form-label">设备 ID</label> |
| 123 | - <input type="text" name="device_id" class="form-control" placeholder="例如: dev_test_001" | ||
| 124 | - required> | 145 | + <input type="text" name="device_id" class="form-control" placeholder="点击下方列表选择或手动输入" required> |
| 125 | </div> | 146 | </div> |
| 126 | <div class="form-group" style="flex: 1;"> | 147 | <div class="form-group" style="flex: 1;"> |
| 127 | <label class="form-label">用户手机号</label> | 148 | <label class="form-label">用户手机号</label> |
| @@ -137,18 +158,79 @@ if ($pdo) { | @@ -137,18 +158,79 @@ if ($pdo) { | ||
| 137 | </form> | 158 | </form> |
| 138 | </div> | 159 | </div> |
| 139 | 160 | ||
| 140 | - <!-- 绑定列表卡片 --> | 161 | + <!-- 设备列表 (Auto-Registered Devices) --> |
| 141 | <div class="card"> | 162 | <div class="card"> |
| 142 | - <div class="title">绑定记录 (<?php echo count($bindings); ?>)</div> | 163 | + <div class="title">所有设备 (<?php echo count($devices); ?>)</div> |
| 164 | + <table style="width: 100%; border-collapse: collapse;"> | ||
| 165 | + <thead> | ||
| 166 | + <tr style="background: #f8f9fa;"> | ||
| 167 | + <th style="padding: 10px; text-align: left;">设备 ID</th> | ||
| 168 | + <th style="padding: 10px; text-align: left;">状态</th> | ||
| 169 | + <th style="padding: 10px; text-align: left;">绑定情况</th> | ||
| 170 | + <th style="padding: 10px; text-align: left;">最后在线</th> | ||
| 171 | + <th style="padding: 10px; text-align: left;">操作</th> | ||
| 172 | + </tr> | ||
| 173 | + </thead> | ||
| 174 | + <tbody> | ||
| 175 | + <?php foreach ($devices as $dev): ?> | ||
| 176 | + <tr style="border-bottom: 1px solid #eee;"> | ||
| 177 | + <td style="padding: 10px; font-family: monospace;"><?php echo htmlspecialchars($dev['id']); ?> | ||
| 178 | + </td> | ||
| 179 | + <td style="padding: 10px;"> | ||
| 180 | + <?php if ($dev['status'] === 'online'): ?> | ||
| 181 | + <span style="color: green;">● 在线</span> | ||
| 182 | + <?php else: ?> | ||
| 183 | + <span style="color: gray;">● 离线</span> | ||
| 184 | + <?php endif; ?> | ||
| 185 | + </td> | ||
| 186 | + <td style="padding: 10px;"> | ||
| 187 | + <?php if ($dev['bound_phone']): ?> | ||
| 188 | + <span style="color: #666;"> | ||
| 189 | + 已绑: <?php echo htmlspecialchars($dev['bound_user']); ?> | ||
| 190 | + (<?php echo htmlspecialchars($dev['bound_phone']); ?>) | ||
| 191 | + </span> | ||
| 192 | + <?php else: ?> | ||
| 193 | + <span | ||
| 194 | + style="color: #ff9800; background: #fff3e0; padding: 2px 6px; border-radius: 4px; font-size: 12px;">未绑定</span> | ||
| 195 | + <?php endif; ?> | ||
| 196 | + </td> | ||
| 197 | + <td style="padding: 10px; font-size: 12px; color: #999;"> | ||
| 198 | + <?php echo $dev['last_seen'] ? date('H:i:s', strtotime($dev['last_seen'])) : '-'; ?> | ||
| 199 | + </td> | ||
| 200 | + <td style="padding: 10px;"> | ||
| 201 | + <?php if (!$dev['bound_phone']): ?> | ||
| 202 | + <button onclick="fillBind('<?php echo htmlspecialchars($dev['id']); ?>')" | ||
| 203 | + style="cursor: pointer; background: #007bff; color: white; border: none; padding: 4px 8px; border-radius: 4px; font-size: 12px;">选择绑定</button> | ||
| 204 | + <?php else: ?> | ||
| 205 | + <button disabled | ||
| 206 | + style="background: #eee; color: #999; border: none; padding: 4px 8px; border-radius: 4px; font-size: 12px;">已占用</button> | ||
| 207 | + <?php endif; ?> | ||
| 208 | + </td> | ||
| 209 | + </tr> | ||
| 210 | + <?php endforeach; ?> | ||
| 211 | + <?php if (empty($devices)): ?> | ||
| 212 | + <tr> | ||
| 213 | + <td colspan="5" style="text-align: center; color: #999; padding: 20px;"> | ||
| 214 | + 暂无设备。请启动 Moltbot 客户端并连接服务器以自动注册。 | ||
| 215 | + </td> | ||
| 216 | + </tr> | ||
| 217 | + <?php endif; ?> | ||
| 218 | + </tbody> | ||
| 219 | + </table> | ||
| 220 | + </div> | ||
| 221 | + | ||
| 222 | + <!-- 绑定历史列表 (已有的) --> | ||
| 223 | + <div class="card"> | ||
| 224 | + <div class="title" style="color: #666; font-size: 14px;">绑定历史记录</div> | ||
| 225 | + <!-- ... existing table code ... --> | ||
| 143 | <table> | 226 | <table> |
| 227 | + <!-- ... existing table content ... --> | ||
| 144 | <thead> | 228 | <thead> |
| 145 | <tr> | 229 | <tr> |
| 146 | <th>用户</th> | 230 | <th>用户</th> |
| 147 | <th>手机号</th> | 231 | <th>手机号</th> |
| 148 | <th>设备 ID</th> | 232 | <th>设备 ID</th> |
| 149 | - <th>主设备</th> | ||
| 150 | <th>绑定时间</th> | 233 | <th>绑定时间</th> |
| 151 | - <th>操作</th> | ||
| 152 | </tr> | 234 | </tr> |
| 153 | </thead> | 235 | </thead> |
| 154 | <tbody> | 236 | <tbody> |
| @@ -157,22 +239,9 @@ if ($pdo) { | @@ -157,22 +239,9 @@ if ($pdo) { | ||
| 157 | <td><?php echo htmlspecialchars($row['nickname']); ?></td> | 239 | <td><?php echo htmlspecialchars($row['nickname']); ?></td> |
| 158 | <td><?php echo htmlspecialchars($row['phone']); ?></td> | 240 | <td><?php echo htmlspecialchars($row['phone']); ?></td> |
| 159 | <td><?php echo htmlspecialchars($row['device_id']); ?></td> | 241 | <td><?php echo htmlspecialchars($row['device_id']); ?></td> |
| 160 | - <td> | ||
| 161 | - <?php if ($row['is_primary']): ?> | ||
| 162 | - <span style="color: var(--primary-color);">✔</span> | ||
| 163 | - <?php endif; ?> | ||
| 164 | - </td> | ||
| 165 | <td><?php echo $row['bound_at']; ?></td> | 242 | <td><?php echo $row['bound_at']; ?></td> |
| 166 | - <td> | ||
| 167 | - <a href="#" style="color: red; font-size: 12px; text-decoration: none;">解绑</a> | ||
| 168 | - </td> | ||
| 169 | </tr> | 243 | </tr> |
| 170 | <?php endforeach; ?> | 244 | <?php endforeach; ?> |
| 171 | - <?php if (empty($bindings)): ?> | ||
| 172 | - <tr> | ||
| 173 | - <td colspan="6" style="text-align: center; color: #999;">暂无数据</td> | ||
| 174 | - </tr> | ||
| 175 | - <?php endif; ?> | ||
| 176 | </tbody> | 245 | </tbody> |
| 177 | </table> | 246 | </table> |
| 178 | </div> | 247 | </div> |
Please
register
or
login
to post a comment