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:
@@ -333,6 +333,82 @@ namespace Project.Web.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public HttpResponseMessage GetNavigationMenu()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 메뉴 정보를 하드코딩하거나 데이터베이스에서 가져올 수 있습니다.
|
||||
// 향후 사용자 권한에 따른 메뉴 표시/숨김 기능도 추가 가능합니다.
|
||||
var menuItems = new[]
|
||||
{
|
||||
new {
|
||||
key = "dashboard",
|
||||
title = "대시보드",
|
||||
url = "/Dashboard/",
|
||||
icon = "M3 7v10a2 2 0 002 2h14a2 2 0 002-2V9a2 2 0 00-2-2H5a2 2 0 00-2-2z M8 5a2 2 0 012-2h4a2 2 0 012 2v2H8V5z",
|
||||
isVisible = true,
|
||||
sortOrder = 1
|
||||
},
|
||||
new {
|
||||
key = "common",
|
||||
title = "공용코드",
|
||||
url = "/Common",
|
||||
icon = "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z",
|
||||
isVisible = true,
|
||||
sortOrder = 2
|
||||
},
|
||||
new {
|
||||
key = "jobreport",
|
||||
title = "업무일지",
|
||||
url = "/Jobreport/",
|
||||
icon = "M9 5H7a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2",
|
||||
isVisible = true,
|
||||
sortOrder = 3
|
||||
},
|
||||
new {
|
||||
key = "kuntae",
|
||||
title = "근태관리",
|
||||
url = "/Kuntae/",
|
||||
icon = "M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z",
|
||||
isVisible = true,
|
||||
sortOrder = 4
|
||||
},
|
||||
new {
|
||||
key = "todo",
|
||||
title = "할일관리",
|
||||
url = "/Todo/",
|
||||
icon = "M9 5H7a2 2 0 00-2 2v10a2 2 0 002 2h8a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2M12 12l2 2 4-4",
|
||||
isVisible = true,
|
||||
sortOrder = 5
|
||||
}
|
||||
};
|
||||
|
||||
// 사용자 권한에 따른 메뉴 필터링 로직을 여기에 추가할 수 있습니다.
|
||||
// 예: var userLevel = FCOMMON.info.Login.level;
|
||||
// if (userLevel < 5) { /* 특정 메뉴 숨김 */ }
|
||||
|
||||
var response = new
|
||||
{
|
||||
Success = true,
|
||||
Data = menuItems,
|
||||
Message = "메뉴 정보를 성공적으로 가져왔습니다."
|
||||
};
|
||||
|
||||
return CreateJsonResponse(response);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var response = new
|
||||
{
|
||||
Success = false,
|
||||
Data = (object)null,
|
||||
Message = "메뉴 정보를 가져오는 중 오류가 발생했습니다: " + ex.Message
|
||||
};
|
||||
return CreateJsonResponse(response);
|
||||
}
|
||||
}
|
||||
|
||||
private HttpResponseMessage CreateJsonResponse(object data)
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(data, new JsonSerializerSettings
|
||||
|
||||
389
Project/Web/Controller/TodoController.cs
Normal file
389
Project/Web/Controller/TodoController.cs
Normal 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")
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user