Todo 관리 시스템 및 공통 네비게이션 구현

- Todo CRUD 기능 구현 (TodoController, TodoModel)
- 서버 기반 공통 네비게이션 시스템 구축
- 모든 웹 페이지에 통일된 네비게이션 적용
- Todo 테이블 행 클릭으로 편집 모달 직접 접근 기능
- 네비게이션 메뉴 서버 설정 및 폴백 시스템

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
ChiKyun Kim
2025-07-28 14:15:08 +09:00
parent 0c5744c12c
commit e309864262
11 changed files with 2132 additions and 252 deletions

View File

@@ -0,0 +1,389 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web.Http;
using Newtonsoft.Json;
using FCOMMON;
using Project.Web.Model;
namespace Project.Web.Controllers
{
public class TodoController : BaseController
{
[HttpGet]
public HttpResponseMessage Index()
{
var filePath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Web", "wwwroot", "Todo", "index.html");
var contents = string.Empty;
if (System.IO.File.Exists(filePath))
{
contents = System.IO.File.ReadAllText(filePath, System.Text.Encoding.UTF8);
}
else
{
contents = "<html><body><h1>404 - File Not Found</h1><p>The requested file was not found: " + filePath + "</p></body></html>";
}
ApplyCommonValue(ref contents);
var resp = new HttpResponseMessage()
{
Content = new StringContent(
contents,
System.Text.Encoding.UTF8,
"text/html")
};
return resp;
}
[HttpGet]
public HttpResponseMessage GetTodos()
{
try
{
var currentUser = GetCurrentUser();
if (currentUser == null)
{
return CreateJsonResponse(new
{
Success = false,
Message = "로그인되지 않은 상태입니다."
});
}
string gcode = FCOMMON.info.Login.gcode;
string uid = FCOMMON.info.Login.no;
var sql = "SELECT * FROM EETGW_Todo WHERE gcode = @gcode AND uid = @uid ORDER BY flag DESC, seqno DESC, expire ASC, wdate ASC";
var todos = DBM.Query<TodoModel>(sql, new { gcode = gcode, uid = uid });
return CreateJsonResponse(new
{
Success = true,
Data = todos
});
}
catch (Exception ex)
{
return CreateJsonResponse(new
{
Success = false,
Message = "Todo 목록을 가져오는 중 오류가 발생했습니다: " + ex.Message
});
}
}
[HttpGet]
public HttpResponseMessage GetUrgentTodos()
{
try
{
var currentUser = GetCurrentUser();
if (currentUser == null)
{
return CreateJsonResponse(new
{
Success = false,
Message = "로그인되지 않은 상태입니다."
});
}
string gcode = FCOMMON.info.Login.gcode;
string uid = FCOMMON.info.Login.no;
var sql = @"
SELECT TOP 5 * FROM EETGW_Todo
WHERE gcode = @gcode AND uid = @uid
AND (expire IS NULL OR CAST(expire AS DATE) >= CAST(GETDATE() AS DATE))
ORDER BY flag DESC, seqno DESC, expire ASC, wdate ASC";
var todos = DBM.Query<TodoModel>(sql, new { gcode = gcode, uid = uid });
return CreateJsonResponse(new
{
Success = true,
Data = todos
});
}
catch (Exception ex)
{
return CreateJsonResponse(new
{
Success = false,
Message = "급한 Todo 목록을 가져오는 중 오류가 발생했습니다: " + ex.Message
});
}
}
[HttpPost]
public HttpResponseMessage CreateTodo([FromBody] TodoModel todo)
{
try
{
var currentUser = GetCurrentUser();
if (currentUser == null)
{
return CreateJsonResponse(new
{
Success = false,
Message = "로그인되지 않은 상태입니다."
});
}
if (string.IsNullOrEmpty(todo.remark))
{
return CreateJsonResponse(new
{
Success = false,
Message = "할일 내용은 필수입니다."
});
}
todo.gcode = FCOMMON.info.Login.gcode;
todo.uid = FCOMMON.info.Login.no;
todo.wuid = FCOMMON.info.Login.no;
todo.wdate = DateTime.Now;
if (todo.seqno == null) todo.seqno = 0;
if (todo.flag == null) todo.flag = false;
var sql = @"
INSERT INTO EETGW_Todo (gcode, uid, title, remark, flag, expire, seqno, request, wuid, wdate)
VALUES (@gcode, @uid, @title, @remark, @flag, @expire, @seqno, @request, @wuid, @wdate);
SELECT SCOPE_IDENTITY();";
var newId = DBM.QuerySingle<int>(sql, todo);
return CreateJsonResponse(new
{
Success = true,
Message = "할일이 추가되었습니다.",
Data = new { idx = newId }
});
}
catch (Exception ex)
{
return CreateJsonResponse(new
{
Success = false,
Message = "할일 추가 중 오류가 발생했습니다: " + ex.Message
});
}
}
[HttpPut]
public HttpResponseMessage UpdateTodo([FromBody] TodoModel todo)
{
try
{
var currentUser = GetCurrentUser();
if (currentUser == null)
{
return CreateJsonResponse(new
{
Success = false,
Message = "로그인되지 않은 상태입니다."
});
}
if (todo.idx <= 0)
{
return CreateJsonResponse(new
{
Success = false,
Message = "유효하지 않은 Todo ID입니다."
});
}
if (string.IsNullOrEmpty(todo.remark))
{
return CreateJsonResponse(new
{
Success = false,
Message = "할일 내용은 필수입니다."
});
}
string gcode = FCOMMON.info.Login.gcode;
string uid = FCOMMON.info.Login.no;
var sql = @"
UPDATE EETGW_Todo
SET title = @title, remark = @remark, flag = @flag, expire = @expire, seqno = @seqno, request = @request
WHERE idx = @idx AND gcode = @gcode AND uid = @uid";
var affectedRows = DBM.Execute(sql, new
{
title = todo.title,
remark = todo.remark,
flag = todo.flag ?? false,
expire = todo.expire,
seqno = todo.seqno ?? 0,
request = todo.request,
idx = todo.idx,
gcode = gcode,
uid = uid
});
if (affectedRows == 0)
{
return CreateJsonResponse(new
{
Success = false,
Message = "수정할 할일을 찾을 수 없습니다."
});
}
return CreateJsonResponse(new
{
Success = true,
Message = "할일이 수정되었습니다."
});
}
catch (Exception ex)
{
return CreateJsonResponse(new
{
Success = false,
Message = "할일 수정 중 오류가 발생했습니다: " + ex.Message
});
}
}
[HttpDelete]
public HttpResponseMessage DeleteTodo(int id)
{
try
{
var currentUser = GetCurrentUser();
if (currentUser == null)
{
return CreateJsonResponse(new
{
Success = false,
Message = "로그인되지 않은 상태입니다."
});
}
if (id <= 0)
{
return CreateJsonResponse(new
{
Success = false,
Message = "유효하지 않은 Todo ID입니다."
});
}
string gcode = FCOMMON.info.Login.gcode;
string uid = FCOMMON.info.Login.no;
var sql = "DELETE FROM EETGW_Todo WHERE idx = @idx AND gcode = @gcode AND uid = @uid";
var affectedRows = DBM.Execute(sql, new { idx = id, gcode = gcode, uid = uid });
if (affectedRows == 0)
{
return CreateJsonResponse(new
{
Success = false,
Message = "삭제할 할일을 찾을 수 없습니다."
});
}
return CreateJsonResponse(new
{
Success = true,
Message = "할일이 삭제되었습니다."
});
}
catch (Exception ex)
{
return CreateJsonResponse(new
{
Success = false,
Message = "할일 삭제 중 오류가 발생했습니다: " + ex.Message
});
}
}
[HttpGet]
public HttpResponseMessage GetTodo(int id)
{
try
{
var currentUser = GetCurrentUser();
if (currentUser == null)
{
return CreateJsonResponse(new
{
Success = false,
Message = "로그인되지 않은 상태입니다."
});
}
if (id <= 0)
{
return CreateJsonResponse(new
{
Success = false,
Message = "유효하지 않은 Todo ID입니다."
});
}
string gcode = FCOMMON.info.Login.gcode;
string uid = FCOMMON.info.Login.no;
var sql = "SELECT * FROM EETGW_Todo WHERE idx = @idx AND gcode = @gcode AND uid = @uid";
var todo = DBM.QuerySingleOrDefault<TodoModel>(sql, new { idx = id, gcode = gcode, uid = uid });
if (todo == null)
{
return CreateJsonResponse(new
{
Success = false,
Message = "할일을 찾을 수 없습니다."
});
}
return CreateJsonResponse(new
{
Success = true,
Data = todo
});
}
catch (Exception ex)
{
return CreateJsonResponse(new
{
Success = false,
Message = "할일 조회 중 오류가 발생했습니다: " + ex.Message
});
}
}
private object GetCurrentUser()
{
if (string.IsNullOrEmpty(FCOMMON.info.Login.no)) return null;
else return FCOMMON.info.Login;
}
private HttpResponseMessage CreateJsonResponse(object data)
{
var json = JsonConvert.SerializeObject(data, new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
DateFormatString = "yyyy-MM-dd HH:mm:ss"
});
return new HttpResponseMessage()
{
Content = new StringContent(
json,
System.Text.Encoding.UTF8,
"application/json")
};
}
}
}