- Todo CRUD 기능 구현 (TodoController, TodoModel) - 서버 기반 공통 네비게이션 시스템 구축 - 모든 웹 페이지에 통일된 네비게이션 적용 - Todo 테이블 행 클릭으로 편집 모달 직접 접근 기능 - 네비게이션 메뉴 서버 설정 및 폴백 시스템 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
454 lines
17 KiB
C#
454 lines
17 KiB
C#
using FCM0000;
|
|
using Microsoft.Owin;
|
|
using Newtonsoft.Json;
|
|
using System;
|
|
using System.Linq;
|
|
using System.Net.Http;
|
|
using System.Web;
|
|
using System.Web.Http;
|
|
|
|
namespace Project.Web.Controllers
|
|
{
|
|
public class CommonController : BaseController
|
|
{
|
|
[HttpGet]
|
|
public HttpResponseMessage GetList(string grp=null)
|
|
{
|
|
var sql = string.Empty;
|
|
|
|
if (string.IsNullOrEmpty(grp))
|
|
{
|
|
// grp가 없으면 모든 그룹의 데이터를 가져옴
|
|
sql = "select *" +
|
|
" from common" +
|
|
" where gcode = @gcode" +
|
|
" order by grp, code, svalue";
|
|
}
|
|
else
|
|
{
|
|
// 특정 그룹의 데이터만 가져옴
|
|
sql = "select *" +
|
|
" from common" +
|
|
" where gcode = @gcode" +
|
|
" and grp = @grp" +
|
|
" order by code,svalue";
|
|
}
|
|
|
|
var cs = Properties.Settings.Default.gwcs;
|
|
var cn = new System.Data.SqlClient.SqlConnection(cs);
|
|
var cmd = new System.Data.SqlClient.SqlCommand(sql, cn);
|
|
cmd.Parameters.AddWithValue("gcode", FCOMMON.info.Login.gcode);
|
|
|
|
if (!string.IsNullOrEmpty(grp))
|
|
{
|
|
cmd.Parameters.AddWithValue("grp", grp);
|
|
}
|
|
|
|
var da = new System.Data.SqlClient.SqlDataAdapter(cmd);
|
|
var dt = new System.Data.DataTable();
|
|
da.Fill(dt);
|
|
da.Dispose();
|
|
cmd.Dispose();
|
|
cn.Dispose();
|
|
|
|
var txtjson = JsonConvert.SerializeObject(dt, new JsonSerializerSettings
|
|
{
|
|
NullValueHandling = NullValueHandling.Ignore
|
|
});
|
|
|
|
var resp = new HttpResponseMessage()
|
|
{
|
|
Content = new StringContent(
|
|
txtjson,
|
|
System.Text.Encoding.UTF8,
|
|
"application/json")
|
|
};
|
|
|
|
return resp;
|
|
}
|
|
|
|
|
|
[HttpGet]
|
|
public HttpResponseMessage Index()
|
|
{
|
|
// 직접 파일을 읽어서 반환
|
|
var filePath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Web", "wwwroot", "Common.html");
|
|
var contents = string.Empty;
|
|
|
|
if (System.IO.File.Exists(filePath))
|
|
{
|
|
contents = System.IO.File.ReadAllText(filePath, System.Text.Encoding.UTF8);
|
|
}
|
|
else
|
|
{
|
|
// 파일이 없으면 404 에러 페이지 또는 기본 메시지
|
|
contents = "<html><body><h1>404 - File Not Found</h1><p>The requested file was not found: " + filePath + "</p></body></html>";
|
|
}
|
|
|
|
|
|
var resp = new HttpResponseMessage()
|
|
{
|
|
Content = new StringContent(
|
|
contents,
|
|
System.Text.Encoding.UTF8,
|
|
"text/html")
|
|
};
|
|
|
|
return resp;
|
|
}
|
|
|
|
[HttpPost]
|
|
public HttpResponseMessage Save([FromBody] CommonModel model)
|
|
{
|
|
try
|
|
{
|
|
var cs = Properties.Settings.Default.gwcs;
|
|
var cn = new System.Data.SqlClient.SqlConnection(cs);
|
|
var sql = string.Empty;
|
|
var cmd = new System.Data.SqlClient.SqlCommand();
|
|
cmd.Connection = cn;
|
|
|
|
if (model.idx > 0)
|
|
{
|
|
// 업데이트
|
|
sql = @"UPDATE common SET
|
|
grp = @grp,
|
|
code = @code,
|
|
svalue = @svalue,
|
|
ivalue = @ivalue,
|
|
fvalue = @fvalue,
|
|
svalue2 = @svalue2,
|
|
memo = @memo,
|
|
wuid = @wuid,
|
|
wdate = GETDATE()
|
|
WHERE idx = @idx AND gcode = @gcode";
|
|
}
|
|
else
|
|
{
|
|
// 신규 추가
|
|
sql = @"INSERT INTO common (gcode, grp, code, svalue, ivalue, fvalue, svalue2, memo, wuid, wdate)
|
|
VALUES (@gcode, @grp, @code, @svalue, @ivalue, @fvalue, @svalue2, @memo, @wuid, GETDATE())";
|
|
}
|
|
|
|
cmd.CommandText = sql;
|
|
cmd.Parameters.AddWithValue("@gcode", FCOMMON.info.Login.gcode);
|
|
cmd.Parameters.AddWithValue("@grp", model.grp ?? "");
|
|
cmd.Parameters.AddWithValue("@code", model.code ?? "");
|
|
cmd.Parameters.AddWithValue("@svalue", model.svalue ?? "");
|
|
cmd.Parameters.AddWithValue("@ivalue", model.ivalue);
|
|
cmd.Parameters.AddWithValue("@fvalue", model.fvalue);
|
|
cmd.Parameters.AddWithValue("@svalue2", model.svalue2 ?? "");
|
|
cmd.Parameters.AddWithValue("@memo", model.memo ?? "");
|
|
cmd.Parameters.AddWithValue("@wuid", FCOMMON.info.Login.no);
|
|
|
|
if (model.idx > 0)
|
|
{
|
|
cmd.Parameters.AddWithValue("@idx", model.idx);
|
|
}
|
|
|
|
cn.Open();
|
|
var result = cmd.ExecuteNonQuery();
|
|
cn.Close();
|
|
|
|
cmd.Dispose();
|
|
cn.Dispose();
|
|
|
|
var response = new
|
|
{
|
|
Success = result > 0,
|
|
Message = result > 0 ? "저장되었습니다." : "저장에 실패했습니다."
|
|
};
|
|
|
|
return CreateJsonResponse(response);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
var response = new
|
|
{
|
|
Success = false,
|
|
Message = "오류가 발생했습니다: " + ex.Message
|
|
};
|
|
return CreateJsonResponse(response);
|
|
}
|
|
}
|
|
|
|
[HttpPost]
|
|
public HttpResponseMessage Delete([FromBody] DeleteModel model)
|
|
{
|
|
try
|
|
{
|
|
var cs = Properties.Settings.Default.gwcs;
|
|
var cn = new System.Data.SqlClient.SqlConnection(cs);
|
|
var sql = "DELETE FROM common WHERE idx = @idx AND gcode = @gcode";
|
|
var cmd = new System.Data.SqlClient.SqlCommand(sql, cn);
|
|
|
|
cmd.Parameters.AddWithValue("@idx", model.idx);
|
|
cmd.Parameters.AddWithValue("@gcode", FCOMMON.info.Login.gcode);
|
|
|
|
cn.Open();
|
|
var result = cmd.ExecuteNonQuery();
|
|
cn.Close();
|
|
|
|
cmd.Dispose();
|
|
cn.Dispose();
|
|
|
|
var response = new
|
|
{
|
|
Success = result > 0,
|
|
Message = result > 0 ? "삭제되었습니다." : "삭제에 실패했습니다."
|
|
};
|
|
|
|
return CreateJsonResponse(response);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
var response = new
|
|
{
|
|
Success = false,
|
|
Message = "오류가 발생했습니다: " + ex.Message
|
|
};
|
|
return CreateJsonResponse(response);
|
|
}
|
|
}
|
|
|
|
[HttpGet]
|
|
public HttpResponseMessage GetGroups()
|
|
{
|
|
try
|
|
{
|
|
var sql = "select code, svalue from common WITH (nolock) " +
|
|
"where gcode = @gcode and grp = '99' " +
|
|
"order by code";
|
|
|
|
var cs = Properties.Settings.Default.gwcs;
|
|
var cn = new System.Data.SqlClient.SqlConnection(cs);
|
|
var cmd = new System.Data.SqlClient.SqlCommand(sql, cn);
|
|
cmd.Parameters.AddWithValue("@gcode", FCOMMON.info.Login.gcode);
|
|
|
|
var da = new System.Data.SqlClient.SqlDataAdapter(cmd);
|
|
var dt = new System.Data.DataTable();
|
|
da.Fill(dt);
|
|
da.Dispose();
|
|
cmd.Dispose();
|
|
cn.Dispose();
|
|
|
|
var txtjson = JsonConvert.SerializeObject(dt, new JsonSerializerSettings
|
|
{
|
|
NullValueHandling = NullValueHandling.Ignore
|
|
});
|
|
|
|
var resp = new HttpResponseMessage()
|
|
{
|
|
Content = new StringContent(
|
|
txtjson,
|
|
System.Text.Encoding.UTF8,
|
|
"application/json")
|
|
};
|
|
|
|
return resp;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
var response = new
|
|
{
|
|
Message = ex.Message,
|
|
};
|
|
return CreateJsonResponse(response);
|
|
}
|
|
}
|
|
|
|
[HttpPost]
|
|
public HttpResponseMessage InitializeGroups()
|
|
{
|
|
try
|
|
{
|
|
var cs = Properties.Settings.Default.gwcs;
|
|
var cn = new System.Data.SqlClient.SqlConnection(cs);
|
|
|
|
// 기본 그룹코드들 정의
|
|
var defaultGroups = new[]
|
|
{
|
|
new { code = "01", svalue = "부서코드" },
|
|
new { code = "02", svalue = "직급코드" },
|
|
new { code = "03", svalue = "공정코드" },
|
|
new { code = "04", svalue = "품목분류" },
|
|
new { code = "05", svalue = "업체분류" },
|
|
new { code = "06", svalue = "제조공정" },
|
|
new { code = "07", svalue = "장비제조" },
|
|
new { code = "08", svalue = "장비모델" },
|
|
new { code = "09", svalue = "장비기술" },
|
|
new { code = "99", svalue = "기타" }
|
|
};
|
|
|
|
cn.Open();
|
|
|
|
int insertedCount = 0;
|
|
foreach (var group in defaultGroups)
|
|
{
|
|
// 이미 존재하는지 확인
|
|
var checkSql = "SELECT COUNT(*) FROM common WHERE gcode = @gcode AND grp = '99' AND code = @code";
|
|
var checkCmd = new System.Data.SqlClient.SqlCommand(checkSql, cn);
|
|
checkCmd.Parameters.AddWithValue("@gcode", FCOMMON.info.Login.gcode);
|
|
checkCmd.Parameters.AddWithValue("@code", group.code);
|
|
|
|
var exists = (int)checkCmd.ExecuteScalar() > 0;
|
|
checkCmd.Dispose();
|
|
|
|
if (!exists)
|
|
{
|
|
// 새로 추가
|
|
var insertSql = @"INSERT INTO common (gcode, grp, code, svalue, ivalue, fvalue, svalue2, memo, wuid, wdate)
|
|
VALUES (@gcode, '99', @code, @svalue, 0, 0.0, '', '코드그룹 정의', @wuid, GETDATE())";
|
|
var insertCmd = new System.Data.SqlClient.SqlCommand(insertSql, cn);
|
|
insertCmd.Parameters.AddWithValue("@gcode", FCOMMON.info.Login.gcode);
|
|
insertCmd.Parameters.AddWithValue("@code", group.code);
|
|
insertCmd.Parameters.AddWithValue("@svalue", group.svalue);
|
|
insertCmd.Parameters.AddWithValue("@wuid", FCOMMON.info.Login.no);
|
|
|
|
insertCmd.ExecuteNonQuery();
|
|
insertCmd.Dispose();
|
|
insertedCount++;
|
|
}
|
|
}
|
|
|
|
cn.Close();
|
|
cn.Dispose();
|
|
|
|
var response = new
|
|
{
|
|
Success = true,
|
|
Message = $"그룹코드 초기화 완료. {insertedCount}개 추가됨."
|
|
};
|
|
|
|
return CreateJsonResponse(response);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
var response = new
|
|
{
|
|
Success = false,
|
|
Message = "오류가 발생했습니다: " + ex.Message
|
|
};
|
|
return CreateJsonResponse(response);
|
|
}
|
|
}
|
|
|
|
[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
|
|
{
|
|
NullValueHandling = NullValueHandling.Ignore
|
|
});
|
|
|
|
return new HttpResponseMessage()
|
|
{
|
|
Content = new StringContent(
|
|
json,
|
|
System.Text.Encoding.UTF8,
|
|
"application/json")
|
|
};
|
|
}
|
|
}
|
|
|
|
public class DeleteModel
|
|
{
|
|
public int idx { get; set; }
|
|
}
|
|
|
|
public class CommonModel
|
|
{
|
|
|
|
|
|
public int idx { get; set; } // 데이터고유번호
|
|
public string gcode { get; set; } // 그룹코드(데이터 그룹간 식별)
|
|
public string grp { get; set; } // 코드그룹
|
|
public string code { get; set; } // 코드
|
|
public string svalue { get; set; } // 값(문자열)
|
|
public int ivalue { get; set; } // 값(숫자)
|
|
public float fvalue { get; set; } // 값(실수)
|
|
public string memo { get; set; } // 비고
|
|
public string svalue2 { get; set; } // 값2(문자열)
|
|
public string wuid { get; set; } // 데이터기록자 사원번호
|
|
public string wdate { get; set; } // 데이터를기록한일시
|
|
}
|
|
}
|
|
|
|
|
|
|