feat(service): Console_SendMail을 Windows 서비스로 변환
- MailService.cs 추가: ServiceBase 상속받는 Windows 서비스 클래스 - Program.cs 수정: 서비스/콘솔 모드 지원, 설치/제거 기능 추가 - 프로젝트 설정: System.ServiceProcess 참조 추가 - 배치 파일 추가: 서비스 설치/제거/콘솔실행 스크립트 주요 기능: - Windows 서비스로 백그라운드 실행 - 명령행 인수로 모드 선택 (-install, -uninstall, -console) - EventLog를 통한 서비스 로깅 - 안전한 서비스 시작/중지 처리 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
454
Project/Web/Controllers/CommonController.cs
Normal file
454
Project/Web/Controllers/CommonController.cs
Normal file
@@ -0,0 +1,454 @@
|
||||
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;
|
||||
|
||||
//코드그룹이 없다면 전체 목록을 조회할 수 있도록 99를 조회한다
|
||||
if (string.IsNullOrEmpty(grp)) grp = "99";
|
||||
|
||||
// 특정 그룹의 데이터만 가져옴
|
||||
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, memo 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
|
||||
},
|
||||
new {
|
||||
key = "project",
|
||||
title = "프로젝트",
|
||||
url = "/Project/",
|
||||
icon = "M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10",
|
||||
isVisible = true,
|
||||
sortOrder = 6
|
||||
}
|
||||
};
|
||||
|
||||
// 사용자 권한에 따른 메뉴 필터링 로직을 여기에 추가할 수 있습니다.
|
||||
// 예: 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; } // 데이터를기록한일시
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user