fix
parent
961d8981fc
commit
ff30e857a7
|
|
@ -0,0 +1,23 @@
|
|||
version: '3.8'
|
||||
|
||||
services:
|
||||
backend:
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- "8001:8001" # Порт для FastAPI
|
||||
volumes:
|
||||
- ./db:/db # Монтирование базы данных
|
||||
|
||||
frontend:
|
||||
image: nginx:latest
|
||||
ports:
|
||||
- "8081:80" # Порт для фронтенда
|
||||
volumes:
|
||||
- ./frontend:/usr/share/nginx/html # Монтирование фронтенда
|
||||
|
||||
db:
|
||||
image: sqlite3:latest # Или используй существующий volume с rustdesk.db
|
||||
volumes:
|
||||
- ./db:/db
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Адресная книга подключений</title>
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<script src="https://cdn.datatables.net/1.11.5/js/jquery.dataTables.min.js"></script>
|
||||
<link rel="stylesheet" href="https://cdn.datatables.net/1.11.5/css/jquery.dataTables.min.css">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<script src="script.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Адресная книга подключений</h1>
|
||||
|
||||
<!-- Панель управления папками -->
|
||||
<div class="folder-controls">
|
||||
<h2>Управление папками</h2>
|
||||
<input type="text" id="folderName" placeholder="Имя папки">
|
||||
<select id="parentFolder">
|
||||
<option value="">Корневая папка</option>
|
||||
</select>
|
||||
<button onclick="createFolder()">Создать папку</button>
|
||||
<button onclick="editFolder()">Редактировать папку</button>
|
||||
<button onclick="deleteFolder()">Удалить папку</button>
|
||||
</div>
|
||||
|
||||
<!-- Форма для добавления подключения -->
|
||||
<div class="connection-controls">
|
||||
<h2>Добавить подключение</h2>
|
||||
<form id="addConnectionForm">
|
||||
<input type="text" id="connectionId" placeholder="ID подключения" required>
|
||||
<input type="text" id="connectionName" placeholder="Имя подключения" required>
|
||||
<select id="connectionType">
|
||||
<option value="RustDesk">RustDesk</option>
|
||||
<option value="SSH">SSH</option>
|
||||
<option value="RDP">RDP</option>
|
||||
</select>
|
||||
<select id="connectionFolder">
|
||||
<option value="">Без папки</option>
|
||||
</select>
|
||||
<button type="submit">Добавить</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Таблица подключений -->
|
||||
<table id="connectionsTable" class="display">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Connection ID</th>
|
||||
<th>Имя</th>
|
||||
<th>Тип</th>
|
||||
<th>Папка</th>
|
||||
<th>Действие</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,239 @@
|
|||
const API_URL = "http://localhost:8001/api";
|
||||
|
||||
$(document).ready(function () {
|
||||
loadFolders();
|
||||
loadConnections();
|
||||
|
||||
// Загрузка папок
|
||||
function loadFolders() {
|
||||
$.getJSON(`${API_URL}/folders`, function (folders) {
|
||||
$('#parentFolder, #connectionFolder').empty();
|
||||
$('#parentFolder, #connectionFolder').append('<option value="">Корневая папка</option>');
|
||||
folders.forEach(folder => {
|
||||
$('#parentFolder, #connectionFolder').append(
|
||||
`<option value="${folder.id}">${folder.name} (ID: ${folder.id})</option>`
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Загрузка подключений в таблицу
|
||||
function loadConnections() {
|
||||
$.getJSON(`${API_URL}/connections`, function (data) {
|
||||
let table = $('#connectionsTable').DataTable({
|
||||
"destroy": true,
|
||||
"data": data,
|
||||
"columns": [
|
||||
{ "data": "id" },
|
||||
{
|
||||
"data": "connection_id",
|
||||
"render": function (data, type, row) {
|
||||
if (row.type === "RustDesk") {
|
||||
return `<a href="rustdesk://${data}" onclick="openRustDesk('${data}'); return false;">${data}</a>`;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
},
|
||||
{ "data": "name" },
|
||||
{ "data": "type" },
|
||||
{
|
||||
"data": "folder_id",
|
||||
"render": function (data, type, row) {
|
||||
return data ? getFolderName(data) : "Без папки";
|
||||
}
|
||||
},
|
||||
{
|
||||
"data": "id",
|
||||
"render": function (data) {
|
||||
return `
|
||||
<button onclick="editConnection(${data})">Редактировать</button>
|
||||
<button onclick="deleteConnection(${data})">Удалить</button>
|
||||
<button onclick="moveConnection(${data})">Переместить</button>
|
||||
`;
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Получение имени папки по ID
|
||||
function getFolderName(folderId) {
|
||||
let folderName = "Без папки";
|
||||
$.ajax({
|
||||
url: `${API_URL}/folders/${folderId}`,
|
||||
async: false,
|
||||
success: function (folder) {
|
||||
folderName = folder.name;
|
||||
}
|
||||
});
|
||||
return folderName;
|
||||
}
|
||||
|
||||
// Создание папки
|
||||
window.createFolder = function () {
|
||||
let name = $('#folderName').val();
|
||||
let parentId = $('#parentFolder').val() || null;
|
||||
$.ajax({
|
||||
url: `${API_URL}/folders`,
|
||||
type: 'POST',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify({ name, parent_id: parentId }),
|
||||
success: function () {
|
||||
alert("Папка создана!");
|
||||
loadFolders();
|
||||
loadConnections();
|
||||
},
|
||||
error: function (xhr) {
|
||||
alert("Ошибка: " + xhr.responseJSON.detail);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Редактирование папки (пример, нужно уточнить UI)
|
||||
window.editFolder = function () {
|
||||
let folderId = prompt("Введите ID папки для редактирования:");
|
||||
if (folderId) {
|
||||
let name = prompt("Новое имя папки:");
|
||||
let parentId = prompt("ID родительской папки (оставьте пустым для корневой):") || null;
|
||||
$.ajax({
|
||||
url: `${API_URL}/folders/${folderId}`,
|
||||
type: 'PUT',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify({ name, parent_id: parentId }),
|
||||
success: function () {
|
||||
alert("Папка обновлена!");
|
||||
loadFolders();
|
||||
loadConnections();
|
||||
},
|
||||
error: function (xhr) {
|
||||
alert("Ошибка: " + xhr.responseJSON.detail);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Удаление папки
|
||||
window.deleteFolder = function () {
|
||||
let folderId = prompt("Введите ID папки для удаления:");
|
||||
if (folderId && confirm("Вы уверены?")) {
|
||||
$.ajax({
|
||||
url: `${API_URL}/folders/${folderId}`,
|
||||
type: 'DELETE',
|
||||
success: function () {
|
||||
alert("Папка удалена!");
|
||||
loadFolders();
|
||||
loadConnections();
|
||||
},
|
||||
error: function (xhr) {
|
||||
alert("Ошибка: " + xhr.responseJSON.detail);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Добавление подключения
|
||||
$('#addConnectionForm').submit(function (event) {
|
||||
event.preventDefault();
|
||||
let connectionId = $('#connectionId').val();
|
||||
let name = $('#connectionName').val();
|
||||
let type = $('#connectionType').val();
|
||||
let folderId = $('#connectionFolder').val() || null;
|
||||
|
||||
$.ajax({
|
||||
url: `${API_URL}/connections`,
|
||||
type: 'POST',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify({ connection_id: connectionId, name, type, folder_id: folderId }),
|
||||
success: function () {
|
||||
alert("Подключение добавлено!");
|
||||
loadConnections();
|
||||
$('#addConnectionForm')[0].reset();
|
||||
},
|
||||
error: function (xhr) {
|
||||
alert("Ошибка: " + xhr.responseJSON.detail);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Редактирование подключения
|
||||
window.editConnection = function (id) {
|
||||
let connection = promptConnectionDetails(id);
|
||||
if (connection) {
|
||||
$.ajax({
|
||||
url: `${API_URL}/connections/${id}`,
|
||||
type: 'PUT',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(connection),
|
||||
success: function () {
|
||||
alert("Подключение обновлено!");
|
||||
loadConnections();
|
||||
},
|
||||
error: function (xhr) {
|
||||
alert("Ошибка: " + xhr.responseJSON.detail);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Удаление подключения
|
||||
window.deleteConnection = function (id) {
|
||||
if (confirm("Вы уверены, что хотите удалить подключение?")) {
|
||||
$.ajax({
|
||||
url: `${API_URL}/connections/${id}`,
|
||||
type: 'DELETE',
|
||||
success: function () {
|
||||
alert("Подключение удалено!");
|
||||
loadConnections();
|
||||
},
|
||||
error: function (xhr) {
|
||||
alert("Ошибка: " + xhr.responseJSON.detail);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Перемещение подключения
|
||||
window.moveConnection = function (id) {
|
||||
let folderId = prompt("Введите ID папки для перемещения (оставьте пустым для корневой):") || null;
|
||||
$.ajax({
|
||||
url: `${API_URL}/connections/${id}`,
|
||||
type: 'PUT',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify({ folder_id: folderId }),
|
||||
success: function () {
|
||||
alert("Подключение перемещено!");
|
||||
loadConnections();
|
||||
},
|
||||
error: function (xhr) {
|
||||
alert("Ошибка: " + xhr.responseJSON.detail);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Функция для запроса деталей подключения через prompt (можно улучшить с модальным окном)
|
||||
function promptConnectionDetails(id) {
|
||||
let connectionId = prompt("Новый ID подключения:");
|
||||
let name = prompt("Новое имя подключения:");
|
||||
let type = prompt("Новый тип подключения (RustDesk, SSH, RDP):");
|
||||
let folderId = prompt("ID папки (оставьте пустым для корневой):") || null;
|
||||
if (connectionId && name && type) {
|
||||
return { connection_id: connectionId, name, type, folder_id: folderId };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Обработка клика по RustDesk ссылке
|
||||
window.openRustDesk = function(rustId) {
|
||||
if (confirm("Подключиться к устройству с ID " + rustId + "?")) {
|
||||
if (typeof navigator.msLaunchUri !== 'undefined') {
|
||||
navigator.msLaunchUri(`rustdesk://${rustId}`,
|
||||
function() { console.log("Успешно запущен RustDesk"); },
|
||||
function() { alert("Не удалось запустить RustDesk. Убедитесь, что RustDesk установлен и зарегистрирован для обработки rustdesk://."); }
|
||||
);
|
||||
} else {
|
||||
window.location.href = `rustdesk://${rustId}`;
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.folder-controls, .connection-controls {
|
||||
margin-bottom: 20px;
|
||||
padding: 10px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
input, select, button {
|
||||
margin: 5px;
|
||||
padding: 5px;
|
||||
}
|
||||
Loading…
Reference in New Issue