업무일지 목록 및 상세화면 디자인 변경.

This commit is contained in:
ChiKyun Kim
2025-07-31 08:59:40 +09:00
parent 642c204a18
commit 5e0337a044
3 changed files with 912 additions and 228 deletions

View File

@@ -1,5 +1,6 @@
using Microsoft.Owin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web;
@@ -17,35 +18,228 @@ namespace Project.Web.Controllers
}
// DELETE api/values/5
public void Delete(int id)
[HttpDelete]
public HttpResponseMessage Delete(int id)
{
try
{
if (id <= 0)
{
throw new Exception("유효하지 않은 업무일지 ID입니다.");
}
// 직접 SQL 삭제 실행
string connectionString = Properties.Settings.Default.gwcs;
using (var connection = new System.Data.SqlClient.SqlConnection(connectionString))
{
connection.Open();
string deleteSql = @"
DELETE FROM JobReport
WHERE idx = @idx AND gcode = @gcode";
using (var command = new System.Data.SqlClient.SqlCommand(deleteSql, connection))
{
command.Parameters.AddWithValue("@idx", id);
command.Parameters.AddWithValue("@gcode", FCOMMON.info.Login.gcode);
int rowsAffected = command.ExecuteNonQuery();
if (rowsAffected == 0)
{
throw new Exception("업무일지를 찾을 수 없거나 삭제 권한이 없습니다.");
}
}
}
var jsonData = "{\"success\":true,\"message\":\"데이터가 성공적으로 삭제되었습니다.\"}";
var resp = new HttpResponseMessage()
{
Content = new StringContent(
jsonData,
System.Text.Encoding.UTF8,
"application/json")
};
return resp;
}
catch (Exception ex)
{
var errorResp = new HttpResponseMessage()
{
Content = new StringContent(
$"{{\"success\":false,\"message\":\"{EscapeJsonString(ex.Message)}\"}}",
System.Text.Encoding.UTF8,
"application/json")
};
return errorResp;
}
}
[HttpPost]
public string Add(FormCollection tbpdate)
public string Add(FormCollection formData)
{
var vals = Request.GetQueryNameValuePairs();
return string.Empty;
try
{
// 폼 데이터에서 값 추출
var pdate = formData["pdate"] ?? DateTime.Now.ToShortDateString();
var status = formData["status"] ?? "";
var projectName = formData["projectName"] ?? "";
var requestpart = formData["requestpart"] ?? "";
var type = formData["type"] ?? "";
var description = formData["description"] ?? "";
var otStart = formData["otStart"] ?? "";
var otEnd = formData["otEnd"] ?? "";
decimal hrs = 0;
decimal.TryParse(formData["hrs"], out hrs);
decimal ot = 0;
decimal.TryParse(formData["ot"], out ot);
// 직접 SQL 삽입 실행
string connectionString = Properties.Settings.Default.gwcs;
using (var connection = new System.Data.SqlClient.SqlConnection(connectionString))
{
connection.Open();
string insertSql = @"
INSERT INTO JobReport
(gcode, pdate, projectName, uid, requestpart, status, type, description, hrs, ot, otStart, otEnd, wuid, wdate)
VALUES
(@gcode, @pdate, @projectName, @uid, @requestpart, @status, @type, @description, @hrs, @ot, @otStart, @otEnd, @wuid, @wdate)";
using (var command = new System.Data.SqlClient.SqlCommand(insertSql, connection))
{
command.Parameters.AddWithValue("@gcode", FCOMMON.info.Login.gcode);
command.Parameters.AddWithValue("@pdate", pdate);
command.Parameters.AddWithValue("@projectName", projectName);
command.Parameters.AddWithValue("@uid", FCOMMON.info.Login.no);
command.Parameters.AddWithValue("@requestpart", requestpart);
command.Parameters.AddWithValue("@status", status);
command.Parameters.AddWithValue("@type", type);
command.Parameters.AddWithValue("@description", description);
command.Parameters.AddWithValue("@hrs", hrs);
command.Parameters.AddWithValue("@ot", ot);
command.Parameters.AddWithValue("@otStart", string.IsNullOrEmpty(otStart) ? (object)DBNull.Value : otStart);
command.Parameters.AddWithValue("@otEnd", string.IsNullOrEmpty(otEnd) ? (object)DBNull.Value : otEnd);
command.Parameters.AddWithValue("@wuid", FCOMMON.info.Login.no);
command.Parameters.AddWithValue("@wdate", DateTime.Now);
command.ExecuteNonQuery();
}
}
return "{\"success\":true,\"message\":\"데이터가 성공적으로 저장되었습니다.\"}";
}
catch (Exception ex)
{
return $"{{\"success\":false,\"message\":\"{EscapeJsonString(ex.Message)}\"}}";
}
}
//[HttpPost]
//public string Edit([FromBody] string value)
//{
// var vals = Request.GetQueryNameValuePairs();
// var req = Request.GetRequestContext();
// return string.Empty;
//}
[HttpPost]
public string Edit(FormCollection value)
public HttpResponseMessage Edit()
{
var vals = Request.GetQueryNameValuePairs();
try
{
// Request.Form에서 직접 값 추출
var idx = HttpContext.Current.Request.Form["idx"];
var pdate = HttpContext.Current.Request.Form["pdate"] ?? DateTime.Now.ToShortDateString();
var status = HttpContext.Current.Request.Form["status"] ?? "";
var projectName = HttpContext.Current.Request.Form["projectName"] ?? "";
var requestpart = HttpContext.Current.Request.Form["requestpart"] ?? "";
var type = HttpContext.Current.Request.Form["type"] ?? "";
var description = HttpContext.Current.Request.Form["description"] ?? "";
var otStart = HttpContext.Current.Request.Form["otStart"] ?? "";
var otEnd = HttpContext.Current.Request.Form["otEnd"] ?? "";
decimal hrs = 0;
decimal.TryParse(HttpContext.Current.Request.Form["hrs"], out hrs);
decimal ot = 0;
decimal.TryParse(HttpContext.Current.Request.Form["ot"], out ot);
var req = Request.GetRequestContext();
int idxNum = 0;
int.TryParse(idx, out idxNum);
return string.Empty;
if (idxNum <= 0)
{
throw new Exception("유효하지 않은 업무일지 ID입니다.");
}
// 직접 SQL 업데이트 실행
string connectionString = Properties.Settings.Default.gwcs;
using (var connection = new System.Data.SqlClient.SqlConnection(connectionString))
{
connection.Open();
string updateSql = @"
UPDATE JobReport
SET pdate = @pdate,
status = @status,
projectName = @projectName,
requestpart = @requestpart,
type = @type,
description = @description,
hrs = @hrs,
ot = @ot,
otStart = @otStart,
otEnd = @otEnd,
wuid = @wuid,
wdate = @wdate
WHERE idx = @idx AND gcode = @gcode";
using (var command = new System.Data.SqlClient.SqlCommand(updateSql, connection))
{
command.Parameters.AddWithValue("@idx", idxNum);
command.Parameters.AddWithValue("@gcode", FCOMMON.info.Login.gcode);
command.Parameters.AddWithValue("@pdate", pdate);
command.Parameters.AddWithValue("@status", status);
command.Parameters.AddWithValue("@projectName", projectName);
command.Parameters.AddWithValue("@requestpart", requestpart);
command.Parameters.AddWithValue("@type", type);
command.Parameters.AddWithValue("@description", description);
command.Parameters.AddWithValue("@hrs", hrs);
command.Parameters.AddWithValue("@ot", ot);
command.Parameters.AddWithValue("@otStart", string.IsNullOrEmpty(otStart) ? (object)DBNull.Value : otStart);
command.Parameters.AddWithValue("@otEnd", string.IsNullOrEmpty(otEnd) ? (object)DBNull.Value : otEnd);
command.Parameters.AddWithValue("@wuid", FCOMMON.info.Login.no);
command.Parameters.AddWithValue("@wdate", DateTime.Now);
int rowsAffected = command.ExecuteNonQuery();
if (rowsAffected == 0)
{
throw new Exception("업무일지를 찾을 수 없거나 수정 권한이 없습니다.");
}
}
}
var jsonData = "{\"success\":true,\"message\":\"데이터가 성공적으로 수정되었습니다.\"}";
var resp = new HttpResponseMessage()
{
Content = new StringContent(
jsonData,
System.Text.Encoding.UTF8,
"application/json")
};
return resp;
}
catch (Exception ex)
{
var errorResp = new HttpResponseMessage()
{
Content = new StringContent(
$"{{\"success\":false,\"message\":\"{EscapeJsonString(ex.Message)}\"}}",
System.Text.Encoding.UTF8,
"application/json")
};
return errorResp;
}
}
[HttpGet]
@@ -315,5 +509,317 @@ namespace Project.Web.Controllers
return resp;
}
[HttpGet]
public HttpResponseMessage GetJobDetail(int id)
{
try
{
// 특정 업무일지의 전체 정보 조회
string connectionString = Properties.Settings.Default.gwcs;
using (var connection = new System.Data.SqlClient.SqlConnection(connectionString))
{
connection.Open();
string selectSql = @"
SELECT idx, pdate, gcode, uid as id, '' as name, '' as process, type, '' as svalue,
hrs, ot, requestpart, '' as package, '' as userProcess, status, projectName,
description, '' as ww, otStart, otEnd, ot as ot2, '' as otReason,
'' as grade, '' as indate, '' as outdate, pidx
FROM JobReport WITH (NOLOCK)
WHERE gcode = @gcode AND uid = @uid AND idx = @idx";
using (var command = new System.Data.SqlClient.SqlCommand(selectSql, connection))
{
command.Parameters.AddWithValue("@gcode", FCOMMON.info.Login.gcode);
command.Parameters.AddWithValue("@uid", FCOMMON.info.Login.no);
command.Parameters.AddWithValue("@idx", id);
using (var reader = command.ExecuteReader())
{
if (reader.Read())
{
var item = new
{
idx = reader["idx"],
pdate = reader["pdate"],
gcode = reader["gcode"],
id = reader["id"],
name = reader["name"],
process = reader["process"],
type = reader["type"],
svalue = reader["svalue"],
hrs = reader["hrs"],
ot = reader["ot"],
requestpart = reader["requestpart"],
package = reader["package"],
userProcess = reader["userProcess"],
status = reader["status"],
projectName = reader["projectName"],
description = reader["description"], // 전체 내용
ww = reader["ww"],
otStart = reader["otStart"],
otEnd = reader["otEnd"],
ot2 = reader["ot2"],
otReason = reader["otReason"],
grade = reader["grade"],
indate = reader["indate"],
outdate = reader["outdate"],
pidx = reader["pidx"]
};
// JSON 형태로 변환
decimal hrs = 0;
decimal ot = 0;
int idx = 0;
int pidx = 0;
try { hrs = Convert.ToDecimal(item.hrs); } catch { hrs = 0; }
try { ot = Convert.ToDecimal(item.ot); } catch { ot = 0; }
try { idx = Convert.ToInt32(item.idx); } catch { idx = 0; }
try { pidx = Convert.ToInt32(item.pidx); } catch { pidx = 0; }
var desc = EscapeJsonString(item.description?.ToString() ?? ""); // 전체 내용
var pdate = EscapeJsonString(item.pdate?.ToString() ?? "");
var status = EscapeJsonString(item.status?.ToString() ?? "");
var type = EscapeJsonString(item.type?.ToString() ?? "");
var projectName = EscapeJsonString(item.projectName?.ToString() ?? "");
var requestpart = EscapeJsonString(item.requestpart?.ToString() ?? "");
var otStart = EscapeJsonString(item.otStart?.ToString() ?? "");
var otEnd = EscapeJsonString(item.otEnd?.ToString() ?? "");
var jsonData = "{";
jsonData += $"\"pdate\":\"{pdate}\",";
jsonData += $"\"status\":\"{status}\",";
jsonData += $"\"type\":\"{type}\",";
jsonData += $"\"projectName\":\"{projectName}\",";
jsonData += $"\"requestpart\":\"{requestpart}\",";
jsonData += $"\"hrs\":{hrs},";
jsonData += $"\"ot\":{ot},";
jsonData += $"\"description\":\"{desc}\",";
jsonData += $"\"otStart\":\"{otStart}\",";
jsonData += $"\"otEnd\":\"{otEnd}\",";
jsonData += $"\"idx\":{idx},";
jsonData += $"\"pidx\":{pidx}";
jsonData += "}";
var resp = new HttpResponseMessage()
{
Content = new StringContent(
jsonData,
System.Text.Encoding.UTF8,
"application/json")
};
return resp;
}
}
}
}
// 데이터를 찾을 수 없는 경우
var errorResp = new HttpResponseMessage()
{
Content = new StringContent(
"{\"error\":\"데이터를 찾을 수 없습니다.\"}",
System.Text.Encoding.UTF8,
"application/json")
};
return errorResp;
}
catch (Exception ex)
{
var errorResp = new HttpResponseMessage()
{
Content = new StringContent(
$"{{\"error\":\"{ex.Message}\"}}",
System.Text.Encoding.UTF8,
"application/json")
};
return errorResp;
}
}
[HttpGet]
public HttpResponseMessage GetJobData()
{
try
{
var gets = Request.GetQueryNameValuePairs();
var startDateParam = gets.Where(t => t.Key == "startDate").FirstOrDefault();
var endDateParam = gets.Where(t => t.Key == "endDate").FirstOrDefault();
var startDate = startDateParam.Key != null ? startDateParam.Value : null;
var endDate = endDateParam.Key != null ? endDateParam.Value : null;
// 날짜 파라미터 처리
string sd, ed;
if (!string.IsNullOrEmpty(startDate) && !string.IsNullOrEmpty(endDate))
{
sd = startDate;
ed = endDate;
}
else
{
// 기본값: 오늘부터 -2주
var now = DateTime.Now;
var twoWeeksAgo = now.AddDays(-14);
sd = twoWeeksAgo.ToShortDateString();
ed = now.ToShortDateString();
}
// 직접 SQL로 데이터 조회
string connectionString = Properties.Settings.Default.gwcs;
var jobReports = new List<dynamic>();
using (var connection = new System.Data.SqlClient.SqlConnection(connectionString))
{
connection.Open();
string selectSql = @"
SELECT idx, pdate, gcode, uid as id, '' as name, '' as process, type, '' as svalue,
hrs, ot, requestpart, '' as package, '' as userProcess, status, projectName,
description, '' as ww, otStart, otEnd, ot as ot2, '' as otReason,
'' as grade, '' as indate, '' as outdate, pidx
FROM JobReport WITH (NOLOCK)
WHERE gcode = @gcode AND uid = @uid AND pdate BETWEEN @startDate AND @endDate
ORDER BY pdate DESC";
using (var command = new System.Data.SqlClient.SqlCommand(selectSql, connection))
{
command.Parameters.AddWithValue("@gcode", FCOMMON.info.Login.gcode);
command.Parameters.AddWithValue("@uid", FCOMMON.info.Login.no);
command.Parameters.AddWithValue("@startDate", sd);
command.Parameters.AddWithValue("@endDate", ed);
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
jobReports.Add(new
{
idx = reader["idx"],
pdate = reader["pdate"],
gcode = reader["gcode"],
id = reader["id"],
name = reader["name"],
process = reader["process"],
type = reader["type"],
svalue = reader["svalue"],
hrs = reader["hrs"],
ot = reader["ot"],
requestpart = reader["requestpart"],
package = reader["package"],
userProcess = reader["userProcess"],
status = reader["status"],
projectName = reader["projectName"],
description = reader["description"],
ww = reader["ww"],
otStart = reader["otStart"],
otEnd = reader["otEnd"],
ot2 = reader["ot2"],
otReason = reader["otReason"],
grade = reader["grade"],
indate = reader["indate"],
outdate = reader["outdate"],
pidx = reader["pidx"]
});
}
}
}
}
// JSON 형태로 변환
var jsonData = "[";
bool first = true;
if (jobReports != null)
{
foreach (var item in jobReports)
{
if (!first) jsonData += ",";
first = false;
// DBNull 처리를 위한 안전한 변환
decimal hrs = 0;
decimal ot = 0;
int idx = 0;
int pidx = 0;
try { hrs = Convert.ToDecimal(item.hrs); } catch { hrs = 0; }
try { ot = Convert.ToDecimal(item.ot); } catch { ot = 0; }
try { idx = Convert.ToInt32(item.idx); } catch { idx = 0; }
try { pidx = Convert.ToInt32(item.pidx); } catch { pidx = 0; }
// 안전한 JSON 문자열 이스케이프 처리 및 25자 제한
var fullDesc = item.description?.ToString() ?? "";
var desc = EscapeJsonString(fullDesc.Length > 25 ? fullDesc.Substring(0, 25) + "..." : fullDesc);
var pdate = EscapeJsonString(item.pdate?.ToString() ?? "");
var ww = EscapeJsonString(item.ww?.ToString() ?? "");
var name = EscapeJsonString(item.name?.ToString() ?? "");
var status = EscapeJsonString(item.status?.ToString() ?? "");
var type = EscapeJsonString(item.type?.ToString() ?? "");
var projectName = EscapeJsonString(item.projectName?.ToString() ?? "");
var requestpart = EscapeJsonString(item.requestpart?.ToString() ?? "");
var userProcess = EscapeJsonString(item.userProcess?.ToString() ?? "");
jsonData += "{";
jsonData += $"\"pdate\":\"{pdate}\",";
jsonData += $"\"ww\":\"{ww}\",";
jsonData += $"\"name\":\"{name}\",";
jsonData += $"\"status\":\"{status}\",";
jsonData += $"\"type\":\"{type}\",";
jsonData += $"\"projectName\":\"{projectName}\",";
jsonData += $"\"requestpart\":\"{requestpart}\",";
jsonData += $"\"userProcess\":\"{userProcess}\",";
jsonData += $"\"hrs\":{hrs},";
jsonData += $"\"ot\":{ot},";
jsonData += $"\"description\":\"{desc}\",";
jsonData += $"\"idx\":{idx},";
jsonData += $"\"pidx\":{pidx}";
jsonData += "}";
}
}
jsonData += "]";
var resp = new HttpResponseMessage()
{
Content = new StringContent(
jsonData,
System.Text.Encoding.UTF8,
"application/json")
};
return resp;
}
catch (Exception ex)
{
var errorResp = new HttpResponseMessage()
{
Content = new StringContent(
$"{{\"error\":\"{ex.Message}\"}}",
System.Text.Encoding.UTF8,
"application/json")
};
return errorResp;
}
}
private string EscapeJsonString(string input)
{
if (string.IsNullOrEmpty(input))
return "";
// 제어 문자 제거 (0x00-0x1F 범위)
var cleanInput = System.Text.RegularExpressions.Regex.Replace(input, @"[\x00-\x08\x0B\x0C\x0E-\x1F]", "");
return cleanInput
.Replace("\\", "\\\\") // 백슬래시
.Replace("\"", "\\\"") // 따옴표
.Replace("\n", "\\n") // 개행
.Replace("\r", "\\r") // 캐리지 리턴
.Replace("\t", "\\t"); // 탭
}
}
}
}