Files
Groupware/Project/Web/Controllers/CommonController.cs
ChiKyun Kim 6bd4f84192 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>
2025-09-11 09:08:40 +09:00

455 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;
//코드그룹이 없다면 전체 목록을 조회할 수 있도록 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; } // 데이터를기록한일시
}
}