1.0
This commit is contained in:
@@ -122,7 +122,7 @@ namespace VNCServerList.Services
|
|||||||
connection.Open();
|
connection.Open();
|
||||||
string sql = @"
|
string sql = @"
|
||||||
INSERT INTO VNC_ServerList ([User], [IP], [Category], [Title],[Description], [Password], [Argument])
|
INSERT INTO VNC_ServerList ([User], [IP], [Category], [Title],[Description], [Password], [Argument])
|
||||||
VALUES (@User, @IP, @Category, @Description, @Password, @Argument)";
|
VALUES (@User, @IP, @Category, @Title,@Description, @Password, @Argument)";
|
||||||
|
|
||||||
using (var command = new SqlCommand(sql, connection))
|
using (var command = new SqlCommand(sql, connection))
|
||||||
{
|
{
|
||||||
@@ -165,6 +165,33 @@ namespace VNCServerList.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool UpdateServerByUserAndIP(string originalUser, string originalIp, VNCServer newServerData)
|
||||||
|
{
|
||||||
|
using (var connection = new SqlConnection(_connectionString))
|
||||||
|
{
|
||||||
|
connection.Open();
|
||||||
|
string sql = @"
|
||||||
|
UPDATE VNC_ServerList
|
||||||
|
SET [IP] = @NewIP, [Category] = @Category, [Title] = @Title, [Description] = @Description,
|
||||||
|
[Password] = @Password, [Argument] = @Argument
|
||||||
|
WHERE [User] = @User AND [IP] = @OriginalIP";
|
||||||
|
|
||||||
|
using (var command = new SqlCommand(sql, connection))
|
||||||
|
{
|
||||||
|
command.Parameters.AddWithValue("@User", originalUser);
|
||||||
|
command.Parameters.AddWithValue("@OriginalIP", originalIp);
|
||||||
|
command.Parameters.AddWithValue("@NewIP", newServerData.IP);
|
||||||
|
command.Parameters.AddWithValue("@Category", (object)newServerData.Category ?? DBNull.Value);
|
||||||
|
command.Parameters.AddWithValue("@Title", (object)newServerData.Title ?? DBNull.Value);
|
||||||
|
command.Parameters.AddWithValue("@Description", (object)newServerData.Description ?? DBNull.Value);
|
||||||
|
command.Parameters.AddWithValue("@Password", (object)newServerData.Password ?? DBNull.Value);
|
||||||
|
command.Parameters.AddWithValue("@Argument", (object)newServerData.Argument ?? DBNull.Value);
|
||||||
|
|
||||||
|
return command.ExecuteNonQuery() > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool DeleteServer(string user, string ip)
|
public bool DeleteServer(string user, string ip)
|
||||||
{
|
{
|
||||||
using (var connection = new SqlConnection(_connectionString))
|
using (var connection = new SqlConnection(_connectionString))
|
||||||
|
|||||||
@@ -92,8 +92,8 @@ namespace VNCServerList.Web.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpPut]
|
[HttpPut]
|
||||||
[Route("update")]
|
[Route("update/{originalUser}/{originalIp}")]
|
||||||
public IHttpActionResult UpdateServer([FromBody] VNCServer server)
|
public IHttpActionResult UpdateServer(string originalUser, string originalIp, [FromBody] VNCServer server)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -102,7 +102,8 @@ namespace VNCServerList.Web.Controllers
|
|||||||
return BadRequest("서버 정보가 없습니다.");
|
return BadRequest("서버 정보가 없습니다.");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool success = _databaseService.UpdateServer(server);
|
// 원본 사용자명과 IP로 서버를 찾아서 업데이트
|
||||||
|
bool success = _databaseService.UpdateServerByUserAndIP(originalUser, originalIp, server);
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
return Ok(new { Message = "서버가 성공적으로 업데이트되었습니다." });
|
return Ok(new { Message = "서버가 성공적으로 업데이트되었습니다." });
|
||||||
@@ -171,7 +172,8 @@ namespace VNCServerList.Web.Controllers
|
|||||||
bool isInstalled = _vncService.IsVNCViewerInstalled();
|
bool isInstalled = _vncService.IsVNCViewerInstalled();
|
||||||
string path = _vncService.GetVNCViewerPath();
|
string path = _vncService.GetVNCViewerPath();
|
||||||
|
|
||||||
return Ok(new {
|
return Ok(new
|
||||||
|
{
|
||||||
IsInstalled = isInstalled,
|
IsInstalled = isInstalled,
|
||||||
Path = path
|
Path = path
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -63,34 +63,37 @@
|
|||||||
<h3 id="modalTitle" class="text-lg font-semibold text-gray-800">서버 추가</h3>
|
<h3 id="modalTitle" class="text-lg font-semibold text-gray-800">서버 추가</h3>
|
||||||
</div>
|
</div>
|
||||||
<form id="serverForm" class="p-6">
|
<form id="serverForm" class="p-6">
|
||||||
<div class="mb-4">
|
<div class="grid grid-cols-2 gap-4 mb-4">
|
||||||
<label for="serverUser" class="block text-sm font-medium text-gray-700 mb-2">사용자</label>
|
<div>
|
||||||
<input type="text" id="serverUser" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" required>
|
|
||||||
</div>
|
|
||||||
<div class="mb-4">
|
|
||||||
<label for="serverIp" class="block text-sm font-medium text-gray-700 mb-2">IP 주소</label>
|
<label for="serverIp" class="block text-sm font-medium text-gray-700 mb-2">IP 주소</label>
|
||||||
<input type="text" id="serverIp" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" required>
|
<input type="text" id="serverIp" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
<div>
|
||||||
<label for="serverCategory" class="block text-sm font-medium text-gray-700 mb-2">카테고리</label>
|
<label for="serverPassword" class="block text-sm font-medium text-gray-700 mb-2">비밀번호</label>
|
||||||
<input type="text" id="serverCategory" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent">
|
<input type="password" id="serverPassword" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label for="serverTitle" class="block text-sm font-medium text-gray-700 mb-2">제목</label>
|
<label for="serverTitle" class="block text-sm font-medium text-gray-700 mb-2">제목</label>
|
||||||
<input type="text" id="serverTitle" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent">
|
<input type="text" id="serverTitle" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="grid grid-cols-2 gap-4 mb-4">
|
||||||
|
<div >
|
||||||
|
<label for="serverCategory" class="block text-sm font-medium text-gray-700 mb-2">카테고리</label>
|
||||||
|
<input type="text" id="serverCategory" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent">
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label for="serverArgument" class="block text-sm font-medium text-gray-700 mb-2">VNC 인수</label>
|
||||||
|
<input type="text" id="serverArgument" placeholder="-port=5900" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<label for="serverDescription" class="block text-sm font-medium text-gray-700 mb-2">설명</label>
|
<label for="serverDescription" class="block text-sm font-medium text-gray-700 mb-2">설명</label>
|
||||||
<textarea id="serverDescription" rows="2" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent"></textarea>
|
<textarea id="serverDescription" rows="2" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent"></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-4">
|
|
||||||
<label for="serverPassword" class="block text-sm font-medium text-gray-700 mb-2">비밀번호</label>
|
|
||||||
<input type="password" id="serverPassword" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent">
|
|
||||||
</div>
|
|
||||||
<div class="mb-6">
|
|
||||||
<label for="serverArgument" class="block text-sm font-medium text-gray-700 mb-2">VNC 인수</label>
|
|
||||||
<input type="text" id="serverArgument" placeholder="-port=5900" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent">
|
|
||||||
</div>
|
|
||||||
<div class="flex justify-end space-x-3">
|
<div class="flex justify-end space-x-3">
|
||||||
<button type="button" id="cancelBtn" class="px-4 py-2 text-gray-700 bg-gray-200 rounded-md hover:bg-gray-300 transition duration-200">취소</button>
|
<button type="button" id="cancelBtn" class="px-4 py-2 text-gray-700 bg-gray-200 rounded-md hover:bg-gray-300 transition duration-200">취소</button>
|
||||||
<button type="submit" class="px-4 py-2 bg-primary text-white rounded-md hover:bg-blue-700 transition duration-200">저장</button>
|
<button type="submit" class="px-4 py-2 bg-primary text-white rounded-md hover:bg-blue-700 transition duration-200">저장</button>
|
||||||
|
|||||||
@@ -206,18 +206,28 @@ class VNCServerApp {
|
|||||||
const title = document.getElementById('modalTitle');
|
const title = document.getElementById('modalTitle');
|
||||||
const form = document.getElementById('serverForm');
|
const form = document.getElementById('serverForm');
|
||||||
|
|
||||||
|
console.log('서버 정보2:', server); // 디버깅용
|
||||||
|
|
||||||
|
|
||||||
if (server) {
|
if (server) {
|
||||||
title.textContent = '서버 편집';
|
title.textContent = '서버 편집';
|
||||||
document.getElementById('serverUser').value = server.user;
|
document.getElementById('serverIp').value = server.IP;
|
||||||
document.getElementById('serverIp').value = server.ip;
|
document.getElementById('serverCategory').value = server.Category || '';
|
||||||
document.getElementById('serverCategory').value = server.category || '';
|
document.getElementById('serverTitle').value = server.Title || '';
|
||||||
document.getElementById('serverTitle').value = server.title || '';
|
document.getElementById('serverDescription').value = server.Description || '';
|
||||||
document.getElementById('serverDescription').value = server.description || '';
|
document.getElementById('serverPassword').value = server.Password || '';
|
||||||
document.getElementById('serverPassword').value = server.password || '';
|
document.getElementById('serverArgument').value = server.Argument || '';
|
||||||
document.getElementById('serverArgument').value = server.argument || '';
|
// 편집 모드 플래그 설정
|
||||||
|
modal.dataset.editMode = 'true';
|
||||||
|
modal.dataset.editUser = server.User;
|
||||||
|
modal.dataset.editIp = server.IP;
|
||||||
} else {
|
} else {
|
||||||
title.textContent = '서버 추가';
|
title.textContent = '서버 추가';
|
||||||
form.reset();
|
form.reset();
|
||||||
|
// 추가 모드 플래그 설정
|
||||||
|
modal.dataset.editMode = 'false';
|
||||||
|
delete modal.dataset.editUser;
|
||||||
|
delete modal.dataset.editIp;
|
||||||
}
|
}
|
||||||
|
|
||||||
modal.classList.remove('hidden');
|
modal.classList.remove('hidden');
|
||||||
@@ -346,10 +356,18 @@ class VNCServerApp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async saveServer() {
|
async saveServer() {
|
||||||
const serverUser = document.getElementById('serverUser').value;
|
|
||||||
const serverIp = document.getElementById('serverIp').value;
|
const serverIp = document.getElementById('serverIp').value;
|
||||||
|
const userName = document.getElementById('userName')?.value || '';
|
||||||
|
const modal = document.getElementById('serverModal');
|
||||||
|
const isEditMode = modal.dataset.editMode === 'true';
|
||||||
|
|
||||||
|
if (!userName) {
|
||||||
|
this.showError('사용자 이름이 설정되지 않았습니다. 먼저 설정에서 사용자 이름을 입력해주세요.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const serverData = {
|
const serverData = {
|
||||||
user: serverUser,
|
user: userName,
|
||||||
ip: serverIp,
|
ip: serverIp,
|
||||||
category: document.getElementById('serverCategory').value,
|
category: document.getElementById('serverCategory').value,
|
||||||
title: document.getElementById('serverTitle').value,
|
title: document.getElementById('serverTitle').value,
|
||||||
@@ -359,8 +377,19 @@ class VNCServerApp {
|
|||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const url = serverUser && serverIp ? `${this.apiBase}/update` : `${this.apiBase}/add`;
|
let url, method;
|
||||||
const method = serverUser && serverIp ? 'PUT' : 'POST';
|
|
||||||
|
if (isEditMode) {
|
||||||
|
// 편집 모드: 원본 사용자명과 IP를 쿼리 파라미터로 전달
|
||||||
|
const originalUser = modal.dataset.editUser;
|
||||||
|
const originalIp = modal.dataset.editIp;
|
||||||
|
url = `${this.apiBase}/update/${encodeURIComponent(originalUser)}/${encodeURIComponent(originalIp)}`;
|
||||||
|
method = 'PUT';
|
||||||
|
} else {
|
||||||
|
// 추가 모드
|
||||||
|
url = `${this.apiBase}/add`;
|
||||||
|
method = 'POST';
|
||||||
|
}
|
||||||
|
|
||||||
const response = await fetch(url, {
|
const response = await fetch(url, {
|
||||||
method: method,
|
method: method,
|
||||||
@@ -382,13 +411,16 @@ class VNCServerApp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async editServer(user, ip) {
|
async editServer(user, ip) {
|
||||||
|
console.log('편집 서버 호출:', { user, ip }); // 디버깅용
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`${this.apiBase}/get/${encodeURIComponent(user)}/${encodeURIComponent(ip)}`);
|
const response = await fetch(`${this.apiBase}/get/${encodeURIComponent(user)}/${encodeURIComponent(ip)}`);
|
||||||
if (!response.ok) throw new Error('서버 정보를 불러올 수 없습니다.');
|
if (!response.ok) throw new Error('서버 정보를 불러올 수 없습니다.');
|
||||||
|
|
||||||
const server = await response.json();
|
const server = await response.json();
|
||||||
|
console.log('서버 정보:', server); // 디버깅용
|
||||||
this.showServerModal(server);
|
this.showServerModal(server);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.error('편집 서버 오류:', error); // 디버깅용
|
||||||
this.showError('서버 정보를 불러오는 중 오류가 발생했습니다: ' + error.message);
|
this.showError('서버 정보를 불러오는 중 오류가 발생했습니다: ' + error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -533,6 +565,7 @@ class VNCServerApp {
|
|||||||
// 서버 목록 렌더링
|
// 서버 목록 렌더링
|
||||||
if (hasServers) {
|
if (hasServers) {
|
||||||
categoryData.servers.forEach(server => {
|
categoryData.servers.forEach(server => {
|
||||||
|
console.log('서버 데이터:', server); // 디버깅용
|
||||||
const serverData = {
|
const serverData = {
|
||||||
serverName: `${server.User || server.user}@${server.Title || server.title}`,
|
serverName: `${server.User || server.user}@${server.Title || server.title}`,
|
||||||
userName: server.User || server.user,
|
userName: server.User || server.user,
|
||||||
@@ -542,6 +575,7 @@ class VNCServerApp {
|
|||||||
serverDescription: server.Description || server.description,
|
serverDescription: server.Description || server.description,
|
||||||
serverArgument: server.Argument || server.argument
|
serverArgument: server.Argument || server.argument
|
||||||
};
|
};
|
||||||
|
console.log('렌더링할 서버 데이터:', serverData); // 디버깅용
|
||||||
html += this.renderTemplate('serverItemTemplate', serverData);
|
html += this.renderTemplate('serverItemTemplate', serverData);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user