| | <!DOCTYPE html>
|
| | <html>
|
| | <head>
|
| | <title>代理管理界面</title>
|
| | <style>
|
| | body {
|
| | font-family: Arial, sans-serif;
|
| | max-width: 1200px;
|
| | margin: 0 auto;
|
| | padding: 20px;
|
| | }
|
| | .container {
|
| | display: flex;
|
| | gap: 20px;
|
| | }
|
| | .section {
|
| | flex: 1;
|
| | background: #f5f5f5;
|
| | padding: 20px;
|
| | border-radius: 8px;
|
| | }
|
| | table {
|
| | width: 100%;
|
| | border-collapse: collapse;
|
| | margin: 10px 0;
|
| | }
|
| | th, td {
|
| | padding: 8px;
|
| | border: 1px solid #ddd;
|
| | text-align: left;
|
| | }
|
| | th { background: #eee; }
|
| | .enabled { color: green; }
|
| | .disabled { color: red; }
|
| | .form-group {
|
| | margin: 10px 0;
|
| | }
|
| | button {
|
| | padding: 5px 10px;
|
| | margin: 2px;
|
| | cursor: pointer;
|
| | }
|
| | .status-bar {
|
| | background: #e0e0e0;
|
| | padding: 10px;
|
| | margin: 10px 0;
|
| | border-radius: 4px;
|
| | }
|
| | </style>
|
| | </head>
|
| | <body>
|
| | <h1>代理管理界面</h1>
|
| |
|
| | <div class="status-bar">
|
| | <strong>系统状态:</strong>
|
| | Models代理数: <span id="modelsCount">0</span> |
|
| | Chat代理数: <span id="chatCount">0</span>
|
| | </div>
|
| |
|
| | <div class="container">
|
| | <div class="section">
|
| | <h2>Models代理列表</h2>
|
| | <table id="modelsTable">
|
| | <tr>
|
| | <th>URL</th>
|
| | <th>权重</th>
|
| | <th>状态</th>
|
| | <th>操作</th>
|
| | </tr>
|
| | </table>
|
| |
|
| | <h3>添加Models代理</h3>
|
| | <div class="form-group">
|
| | <input type="text" id="modelsUrl" placeholder="URL">
|
| | <input type="number" id="modelsWeight" placeholder="权重" value="1">
|
| | <button onclick="addTarget('models')">添加</button>
|
| | </div>
|
| | </div>
|
| |
|
| | <div class="section">
|
| | <h2>Chat代理列表</h2>
|
| | <table id="chatTable">
|
| | <tr>
|
| | <th>URL</th>
|
| | <th>权重</th>
|
| | <th>状态</th>
|
| | <th>操作</th>
|
| | </tr>
|
| | </table>
|
| |
|
| | <h3>添加Chat代理</h3>
|
| | <div class="form-group">
|
| | <input type="text" id="chatUrl" placeholder="URL">
|
| | <input type="number" id="chatWeight" placeholder="权重" value="1">
|
| | <button onclick="addTarget('chat')">添加</button>
|
| | </div>
|
| | </div>
|
| | </div>
|
| |
|
| | <script>
|
| | const password = new URLSearchParams(window.location.search).get('password');
|
| |
|
| | function updateTables() {
|
| | fetch('/admin/api/targets?password=' + password)
|
| | .then(response => response.json())
|
| | .then(data => {
|
| | document.getElementById('modelsCount').textContent = data.models.length;
|
| | document.getElementById('chatCount').textContent = data.chat.length;
|
| |
|
| | updateTable('models', data.models);
|
| | updateTable('chat', data.chat);
|
| | });
|
| | }
|
| |
|
| | function updateTable(type, targets) {
|
| | const table = document.getElementById(type + 'Table');
|
| |
|
| | while (table.rows.length > 1) {
|
| | table.deleteRow(1);
|
| | }
|
| |
|
| | targets.forEach((target, index) => {
|
| | const row = table.insertRow();
|
| | row.innerHTML = `
|
| | <td>${target.url}</td>
|
| | <td>${target.weight}</td>
|
| | <td class="${target.enabled ? 'enabled' : 'disabled'}">
|
| | ${target.enabled ? '启用' : '禁用'}
|
| | </td>
|
| | <td>
|
| | <button onclick="toggleTarget('${type}', '${target.url}')">
|
| | ${target.enabled ? '禁用' : '启用'}
|
| | </button>
|
| | <button onclick="deleteTarget('${type}', '${target.url}')">删除</button>
|
| | </td>
|
| | `;
|
| | });
|
| | }
|
| |
|
| | function addTarget(type) {
|
| | const url = document.getElementById(type + 'Url').value;
|
| | const weight = document.getElementById(type + 'Weight').value;
|
| |
|
| | fetch('/admin/api/target', {
|
| | method: 'POST',
|
| | headers: {
|
| | 'Content-Type': 'application/json',
|
| | },
|
| | body: JSON.stringify({
|
| | type: type,
|
| | url: url,
|
| | weight: parseInt(weight),
|
| | password: password
|
| | })
|
| | }).then(() => {
|
| | document.getElementById(type + 'Url').value = '';
|
| | document.getElementById(type + 'Weight').value = '1';
|
| | updateTables();
|
| | });
|
| | }
|
| |
|
| | function toggleTarget(type, url) {
|
| | fetch('/admin/api/target/toggle', {
|
| | method: 'POST',
|
| | headers: {
|
| | 'Content-Type': 'application/json',
|
| | },
|
| | body: JSON.stringify({
|
| | type: type,
|
| | url: url,
|
| | password: password
|
| | })
|
| | }).then(() => updateTables());
|
| | }
|
| |
|
| | function deleteTarget(type, url) {
|
| | if (!confirm('确定要删除这个代理地址吗?')) return;
|
| |
|
| | fetch('/admin/api/target', {
|
| | method: 'DELETE',
|
| | headers: {
|
| | 'Content-Type': 'application/json',
|
| | },
|
| | body: JSON.stringify({
|
| | type: type,
|
| | url: url,
|
| | password: password
|
| | })
|
| | }).then(() => updateTables());
|
| | }
|
| |
|
| |
|
| | updateTables();
|
| |
|
| | setInterval(updateTables, 5000);
|
| | </script>
|
| | </body>
|
| | </html>
|
| |
|