feat: React 프론트엔드 기능 대폭 확장
- 월별근무표: 휴일/근무일 관리, 자동 초기화 - 메일양식: 템플릿 CRUD, To/CC/BCC 설정 - 그룹정보: 부서 관리, 비트 연산 기반 권한 설정 - 업무일지: 수정 성공 메시지 제거, 오늘 근무시간 필터링 수정 - 웹소켓 메시지 type 충돌 버그 수정 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -229,5 +229,198 @@ namespace Project.Web
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Items API
|
||||
|
||||
/// <summary>
|
||||
/// 품목 카테고리 목록 조회
|
||||
/// </summary>
|
||||
public string Items_GetCategories()
|
||||
{
|
||||
try
|
||||
{
|
||||
var sql = "SELECT DISTINCT cate FROM Items WITH (NOLOCK) WHERE gcode = @gcode AND ISNULL(cate,'') <> '' ORDER BY cate";
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
var cn = new SqlConnection(cs);
|
||||
var cmd = new SqlCommand(sql, cn);
|
||||
cmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
|
||||
var da = new SqlDataAdapter(cmd);
|
||||
var dt = new DataTable();
|
||||
da.Fill(dt);
|
||||
da.Dispose();
|
||||
cmd.Dispose();
|
||||
cn.Dispose();
|
||||
|
||||
var result = new System.Collections.Generic.List<string>();
|
||||
foreach (DataRow dr in dt.Rows)
|
||||
{
|
||||
result.Add(dr["cate"]?.ToString() ?? "");
|
||||
}
|
||||
|
||||
return JsonConvert.SerializeObject(new { Success = true, Data = result });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "카테고리 조회 실패: " + ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 품목 목록 조회
|
||||
/// </summary>
|
||||
public string Items_GetList(string category, string searchKey)
|
||||
{
|
||||
try
|
||||
{
|
||||
var cateSearch = string.IsNullOrEmpty(category) || category == "all" ? "%" : category;
|
||||
var skey = string.IsNullOrEmpty(searchKey) || searchKey == "%" ? "%" : $"%{searchKey}%";
|
||||
|
||||
var sql = @"SELECT idx, sid, cate, name, model, scale, unit, price, supply, manu, storage, disable, memo
|
||||
FROM Items WITH (NOLOCK)
|
||||
WHERE gcode = @gcode
|
||||
AND ISNULL(cate,'') LIKE @cate
|
||||
AND (ISNULL(sid,'') LIKE @search OR ISNULL(name,'') LIKE @search OR ISNULL(model,'') LIKE @search)
|
||||
ORDER BY sid, name";
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
var cn = new SqlConnection(cs);
|
||||
var cmd = new SqlCommand(sql, cn);
|
||||
cmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
cmd.Parameters.AddWithValue("@cate", cateSearch);
|
||||
cmd.Parameters.AddWithValue("@search", skey);
|
||||
|
||||
var da = new SqlDataAdapter(cmd);
|
||||
var dt = new DataTable();
|
||||
da.Fill(dt);
|
||||
da.Dispose();
|
||||
cmd.Dispose();
|
||||
cn.Dispose();
|
||||
|
||||
return JsonConvert.SerializeObject(dt, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "품목 조회 실패: " + ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 품목 저장
|
||||
/// </summary>
|
||||
public string Items_Save(int idx, string sid, string cate, string name, string model,
|
||||
string scale, string unit, decimal price, string supply, string manu, string storage, bool disable, string memo)
|
||||
{
|
||||
try
|
||||
{
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
var cn = new SqlConnection(cs);
|
||||
var sql = string.Empty;
|
||||
var cmd = new SqlCommand();
|
||||
cmd.Connection = cn;
|
||||
|
||||
// 신규 추가 시 SID 중복 체크
|
||||
if (idx == 0 && !string.IsNullOrEmpty(sid))
|
||||
{
|
||||
var checkSql = "SELECT COUNT(*) FROM Items WITH (NOLOCK) WHERE gcode = @gcode AND sid = @sid";
|
||||
var checkCmd = new SqlCommand(checkSql, cn);
|
||||
checkCmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
checkCmd.Parameters.AddWithValue("@sid", sid);
|
||||
|
||||
cn.Open();
|
||||
var count = (int)checkCmd.ExecuteScalar();
|
||||
cn.Close();
|
||||
checkCmd.Dispose();
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
cn.Dispose();
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = $"이미 존재하는 SID입니다: {sid}" });
|
||||
}
|
||||
}
|
||||
|
||||
if (idx > 0)
|
||||
{
|
||||
sql = @"UPDATE Items SET
|
||||
sid = @sid, cate = @cate, name = @name, model = @model,
|
||||
scale = @scale, unit = @unit, price = @price, supply = @supply,
|
||||
manu = @manu, storage = @storage, disable = @disable, memo = @memo,
|
||||
wuid = @wuid, wdate = GETDATE()
|
||||
WHERE idx = @idx AND gcode = @gcode";
|
||||
}
|
||||
else
|
||||
{
|
||||
sql = @"INSERT INTO Items (gcode, sid, cate, name, model, scale, unit, price, supply, manu, storage, disable, memo, wuid, wdate)
|
||||
VALUES (@gcode, @sid, @cate, @name, @model, @scale, @unit, @price, @supply, @manu, @storage, @disable, @memo, @wuid, GETDATE())";
|
||||
}
|
||||
|
||||
cmd.CommandText = sql;
|
||||
cmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
cmd.Parameters.AddWithValue("@sid", sid ?? "");
|
||||
cmd.Parameters.AddWithValue("@cate", cate ?? "");
|
||||
cmd.Parameters.AddWithValue("@name", name ?? "");
|
||||
cmd.Parameters.AddWithValue("@model", model ?? "");
|
||||
cmd.Parameters.AddWithValue("@scale", scale ?? "");
|
||||
cmd.Parameters.AddWithValue("@unit", unit ?? "");
|
||||
cmd.Parameters.AddWithValue("@price", price);
|
||||
cmd.Parameters.AddWithValue("@supply", supply ?? "");
|
||||
cmd.Parameters.AddWithValue("@manu", manu ?? "");
|
||||
cmd.Parameters.AddWithValue("@storage", storage ?? "");
|
||||
cmd.Parameters.AddWithValue("@disable", disable);
|
||||
cmd.Parameters.AddWithValue("@memo", memo ?? "");
|
||||
cmd.Parameters.AddWithValue("@wuid", info.Login.no);
|
||||
|
||||
if (idx > 0)
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@idx", idx);
|
||||
}
|
||||
|
||||
cn.Open();
|
||||
var result = cmd.ExecuteNonQuery();
|
||||
cn.Close();
|
||||
|
||||
cmd.Dispose();
|
||||
cn.Dispose();
|
||||
|
||||
return JsonConvert.SerializeObject(new { Success = result > 0, Message = result > 0 ? "저장되었습니다." : "저장에 실패했습니다." });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "저장 실패: " + ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 품목 삭제
|
||||
/// </summary>
|
||||
public string Items_Delete(int idx)
|
||||
{
|
||||
try
|
||||
{
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
var cn = new SqlConnection(cs);
|
||||
var sql = "DELETE FROM Items WHERE idx = @idx AND gcode = @gcode";
|
||||
var cmd = new SqlCommand(sql, cn);
|
||||
|
||||
cmd.Parameters.AddWithValue("@idx", idx);
|
||||
cmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
|
||||
cn.Open();
|
||||
var result = cmd.ExecuteNonQuery();
|
||||
cn.Close();
|
||||
|
||||
cmd.Dispose();
|
||||
cn.Dispose();
|
||||
|
||||
return JsonConvert.SerializeObject(new { Success = result > 0, Message = result > 0 ? "삭제되었습니다." : "삭제에 실패했습니다." });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "삭제 실패: " + ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
177
Project/Web/MachineBridge/MachineBridge.Holiday.cs
Normal file
177
Project/Web/MachineBridge/MachineBridge.Holiday.cs
Normal file
@@ -0,0 +1,177 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using Newtonsoft.Json;
|
||||
using FCOMMON;
|
||||
|
||||
namespace Project.Web
|
||||
{
|
||||
public partial class MachineBridge
|
||||
{
|
||||
#region Holiday API (월별근무표)
|
||||
|
||||
/// <summary>
|
||||
/// 월별근무표 목록 조회
|
||||
/// </summary>
|
||||
public string Holiday_GetList(string month)
|
||||
{
|
||||
try
|
||||
{
|
||||
var monthPattern = month + "%";
|
||||
var sql = @"SELECT idx, pdate, free, memo, wuid, wdate
|
||||
FROM HolidayList WITH (nolock)
|
||||
WHERE pdate LIKE @month
|
||||
ORDER BY pdate";
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
using (var cn = new SqlConnection(cs))
|
||||
using (var cmd = new SqlCommand(sql, cn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@month", monthPattern);
|
||||
using (var da = new SqlDataAdapter(cmd))
|
||||
{
|
||||
var dt = new DataTable();
|
||||
da.Fill(dt);
|
||||
return JsonConvert.SerializeObject(new { Success = true, Data = dt });
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 월별근무표 저장 (없으면 생성)
|
||||
/// </summary>
|
||||
public string Holiday_Save(string month, string holidaysJson)
|
||||
{
|
||||
try
|
||||
{
|
||||
var holidays = JsonConvert.DeserializeObject<List<HolidayItem>>(holidaysJson);
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
|
||||
using (var cn = new SqlConnection(cs))
|
||||
{
|
||||
cn.Open();
|
||||
using (var tran = cn.BeginTransaction())
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var item in holidays)
|
||||
{
|
||||
var sql = @"
|
||||
IF EXISTS (SELECT 1 FROM HolidayList WHERE pdate = @pdate)
|
||||
UPDATE HolidayList SET free = @free, memo = @memo, wuid = @wuid, wdate = GETDATE() WHERE pdate = @pdate
|
||||
ELSE
|
||||
INSERT INTO HolidayList (pdate, free, memo, wuid, wdate) VALUES (@pdate, @free, @memo, @wuid, GETDATE())";
|
||||
|
||||
using (var cmd = new SqlCommand(sql, cn, tran))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@pdate", item.pdate);
|
||||
cmd.Parameters.AddWithValue("@free", item.free);
|
||||
cmd.Parameters.AddWithValue("@memo", item.memo ?? "");
|
||||
cmd.Parameters.AddWithValue("@wuid", info.Login.no);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
tran.Commit();
|
||||
return JsonConvert.SerializeObject(new { Success = true, Message = "저장되었습니다." });
|
||||
}
|
||||
catch
|
||||
{
|
||||
tran.Rollback();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 월별근무표 초기 데이터 생성 (해당 월에 데이터가 없을 때)
|
||||
/// </summary>
|
||||
public string Holiday_Initialize(string month)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 해당 월 데이터 존재 여부 확인
|
||||
var monthPattern = month + "%";
|
||||
var checkSql = "SELECT COUNT(*) FROM HolidayList WITH (nolock) WHERE pdate LIKE @month";
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
|
||||
using (var cn = new SqlConnection(cs))
|
||||
{
|
||||
cn.Open();
|
||||
|
||||
using (var checkCmd = new SqlCommand(checkSql, cn))
|
||||
{
|
||||
checkCmd.Parameters.AddWithValue("@month", monthPattern);
|
||||
var count = (int)checkCmd.ExecuteScalar();
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = true, Message = "이미 데이터가 존재합니다.", Created = false });
|
||||
}
|
||||
}
|
||||
|
||||
// 해당 월의 모든 날짜 생성
|
||||
var startDate = DateTime.Parse(month + "-01");
|
||||
var endDate = startDate.AddMonths(1).AddDays(-1);
|
||||
|
||||
using (var tran = cn.BeginTransaction())
|
||||
{
|
||||
try
|
||||
{
|
||||
for (var date = startDate; date <= endDate; date = date.AddDays(1))
|
||||
{
|
||||
var isFree = date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday;
|
||||
var memo = date.DayOfWeek == DayOfWeek.Saturday ? "토요일" :
|
||||
date.DayOfWeek == DayOfWeek.Sunday ? "일요일" : "";
|
||||
|
||||
var sql = @"INSERT INTO HolidayList (pdate, free, memo, wuid, wdate)
|
||||
VALUES (@pdate, @free, @memo, @wuid, GETDATE())";
|
||||
|
||||
using (var cmd = new SqlCommand(sql, cn, tran))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@pdate", date.ToString("yyyy-MM-dd"));
|
||||
cmd.Parameters.AddWithValue("@free", isFree);
|
||||
cmd.Parameters.AddWithValue("@memo", memo);
|
||||
cmd.Parameters.AddWithValue("@wuid", info.Login.no);
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
tran.Commit();
|
||||
return JsonConvert.SerializeObject(new { Success = true, Message = "초기 데이터가 생성되었습니다.", Created = true });
|
||||
}
|
||||
catch
|
||||
{
|
||||
tran.Rollback();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class HolidayItem
|
||||
{
|
||||
public int idx { get; set; }
|
||||
public string pdate { get; set; }
|
||||
public bool free { get; set; }
|
||||
public string memo { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -12,62 +12,47 @@ namespace Project.Web
|
||||
#region Jobreport API
|
||||
|
||||
/// <summary>
|
||||
/// 업무일지 목록 조회
|
||||
/// 업무일지 목록 조회 (vJobReportForUser 뷰 사용)
|
||||
/// </summary>
|
||||
public string Jobreport_GetList(string sd, string ed, string uid, string cate, string doit)
|
||||
public string Jobreport_GetList(string sd, string ed, string uid, string cate, string searchKey)
|
||||
{
|
||||
try
|
||||
{
|
||||
var sql = @"SELECT j.idx, j.jdate, j.uid, j.cate, j.title, j.doit, j.remark, j.jfrom, j.jto,
|
||||
u.name as userName, j.wdate
|
||||
FROM EETGW_Jobreport j WITH (nolock)
|
||||
LEFT JOIN Users u ON j.uid = u.id
|
||||
WHERE j.gcode = @gcode";
|
||||
var sql = @"SELECT idx, pidx, pdate, id, name,type, svalue, hrs,ot,requestpart,package,userprocess,status, projectName, description, ww,otpms,process
|
||||
FROM vJobReportForUser WITH (nolock)
|
||||
WHERE gcode = @gcode AND (pdate BETWEEN @sd AND @ed)";
|
||||
|
||||
var parameters = new List<SqlParameter>();
|
||||
parameters.Add(new SqlParameter("@gcode", info.Login.gcode));
|
||||
parameters.Add(new SqlParameter("@sd", sd));
|
||||
parameters.Add(new SqlParameter("@ed", ed));
|
||||
|
||||
if (!string.IsNullOrEmpty(sd))
|
||||
{
|
||||
sql += " AND j.jdate >= @sd";
|
||||
parameters.Add(new SqlParameter("@sd", sd));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(ed))
|
||||
{
|
||||
sql += " AND j.jdate <= @ed";
|
||||
parameters.Add(new SqlParameter("@ed", ed));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(uid))
|
||||
{
|
||||
sql += " AND j.uid = @uid";
|
||||
sql += " AND id = @uid";
|
||||
parameters.Add(new SqlParameter("@uid", uid));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(cate))
|
||||
|
||||
if (!string.IsNullOrEmpty(searchKey))
|
||||
{
|
||||
sql += " AND j.cate = @cate";
|
||||
parameters.Add(new SqlParameter("@cate", cate));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(doit))
|
||||
{
|
||||
sql += " AND j.doit = @doit";
|
||||
parameters.Add(new SqlParameter("@doit", doit));
|
||||
sql += " AND (requestpart LIKE @searchKey OR package LIKE @searchKey OR projectName LIKE @searchKey OR process LIKE @searchKey OR [type] LIKE @searchKey OR description LIKE @searchKey)";
|
||||
parameters.Add(new SqlParameter("@searchKey", "%" + searchKey + "%"));
|
||||
}
|
||||
|
||||
sql += " ORDER BY j.jdate DESC, j.idx DESC";
|
||||
sql += " ORDER BY pdate DESC, idx DESC";
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
var cn = new SqlConnection(cs);
|
||||
var cmd = new SqlCommand(sql, cn);
|
||||
cmd.Parameters.AddRange(parameters.ToArray());
|
||||
|
||||
var da = new SqlDataAdapter(cmd);
|
||||
var dt = new DataTable();
|
||||
da.Fill(dt);
|
||||
da.Dispose();
|
||||
cmd.Dispose();
|
||||
cn.Dispose();
|
||||
|
||||
return JsonConvert.SerializeObject(new { Success = true, Data = dt }, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
||||
using (var cn = new SqlConnection(cs))
|
||||
using (var cmd = new SqlCommand(sql, cn))
|
||||
{
|
||||
cmd.Parameters.AddRange(parameters.ToArray());
|
||||
using (var da = new SqlDataAdapter(cmd))
|
||||
{
|
||||
var dt = new DataTable();
|
||||
da.Fill(dt);
|
||||
return JsonConvert.SerializeObject(new { Success = true, Data = dt });
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -88,18 +73,17 @@ namespace Project.Web
|
||||
ORDER BY u.name";
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
var cn = new SqlConnection(cs);
|
||||
var cmd = new SqlCommand(sql, cn);
|
||||
cmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
|
||||
var da = new SqlDataAdapter(cmd);
|
||||
var dt = new DataTable();
|
||||
da.Fill(dt);
|
||||
da.Dispose();
|
||||
cmd.Dispose();
|
||||
cn.Dispose();
|
||||
|
||||
return JsonConvert.SerializeObject(dt, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
||||
using (var cn = new SqlConnection(cs))
|
||||
using (var cmd = new SqlCommand(sql, cn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
using (var da = new SqlDataAdapter(cmd))
|
||||
{
|
||||
var dt = new DataTable();
|
||||
da.Fill(dt);
|
||||
return JsonConvert.SerializeObject(dt);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -109,36 +93,40 @@ namespace Project.Web
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 업무일지 상세 조회
|
||||
/// 업무일지 상세 조회 (vJobReportForUser 뷰 사용)
|
||||
/// </summary>
|
||||
public string Jobreport_GetDetail(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var sql = @"SELECT j.*, u.name as userName
|
||||
FROM EETGW_Jobreport j WITH (nolock)
|
||||
LEFT JOIN Users u ON j.uid = u.id
|
||||
WHERE j.idx = @idx AND j.gcode = @gcode";
|
||||
var sql = @"SELECT idx, pidx, pdate, id, name, type, svalue, hrs, ot, requestpart, package,
|
||||
userprocess, status, projectName, description, ww, otpms, process
|
||||
FROM vJobReportForUser WITH (nolock)
|
||||
WHERE idx = @idx AND gcode = @gcode";
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
var cn = new SqlConnection(cs);
|
||||
var cmd = new SqlCommand(sql, cn);
|
||||
cmd.Parameters.AddWithValue("@idx", id);
|
||||
cmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
|
||||
var da = new SqlDataAdapter(cmd);
|
||||
var dt = new DataTable();
|
||||
da.Fill(dt);
|
||||
da.Dispose();
|
||||
cmd.Dispose();
|
||||
cn.Dispose();
|
||||
|
||||
if (dt.Rows.Count > 0)
|
||||
using (var cn = new SqlConnection(cs))
|
||||
using (var cmd = new SqlCommand(sql, cn))
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = true, Data = dt.Rows[0] }, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
||||
cmd.Parameters.AddWithValue("@idx", id);
|
||||
cmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
using (var da = new SqlDataAdapter(cmd))
|
||||
{
|
||||
var dt = new DataTable();
|
||||
da.Fill(dt);
|
||||
if (dt.Rows.Count > 0)
|
||||
{
|
||||
var row = dt.Rows[0];
|
||||
var data = new Dictionary<string, object>();
|
||||
foreach (DataColumn col in dt.Columns)
|
||||
{
|
||||
data[col.ColumnName] = row[col] == DBNull.Value ? null : row[col];
|
||||
}
|
||||
return JsonConvert.SerializeObject(new { Success = true, Data = data });
|
||||
}
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "데이터를 찾을 수 없습니다." });
|
||||
}
|
||||
}
|
||||
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "데이터를 찾을 수 없습니다." });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -147,37 +135,50 @@ namespace Project.Web
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 업무일지 추가
|
||||
/// 업무일지 추가 (JobReport 테이블)
|
||||
/// </summary>
|
||||
public string Jobreport_Add(string jdate, string cate, string title, string doit, string remark, string jfrom, string jto)
|
||||
public string Jobreport_Add(string pdate, string projectName, string requestpart, string package,
|
||||
string type, string process, string status, string description, double hrs, double ot, string jobgrp, string tag)
|
||||
{
|
||||
try
|
||||
{
|
||||
var sql = @"INSERT INTO EETGW_Jobreport (gcode, uid, jdate, cate, title, doit, remark, jfrom, jto, wuid, wdate)
|
||||
VALUES (@gcode, @uid, @jdate, @cate, @title, @doit, @remark, @jfrom, @jto, @wuid, GETDATE());
|
||||
// 마감 체크
|
||||
var smon = pdate.Substring(0, 7);
|
||||
if (DBM.GetMagamStatus(smon))
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = $"등록일이 속한 월({smon})이 마감되었습니다." });
|
||||
}
|
||||
|
||||
var sql = @"INSERT INTO JobReport (gcode, uid, pdate, projectName, requestpart, package,
|
||||
type, process, status, description, hrs, ot, jobgrp, tag, wuid, wdate, pidx)
|
||||
VALUES (@gcode, @uid, @pdate, @projectName, @requestpart, @package,
|
||||
@type, @process, @status, @description, @hrs, @ot, @jobgrp, @tag, @wuid, GETDATE(), -1);
|
||||
SELECT SCOPE_IDENTITY();";
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
var cn = new SqlConnection(cs);
|
||||
var cmd = new SqlCommand(sql, cn);
|
||||
cmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
cmd.Parameters.AddWithValue("@uid", info.Login.no);
|
||||
cmd.Parameters.AddWithValue("@jdate", jdate ?? DateTime.Now.ToString("yyyy-MM-dd"));
|
||||
cmd.Parameters.AddWithValue("@cate", cate ?? "");
|
||||
cmd.Parameters.AddWithValue("@title", title ?? "");
|
||||
cmd.Parameters.AddWithValue("@doit", doit ?? "");
|
||||
cmd.Parameters.AddWithValue("@remark", remark ?? "");
|
||||
cmd.Parameters.AddWithValue("@jfrom", jfrom ?? "");
|
||||
cmd.Parameters.AddWithValue("@jto", jto ?? "");
|
||||
cmd.Parameters.AddWithValue("@wuid", info.Login.no);
|
||||
using (var cn = new SqlConnection(cs))
|
||||
using (var cmd = new SqlCommand(sql, cn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
cmd.Parameters.AddWithValue("@uid", info.Login.no);
|
||||
cmd.Parameters.AddWithValue("@pdate", pdate);
|
||||
cmd.Parameters.AddWithValue("@projectName", projectName ?? "");
|
||||
cmd.Parameters.AddWithValue("@requestpart", requestpart ?? "");
|
||||
cmd.Parameters.AddWithValue("@package", package ?? "");
|
||||
cmd.Parameters.AddWithValue("@type", type ?? "");
|
||||
cmd.Parameters.AddWithValue("@process", process ?? "");
|
||||
cmd.Parameters.AddWithValue("@status", status ?? "진행 완료");
|
||||
cmd.Parameters.AddWithValue("@description", description ?? "");
|
||||
cmd.Parameters.AddWithValue("@hrs", hrs);
|
||||
cmd.Parameters.AddWithValue("@ot", ot);
|
||||
cmd.Parameters.AddWithValue("@jobgrp", jobgrp ?? "");
|
||||
cmd.Parameters.AddWithValue("@tag", tag ?? "");
|
||||
cmd.Parameters.AddWithValue("@wuid", info.Login.no);
|
||||
|
||||
cn.Open();
|
||||
var newId = Convert.ToInt32(cmd.ExecuteScalar());
|
||||
cn.Close();
|
||||
cmd.Dispose();
|
||||
cn.Dispose();
|
||||
|
||||
return JsonConvert.SerializeObject(new { Success = true, Message = "저장되었습니다.", Data = new { idx = newId } });
|
||||
cn.Open();
|
||||
var newId = Convert.ToInt32(cmd.ExecuteScalar());
|
||||
return JsonConvert.SerializeObject(new { Success = true, Message = "저장되었습니다.", Data = new { idx = newId } });
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -186,39 +187,73 @@ namespace Project.Web
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 업무일지 수정
|
||||
/// 업무일지 수정 (JobReport 테이블)
|
||||
/// </summary>
|
||||
public string Jobreport_Edit(int idx, string jdate, string cate, string title, string doit, string remark, string jfrom, string jto)
|
||||
public string Jobreport_Edit(int idx, string pdate, string projectName, string requestpart, string package,
|
||||
string type, string process, string status, string description, double hrs, double ot, string jobgrp, string tag)
|
||||
{
|
||||
try
|
||||
{
|
||||
var sql = @"UPDATE EETGW_Jobreport SET
|
||||
jdate = @jdate, cate = @cate, title = @title, doit = @doit,
|
||||
remark = @remark, jfrom = @jfrom, jto = @jto,
|
||||
// 권한 체크
|
||||
int curLevel = Math.Max(info.Login.level, DBM.getAuth(DBM.eAuthType.jobreport));
|
||||
|
||||
// 마감 체크
|
||||
var smon = pdate.Substring(0, 7);
|
||||
if (DBM.GetMagamStatus(smon))
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = $"등록일이 속한 월({smon})이 마감되었습니다." });
|
||||
}
|
||||
|
||||
// 본인 자료인지 체크 (관리자가 아닌 경우)
|
||||
if (curLevel < 5)
|
||||
{
|
||||
var checkSql = "SELECT uid FROM JobReport WHERE idx = @idx AND gcode = @gcode";
|
||||
var cs2 = Properties.Settings.Default.gwcs;
|
||||
using (var cn2 = new SqlConnection(cs2))
|
||||
using (var cmd2 = new SqlCommand(checkSql, cn2))
|
||||
{
|
||||
cmd2.Parameters.AddWithValue("@idx", idx);
|
||||
cmd2.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
cn2.Open();
|
||||
var ownerUid = cmd2.ExecuteScalar()?.ToString();
|
||||
if (ownerUid != info.Login.no)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "타인의 자료는 수정할 수 없습니다." });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var sql = @"UPDATE JobReport SET
|
||||
pdate = @pdate, projectName = @projectName, requestpart = @requestpart,
|
||||
package = @package, type = @type, process = @process, status = @status,
|
||||
description = @description, hrs = @hrs, ot = @ot, jobgrp = @jobgrp, tag = @tag,
|
||||
wuid = @wuid, wdate = GETDATE()
|
||||
WHERE idx = @idx AND gcode = @gcode";
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
var cn = new SqlConnection(cs);
|
||||
var cmd = new SqlCommand(sql, cn);
|
||||
cmd.Parameters.AddWithValue("@idx", idx);
|
||||
cmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
cmd.Parameters.AddWithValue("@jdate", jdate ?? DateTime.Now.ToString("yyyy-MM-dd"));
|
||||
cmd.Parameters.AddWithValue("@cate", cate ?? "");
|
||||
cmd.Parameters.AddWithValue("@title", title ?? "");
|
||||
cmd.Parameters.AddWithValue("@doit", doit ?? "");
|
||||
cmd.Parameters.AddWithValue("@remark", remark ?? "");
|
||||
cmd.Parameters.AddWithValue("@jfrom", jfrom ?? "");
|
||||
cmd.Parameters.AddWithValue("@jto", jto ?? "");
|
||||
cmd.Parameters.AddWithValue("@wuid", info.Login.no);
|
||||
using (var cn = new SqlConnection(cs))
|
||||
using (var cmd = new SqlCommand(sql, cn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@idx", idx);
|
||||
cmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
cmd.Parameters.AddWithValue("@pdate", pdate);
|
||||
cmd.Parameters.AddWithValue("@projectName", projectName ?? "");
|
||||
cmd.Parameters.AddWithValue("@requestpart", requestpart ?? "");
|
||||
cmd.Parameters.AddWithValue("@package", package ?? "");
|
||||
cmd.Parameters.AddWithValue("@type", type ?? "");
|
||||
cmd.Parameters.AddWithValue("@process", process ?? "");
|
||||
cmd.Parameters.AddWithValue("@status", status ?? "");
|
||||
cmd.Parameters.AddWithValue("@description", description ?? "");
|
||||
cmd.Parameters.AddWithValue("@hrs", hrs);
|
||||
cmd.Parameters.AddWithValue("@ot", ot);
|
||||
cmd.Parameters.AddWithValue("@jobgrp", jobgrp ?? "");
|
||||
cmd.Parameters.AddWithValue("@tag", tag ?? "");
|
||||
cmd.Parameters.AddWithValue("@wuid", info.Login.no);
|
||||
|
||||
cn.Open();
|
||||
var result = cmd.ExecuteNonQuery();
|
||||
cn.Close();
|
||||
cmd.Dispose();
|
||||
cn.Dispose();
|
||||
|
||||
return JsonConvert.SerializeObject(new { Success = result > 0, Message = result > 0 ? "수정되었습니다." : "수정에 실패했습니다." });
|
||||
cn.Open();
|
||||
var result = cmd.ExecuteNonQuery();
|
||||
return JsonConvert.SerializeObject(new { Success = result > 0, Message = result > 0 ? "수정되었습니다." : "수정에 실패했습니다." });
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -233,21 +268,128 @@ namespace Project.Web
|
||||
{
|
||||
try
|
||||
{
|
||||
var sql = "DELETE FROM EETGW_Jobreport WHERE idx = @idx AND gcode = @gcode";
|
||||
// 권한 체크
|
||||
int curLevel = Math.Max(info.Login.level, DBM.getAuth(DBM.eAuthType.jobreport));
|
||||
|
||||
// 본인 자료인지 체크 (관리자가 아닌 경우)
|
||||
if (curLevel < 5)
|
||||
{
|
||||
var checkSql = "SELECT uid, pdate FROM JobReport WHERE idx = @idx AND gcode = @gcode";
|
||||
var cs2 = Properties.Settings.Default.gwcs;
|
||||
using (var cn2 = new SqlConnection(cs2))
|
||||
using (var cmd2 = new SqlCommand(checkSql, cn2))
|
||||
{
|
||||
cmd2.Parameters.AddWithValue("@idx", idx);
|
||||
cmd2.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
cn2.Open();
|
||||
using (var reader = cmd2.ExecuteReader())
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
var ownerUid = reader["uid"]?.ToString();
|
||||
var pdate = reader["pdate"]?.ToString();
|
||||
|
||||
if (ownerUid != info.Login.no)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "타인의 자료는 삭제할 수 없습니다." });
|
||||
}
|
||||
|
||||
// 마감 체크
|
||||
if (!string.IsNullOrEmpty(pdate) && pdate.Length >= 7)
|
||||
{
|
||||
var smon = pdate.Substring(0, 7);
|
||||
if (DBM.GetMagamStatus(smon))
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = $"등록일이 속한 월({smon})이 마감되었습니다." });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var sql = "DELETE FROM JobReport WHERE idx = @idx AND gcode = @gcode";
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
var cn = new SqlConnection(cs);
|
||||
var cmd = new SqlCommand(sql, cn);
|
||||
cmd.Parameters.AddWithValue("@idx", idx);
|
||||
cmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
using (var cn = new SqlConnection(cs))
|
||||
using (var cmd = new SqlCommand(sql, cn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@idx", idx);
|
||||
cmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
|
||||
cn.Open();
|
||||
var result = cmd.ExecuteNonQuery();
|
||||
cn.Close();
|
||||
cmd.Dispose();
|
||||
cn.Dispose();
|
||||
cn.Open();
|
||||
var result = cmd.ExecuteNonQuery();
|
||||
return JsonConvert.SerializeObject(new { Success = result > 0, Message = result > 0 ? "삭제되었습니다." : "삭제에 실패했습니다." });
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
return JsonConvert.SerializeObject(new { Success = result > 0, Message = result > 0 ? "삭제되었습니다." : "삭제에 실패했습니다." });
|
||||
/// <summary>
|
||||
/// 업무형태 목록 조회 (Common 테이블, grp='15')
|
||||
/// 트리뷰 형태: process > jobgrp > type
|
||||
/// </summary>
|
||||
public string Jobreport_GetJobTypes(string process = "")
|
||||
{
|
||||
try
|
||||
{
|
||||
var sql = @"SELECT idx, code, memo as [type], svalue as jobgrp, svalue2 as process
|
||||
FROM Common WITH (nolock)
|
||||
WHERE gcode = @gcode AND grp = '15'";
|
||||
|
||||
var parameters = new List<SqlParameter>();
|
||||
parameters.Add(new SqlParameter("@gcode", info.Login.gcode));
|
||||
|
||||
if (!string.IsNullOrEmpty(process))
|
||||
{
|
||||
sql += " AND svalue2 = @process";
|
||||
parameters.Add(new SqlParameter("@process", process));
|
||||
}
|
||||
|
||||
sql += " ORDER BY svalue2, svalue, memo";
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
using (var cn = new SqlConnection(cs))
|
||||
using (var cmd = new SqlCommand(sql, cn))
|
||||
{
|
||||
cmd.Parameters.AddRange(parameters.ToArray());
|
||||
using (var da = new SqlDataAdapter(cmd))
|
||||
{
|
||||
var dt = new DataTable();
|
||||
da.Fill(dt);
|
||||
return JsonConvert.SerializeObject(new { Success = true, Data = dt });
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 업무일지 권한 정보 조회
|
||||
/// 본인이거나 권한 레벨 5 이상이면 OT 열을 볼 수 있음
|
||||
/// </summary>
|
||||
public string Jobreport_GetPermission(string targetUserId)
|
||||
{
|
||||
try
|
||||
{
|
||||
int curLevel = Math.Max(info.Login.level, DBM.getAuth(DBM.eAuthType.jobreport));
|
||||
bool canViewOT = string.IsNullOrEmpty(targetUserId) ||
|
||||
targetUserId == info.Login.no ||
|
||||
curLevel >= 5;
|
||||
|
||||
return JsonConvert.SerializeObject(new
|
||||
{
|
||||
Success = true,
|
||||
CurrentUserId = info.Login.no,
|
||||
Level = curLevel,
|
||||
CanViewOT = canViewOT
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -191,8 +191,19 @@ namespace Project.Web
|
||||
{
|
||||
mainForm.OnLoginCompleted();
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (form is Dialog.fDashboard dashForm)
|
||||
{
|
||||
if (dashForm.InvokeRequired)
|
||||
{
|
||||
dashForm.Invoke(new Action(() => dashForm.RefreshPage()));
|
||||
}
|
||||
else
|
||||
{
|
||||
dashForm.RefreshPage();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -258,6 +269,30 @@ namespace Project.Web
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 현재 로그인 상태 확인
|
||||
/// </summary>
|
||||
public string CheckLoginStatus()
|
||||
{
|
||||
var isLoggedIn = !string.IsNullOrEmpty(info.Login.no);
|
||||
var result = new
|
||||
{
|
||||
Success = true,
|
||||
IsLoggedIn = isLoggedIn,
|
||||
User = isLoggedIn ? new
|
||||
{
|
||||
Id = info.Login.no,
|
||||
Name = info.Login.nameK,
|
||||
NameE = info.Login.nameE,
|
||||
Dept = info.Login.dept,
|
||||
Email = info.Login.email,
|
||||
Level = info.Login.level,
|
||||
Gcode = info.Login.gcode
|
||||
} : null
|
||||
};
|
||||
return JsonConvert.SerializeObject(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 그룹 목록 조회
|
||||
/// </summary>
|
||||
@@ -288,6 +323,68 @@ namespace Project.Web
|
||||
return JsonConvert.SerializeObject(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 로그아웃 처리
|
||||
/// </summary>
|
||||
public string Logout()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 로그인 정보 초기화
|
||||
info.Login.no = "";
|
||||
info.Login.nameK = "";
|
||||
info.Login.nameE = "";
|
||||
info.Login.dept = "";
|
||||
info.Login.email = "";
|
||||
info.Login.level = 0;
|
||||
info.Login.gcode = "";
|
||||
info.Login.hp = "";
|
||||
info.Login.tel = "";
|
||||
info.Login.title = "";
|
||||
info.Login.process = "";
|
||||
info.Login.permission = 0;
|
||||
info.Login.gpermission = 0;
|
||||
|
||||
// fMain의 CloseAllForm 호출
|
||||
CallMainFormCloseAllForm();
|
||||
|
||||
return JsonConvert.SerializeObject(new { Success = true, Message = "로그아웃 되었습니다." });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// fMain의 CloseAllForm() 호출
|
||||
/// </summary>
|
||||
private void CallMainFormCloseAllForm()
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (Form form in Application.OpenForms)
|
||||
{
|
||||
if (form is fMain mainForm)
|
||||
{
|
||||
if (mainForm.InvokeRequired)
|
||||
{
|
||||
mainForm.Invoke(new Action(() => mainForm.CloseAllFormPublic()));
|
||||
}
|
||||
else
|
||||
{
|
||||
mainForm.CloseAllFormPublic();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"CloseAllForm 호출 오류: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
200
Project/Web/MachineBridge/MachineBridge.MailForm.cs
Normal file
200
Project/Web/MachineBridge/MachineBridge.MailForm.cs
Normal file
@@ -0,0 +1,200 @@
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using Newtonsoft.Json;
|
||||
using FCOMMON;
|
||||
|
||||
namespace Project.Web
|
||||
{
|
||||
public partial class MachineBridge
|
||||
{
|
||||
#region MailForm API (메일양식)
|
||||
|
||||
/// <summary>
|
||||
/// 메일양식 목록 조회
|
||||
/// </summary>
|
||||
public string MailForm_GetList()
|
||||
{
|
||||
try
|
||||
{
|
||||
var sql = @"SELECT idx, gcode, cate, title, tolist, bcc, cc, subject, tail, body,
|
||||
selfTo, selfCC, selfBCC, wuid, wdate, exceptmail, exceptmailcc
|
||||
FROM MailForm WITH (nolock)
|
||||
WHERE gcode = @gcode
|
||||
ORDER BY cate, title";
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
using (var cn = new SqlConnection(cs))
|
||||
using (var cmd = new SqlCommand(sql, cn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
using (var da = new SqlDataAdapter(cmd))
|
||||
{
|
||||
var dt = new DataTable();
|
||||
da.Fill(dt);
|
||||
return JsonConvert.SerializeObject(new { Success = true, Data = dt });
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 메일양식 상세 조회
|
||||
/// </summary>
|
||||
public string MailForm_GetDetail(int idx)
|
||||
{
|
||||
try
|
||||
{
|
||||
var sql = @"SELECT idx, gcode, cate, title, tolist, bcc, cc, subject, tail, body,
|
||||
selfTo, selfCC, selfBCC, wuid, wdate, exceptmail, exceptmailcc
|
||||
FROM MailForm WITH (nolock)
|
||||
WHERE idx = @idx";
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
using (var cn = new SqlConnection(cs))
|
||||
using (var cmd = new SqlCommand(sql, cn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@idx", idx);
|
||||
using (var da = new SqlDataAdapter(cmd))
|
||||
{
|
||||
var dt = new DataTable();
|
||||
da.Fill(dt);
|
||||
if (dt.Rows.Count > 0)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = true, Data = dt.Rows[0] });
|
||||
}
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "데이터를 찾을 수 없습니다." });
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 메일양식 추가
|
||||
/// </summary>
|
||||
public string MailForm_Add(string cate, string title, string tolist, string bcc, string cc,
|
||||
string subject, string tail, string body, bool selfTo, bool selfCC, bool selfBCC,
|
||||
string exceptmail, string exceptmailcc)
|
||||
{
|
||||
try
|
||||
{
|
||||
var sql = @"INSERT INTO MailForm (gcode, cate, title, tolist, bcc, cc, subject, tail, body,
|
||||
selfTo, selfCC, selfBCC, wuid, wdate, exceptmail, exceptmailcc)
|
||||
VALUES (@gcode, @cate, @title, @tolist, @bcc, @cc, @subject, @tail, @body,
|
||||
@selfTo, @selfCC, @selfBCC, @wuid, GETDATE(), @exceptmail, @exceptmailcc);
|
||||
SELECT SCOPE_IDENTITY();";
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
using (var cn = new SqlConnection(cs))
|
||||
using (var cmd = new SqlCommand(sql, cn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
cmd.Parameters.AddWithValue("@cate", cate ?? "");
|
||||
cmd.Parameters.AddWithValue("@title", title ?? "");
|
||||
cmd.Parameters.AddWithValue("@tolist", tolist ?? "");
|
||||
cmd.Parameters.AddWithValue("@bcc", bcc ?? "");
|
||||
cmd.Parameters.AddWithValue("@cc", cc ?? "");
|
||||
cmd.Parameters.AddWithValue("@subject", subject ?? "");
|
||||
cmd.Parameters.AddWithValue("@tail", tail ?? "");
|
||||
cmd.Parameters.AddWithValue("@body", body ?? "");
|
||||
cmd.Parameters.AddWithValue("@selfTo", selfTo);
|
||||
cmd.Parameters.AddWithValue("@selfCC", selfCC);
|
||||
cmd.Parameters.AddWithValue("@selfBCC", selfBCC);
|
||||
cmd.Parameters.AddWithValue("@wuid", info.Login.no);
|
||||
cmd.Parameters.AddWithValue("@exceptmail", exceptmail ?? "");
|
||||
cmd.Parameters.AddWithValue("@exceptmailcc", exceptmailcc ?? "");
|
||||
|
||||
cn.Open();
|
||||
var newIdx = cmd.ExecuteScalar();
|
||||
return JsonConvert.SerializeObject(new { Success = true, Message = "등록되었습니다.", idx = newIdx });
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 메일양식 수정
|
||||
/// </summary>
|
||||
public string MailForm_Edit(int idx, string cate, string title, string tolist, string bcc, string cc,
|
||||
string subject, string tail, string body, bool selfTo, bool selfCC, bool selfBCC,
|
||||
string exceptmail, string exceptmailcc)
|
||||
{
|
||||
try
|
||||
{
|
||||
var sql = @"UPDATE MailForm SET
|
||||
cate = @cate, title = @title, tolist = @tolist, bcc = @bcc, cc = @cc,
|
||||
subject = @subject, tail = @tail, body = @body,
|
||||
selfTo = @selfTo, selfCC = @selfCC, selfBCC = @selfBCC,
|
||||
wuid = @wuid, wdate = GETDATE(), exceptmail = @exceptmail, exceptmailcc = @exceptmailcc
|
||||
WHERE idx = @idx";
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
using (var cn = new SqlConnection(cs))
|
||||
using (var cmd = new SqlCommand(sql, cn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@idx", idx);
|
||||
cmd.Parameters.AddWithValue("@cate", cate ?? "");
|
||||
cmd.Parameters.AddWithValue("@title", title ?? "");
|
||||
cmd.Parameters.AddWithValue("@tolist", tolist ?? "");
|
||||
cmd.Parameters.AddWithValue("@bcc", bcc ?? "");
|
||||
cmd.Parameters.AddWithValue("@cc", cc ?? "");
|
||||
cmd.Parameters.AddWithValue("@subject", subject ?? "");
|
||||
cmd.Parameters.AddWithValue("@tail", tail ?? "");
|
||||
cmd.Parameters.AddWithValue("@body", body ?? "");
|
||||
cmd.Parameters.AddWithValue("@selfTo", selfTo);
|
||||
cmd.Parameters.AddWithValue("@selfCC", selfCC);
|
||||
cmd.Parameters.AddWithValue("@selfBCC", selfBCC);
|
||||
cmd.Parameters.AddWithValue("@wuid", info.Login.no);
|
||||
cmd.Parameters.AddWithValue("@exceptmail", exceptmail ?? "");
|
||||
cmd.Parameters.AddWithValue("@exceptmailcc", exceptmailcc ?? "");
|
||||
|
||||
cn.Open();
|
||||
cmd.ExecuteNonQuery();
|
||||
return JsonConvert.SerializeObject(new { Success = true, Message = "수정되었습니다." });
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 메일양식 삭제
|
||||
/// </summary>
|
||||
public string MailForm_Delete(int idx)
|
||||
{
|
||||
try
|
||||
{
|
||||
var sql = "DELETE FROM MailForm WHERE idx = @idx";
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
using (var cn = new SqlConnection(cs))
|
||||
using (var cmd = new SqlCommand(sql, cn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@idx", idx);
|
||||
cn.Open();
|
||||
cmd.ExecuteNonQuery();
|
||||
return JsonConvert.SerializeObject(new { Success = true, Message = "삭제되었습니다." });
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -79,6 +79,7 @@ namespace Project.Web
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 할일 추가
|
||||
/// </summary>
|
||||
|
||||
290
Project/Web/MachineBridge/MachineBridge.User.cs
Normal file
290
Project/Web/MachineBridge/MachineBridge.User.cs
Normal file
@@ -0,0 +1,290 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using FCOMMON;
|
||||
|
||||
namespace Project.Web
|
||||
{
|
||||
public partial class MachineBridge
|
||||
{
|
||||
#region User API
|
||||
|
||||
/// <summary>
|
||||
/// 현재 로그인한 사용자 정보 조회
|
||||
/// </summary>
|
||||
public string GetCurrentUserInfo()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(info.Login.no))
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "로그인이 필요합니다." });
|
||||
}
|
||||
|
||||
var taUser = new dsMSSQLTableAdapters.UsersTableAdapter();
|
||||
var taGUser = new dsMSSQLTableAdapters.EETGW_GroupUserTableAdapter();
|
||||
|
||||
var drUser = taUser.GetID(info.Login.no).FirstOrDefault();
|
||||
var drGUser = taGUser.GetbyID(info.Login.gcode, info.Login.no).FirstOrDefault();
|
||||
|
||||
if (drUser == null)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "사용자 정보를 찾을 수 없습니다." });
|
||||
}
|
||||
|
||||
var userInfo = new
|
||||
{
|
||||
Id = drUser.id,
|
||||
NameK = drUser.name,
|
||||
NameE = drUser.nameE,
|
||||
Dept = drUser.dept,
|
||||
Grade = drUser.grade,
|
||||
Email = drUser.email,
|
||||
Tel = drUser.tel,
|
||||
Hp = drUser.hp,
|
||||
DateIn = drUser.indate,
|
||||
DateO = drUser.outdate,
|
||||
Memo = drUser.memo,
|
||||
Process = drGUser?.Process ?? "",
|
||||
State = drGUser?.state ?? "",
|
||||
UseJobReport = drGUser != null && !drGUser.IsuseJobReportNull() && drGUser.useJobReport,
|
||||
UseUserState = drGUser != null && !drGUser.IsuseUserStateNull() && drGUser.useUserState,
|
||||
ExceptHoly = drGUser != null && !drGUser.IsexceptHolyNull() && drGUser.exceptHoly,
|
||||
Level = drGUser?.level ?? 0
|
||||
};
|
||||
|
||||
return JsonConvert.SerializeObject(new { Success = true, Data = userInfo });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "사용자 정보 조회 실패: " + ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 사용자 정보 조회 (ID로)
|
||||
/// </summary>
|
||||
public string GetUserInfoById(string userId)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(userId))
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "사용자 ID를 입력하세요." });
|
||||
}
|
||||
|
||||
var taUser = new dsMSSQLTableAdapters.UsersTableAdapter();
|
||||
var taGUser = new dsMSSQLTableAdapters.EETGW_GroupUserTableAdapter();
|
||||
|
||||
var drUser = taUser.GetID(userId).FirstOrDefault();
|
||||
var drGUser = taGUser.GetbyID(info.Login.gcode, userId).FirstOrDefault();
|
||||
|
||||
if (drUser == null)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "등록된 사용자가 없습니다." });
|
||||
}
|
||||
|
||||
var userInfo = new
|
||||
{
|
||||
Id = drUser.id,
|
||||
NameK = drUser.name,
|
||||
NameE = drUser.nameE,
|
||||
Dept = drUser.dept,
|
||||
Grade = drUser.grade,
|
||||
Email = drUser.email,
|
||||
Tel = drUser.tel,
|
||||
Hp = drUser.hp,
|
||||
DateIn = drUser.indate,
|
||||
DateO = drUser.outdate,
|
||||
Memo = drUser.memo,
|
||||
Process = drGUser?.Process ?? "",
|
||||
State = drGUser?.state ?? "",
|
||||
UseJobReport = drGUser != null && !drGUser.IsuseJobReportNull() && drGUser.useJobReport,
|
||||
UseUserState = drGUser != null && !drGUser.IsuseUserStateNull() && drGUser.useUserState,
|
||||
ExceptHoly = drGUser != null && !drGUser.IsexceptHolyNull() && drGUser.exceptHoly,
|
||||
Level = drGUser?.level ?? 0
|
||||
};
|
||||
|
||||
return JsonConvert.SerializeObject(new { Success = true, Data = userInfo });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "사용자 정보 조회 실패: " + ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 사용자 정보 저장
|
||||
/// </summary>
|
||||
public string SaveUserInfo(string jsonData)
|
||||
{
|
||||
try
|
||||
{
|
||||
var userData = JsonConvert.DeserializeObject<UserInfoData>(jsonData);
|
||||
|
||||
if (userData == null)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "잘못된 데이터 형식입니다." });
|
||||
}
|
||||
|
||||
var gcode = info.Login.gcode;
|
||||
var uid = userData.Id;
|
||||
|
||||
// 현재 사용자 권한 확인
|
||||
int curLevel = Math.Max(info.Login.level, DBM.getAuth(DBM.eAuthType.account));
|
||||
|
||||
// 그룹 사용자 정보 처리
|
||||
var taUserGrp = new dsMSSQLTableAdapters.EETGW_GroupUserTableAdapter();
|
||||
var dtUserGrp = taUserGrp.GetData(gcode);
|
||||
var drGuser = dtUserGrp.Where(t => t.uid == uid).FirstOrDefault();
|
||||
|
||||
if (drGuser != null)
|
||||
{
|
||||
drGuser.Process = userData.Process ?? "";
|
||||
drGuser.state = userData.State ?? "";
|
||||
|
||||
if (curLevel > 4)
|
||||
{
|
||||
drGuser.useJobReport = userData.UseJobReport;
|
||||
drGuser.useUserState = userData.UseUserState;
|
||||
drGuser.exceptHoly = userData.ExceptHoly;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
drGuser = dtUserGrp.NewEETGW_GroupUserRow();
|
||||
drGuser.wuid = info.Login.no;
|
||||
drGuser.wdate = DateTime.Now;
|
||||
drGuser.gcode = gcode;
|
||||
drGuser.level = 1;
|
||||
drGuser.uid = uid;
|
||||
drGuser.state = userData.State ?? "";
|
||||
drGuser.Process = userData.Process ?? "";
|
||||
drGuser.useJobReport = userData.UseJobReport;
|
||||
drGuser.useUserState = userData.UseUserState;
|
||||
drGuser.exceptHoly = userData.ExceptHoly;
|
||||
dtUserGrp.AddEETGW_GroupUserRow(drGuser);
|
||||
}
|
||||
|
||||
// 사용자 정보 처리
|
||||
var tauser = new dsMSSQLTableAdapters.UsersTableAdapter();
|
||||
var dtuser = tauser.GetID(uid);
|
||||
var drUser = dtuser.FirstOrDefault();
|
||||
|
||||
if (drUser == null)
|
||||
{
|
||||
drUser = dtuser.NewUsersRow();
|
||||
drUser.wuid = info.Login.no;
|
||||
drUser.wdate = DateTime.Now;
|
||||
drUser.gcode = gcode;
|
||||
drUser.level = 1;
|
||||
drUser.id = uid;
|
||||
drUser.password = "B6589FC6AB0DC82CF12099D1C2D40AB994E8410C"; // 기본값 0
|
||||
dtuser.AddUsersRow(drUser);
|
||||
}
|
||||
|
||||
drUser.name = userData.NameK ?? "";
|
||||
drUser.nameE = userData.NameE ?? "";
|
||||
drUser.dept = userData.Dept ?? "";
|
||||
drUser.email = userData.Email ?? "";
|
||||
drUser.tel = userData.Tel ?? "";
|
||||
drUser.hp = userData.Hp ?? "";
|
||||
drUser.indate = userData.DateIn ?? "";
|
||||
drUser.outdate = userData.DateO ?? "";
|
||||
drUser.memo = userData.Memo ?? "";
|
||||
drUser.processs = userData.Process ?? "";
|
||||
drUser.grade = userData.Grade ?? "";
|
||||
drUser.EndEdit();
|
||||
|
||||
var cnt1 = taUserGrp.Update(dtUserGrp);
|
||||
var cnt2 = tauser.Update(dtuser);
|
||||
|
||||
taUserGrp.Dispose();
|
||||
tauser.Dispose();
|
||||
|
||||
return JsonConvert.SerializeObject(new { Success = true, Message = "저장되었습니다." });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "저장 실패: " + ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 비밀번호 변경
|
||||
/// </summary>
|
||||
public string ChangePassword(string oldPassword, string newPassword)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(info.Login.no))
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "로그인이 필요합니다." });
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(newPassword))
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "새 비밀번호를 입력하세요." });
|
||||
}
|
||||
|
||||
var uid = info.Login.no;
|
||||
int curLevel = Math.Max(info.Login.level, DBM.getAuth(DBM.eAuthType.account));
|
||||
|
||||
var taUser = new dsMSSQLTableAdapters.UsersTableAdapter();
|
||||
var dtUser = taUser.GetID(uid);
|
||||
var drUser = dtUser.FirstOrDefault();
|
||||
|
||||
if (drUser == null)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "사용자 정보를 찾을 수 없습니다." });
|
||||
}
|
||||
|
||||
// 관리자가 아니면 기존 암호 확인
|
||||
if (curLevel < 5)
|
||||
{
|
||||
var encOldPass = Pub.MakePasswordEnc(oldPassword);
|
||||
if (!encOldPass.Equals(drUser.password))
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "기존 암호가 일치하지 않습니다." });
|
||||
}
|
||||
}
|
||||
|
||||
drUser.password = Pub.MakePasswordEnc(newPassword);
|
||||
drUser.EndEdit();
|
||||
taUser.Update(dtUser);
|
||||
taUser.Dispose();
|
||||
|
||||
return JsonConvert.SerializeObject(new { Success = true, Message = "비밀번호가 변경되었습니다." });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "비밀번호 변경 실패: " + ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 사용자 정보 데이터 클래스
|
||||
/// </summary>
|
||||
public class UserInfoData
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string NameK { get; set; }
|
||||
public string NameE { get; set; }
|
||||
public string Dept { get; set; }
|
||||
public string Grade { get; set; }
|
||||
public string Email { get; set; }
|
||||
public string Tel { get; set; }
|
||||
public string Hp { get; set; }
|
||||
public string DateIn { get; set; }
|
||||
public string DateO { get; set; }
|
||||
public string Memo { get; set; }
|
||||
public string Process { get; set; }
|
||||
public string State { get; set; }
|
||||
public bool UseJobReport { get; set; }
|
||||
public bool UseUserState { get; set; }
|
||||
public bool ExceptHoly { get; set; }
|
||||
}
|
||||
}
|
||||
228
Project/Web/MachineBridge/MachineBridge.UserGroup.cs
Normal file
228
Project/Web/MachineBridge/MachineBridge.UserGroup.cs
Normal file
@@ -0,0 +1,228 @@
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using Newtonsoft.Json;
|
||||
using FCOMMON;
|
||||
|
||||
namespace Project.Web
|
||||
{
|
||||
public partial class MachineBridge
|
||||
{
|
||||
#region UserGroup API (그룹정보/권한설정)
|
||||
|
||||
/// <summary>
|
||||
/// 그룹 목록 조회
|
||||
/// </summary>
|
||||
public string UserGroup_GetList()
|
||||
{
|
||||
try
|
||||
{
|
||||
var sql = @"SELECT dept, gcode, path_kj, permission, advpurchase, advkisul,
|
||||
managerinfo, devinfo, usemail
|
||||
FROM UserGroup WITH (nolock)
|
||||
WHERE gcode = @gcode
|
||||
ORDER BY dept";
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
using (var cn = new SqlConnection(cs))
|
||||
using (var cmd = new SqlCommand(sql, cn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
using (var da = new SqlDataAdapter(cmd))
|
||||
{
|
||||
var dt = new DataTable();
|
||||
da.Fill(dt);
|
||||
return JsonConvert.SerializeObject(new { Success = true, Data = dt });
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 그룹 정보 추가
|
||||
/// </summary>
|
||||
public string UserGroup_Add(string dept, string path_kj, int permission,
|
||||
bool advpurchase, bool advkisul, string managerinfo, string devinfo, bool usemail)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 중복 체크
|
||||
var checkSql = "SELECT COUNT(*) FROM UserGroup WHERE gcode = @gcode AND dept = @dept";
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
|
||||
using (var cn = new SqlConnection(cs))
|
||||
{
|
||||
cn.Open();
|
||||
using (var checkCmd = new SqlCommand(checkSql, cn))
|
||||
{
|
||||
checkCmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
checkCmd.Parameters.AddWithValue("@dept", dept);
|
||||
var count = (int)checkCmd.ExecuteScalar();
|
||||
if (count > 0)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "이미 존재하는 부서명입니다." });
|
||||
}
|
||||
}
|
||||
|
||||
var sql = @"INSERT INTO UserGroup (dept, gcode, path_kj, permission, advpurchase, advkisul, managerinfo, devinfo, usemail)
|
||||
VALUES (@dept, @gcode, @path_kj, @permission, @advpurchase, @advkisul, @managerinfo, @devinfo, @usemail)";
|
||||
|
||||
using (var cmd = new SqlCommand(sql, cn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@dept", dept ?? "");
|
||||
cmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
cmd.Parameters.AddWithValue("@path_kj", path_kj ?? "");
|
||||
cmd.Parameters.AddWithValue("@permission", permission);
|
||||
cmd.Parameters.AddWithValue("@advpurchase", advpurchase);
|
||||
cmd.Parameters.AddWithValue("@advkisul", advkisul);
|
||||
cmd.Parameters.AddWithValue("@managerinfo", managerinfo ?? "");
|
||||
cmd.Parameters.AddWithValue("@devinfo", devinfo ?? "");
|
||||
cmd.Parameters.AddWithValue("@usemail", usemail);
|
||||
cmd.ExecuteNonQuery();
|
||||
return JsonConvert.SerializeObject(new { Success = true, Message = "등록되었습니다." });
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 그룹 정보 수정
|
||||
/// </summary>
|
||||
public string UserGroup_Edit(string originalDept, string dept, string path_kj, int permission,
|
||||
bool advpurchase, bool advkisul, string managerinfo, string devinfo, bool usemail)
|
||||
{
|
||||
try
|
||||
{
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
using (var cn = new SqlConnection(cs))
|
||||
{
|
||||
cn.Open();
|
||||
|
||||
// 부서명이 변경되었을 경우 중복 체크
|
||||
if (originalDept != dept)
|
||||
{
|
||||
var checkSql = "SELECT COUNT(*) FROM UserGroup WHERE gcode = @gcode AND dept = @dept";
|
||||
using (var checkCmd = new SqlCommand(checkSql, cn))
|
||||
{
|
||||
checkCmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
checkCmd.Parameters.AddWithValue("@dept", dept);
|
||||
var count = (int)checkCmd.ExecuteScalar();
|
||||
if (count > 0)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "이미 존재하는 부서명입니다." });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var sql = @"UPDATE UserGroup SET
|
||||
dept = @dept, path_kj = @path_kj, permission = @permission,
|
||||
advpurchase = @advpurchase, advkisul = @advkisul,
|
||||
managerinfo = @managerinfo, devinfo = @devinfo, usemail = @usemail
|
||||
WHERE gcode = @gcode AND dept = @originalDept";
|
||||
|
||||
using (var cmd = new SqlCommand(sql, cn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@originalDept", originalDept);
|
||||
cmd.Parameters.AddWithValue("@dept", dept ?? "");
|
||||
cmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
cmd.Parameters.AddWithValue("@path_kj", path_kj ?? "");
|
||||
cmd.Parameters.AddWithValue("@permission", permission);
|
||||
cmd.Parameters.AddWithValue("@advpurchase", advpurchase);
|
||||
cmd.Parameters.AddWithValue("@advkisul", advkisul);
|
||||
cmd.Parameters.AddWithValue("@managerinfo", managerinfo ?? "");
|
||||
cmd.Parameters.AddWithValue("@devinfo", devinfo ?? "");
|
||||
cmd.Parameters.AddWithValue("@usemail", usemail);
|
||||
cmd.ExecuteNonQuery();
|
||||
return JsonConvert.SerializeObject(new { Success = true, Message = "수정되었습니다." });
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 그룹 삭제
|
||||
/// </summary>
|
||||
public string UserGroup_Delete(string dept)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 해당 그룹에 소속된 사용자가 있는지 확인
|
||||
var checkSql = "SELECT COUNT(*) FROM GroupUser WHERE gcode = @gcode AND dept = @dept";
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
|
||||
using (var cn = new SqlConnection(cs))
|
||||
{
|
||||
cn.Open();
|
||||
|
||||
using (var checkCmd = new SqlCommand(checkSql, cn))
|
||||
{
|
||||
checkCmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
checkCmd.Parameters.AddWithValue("@dept", dept);
|
||||
var count = (int)checkCmd.ExecuteScalar();
|
||||
if (count > 0)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = $"해당 그룹에 {count}명의 사용자가 소속되어 있어 삭제할 수 없습니다." });
|
||||
}
|
||||
}
|
||||
|
||||
var sql = "DELETE FROM UserGroup WHERE gcode = @gcode AND dept = @dept";
|
||||
using (var cmd = new SqlCommand(sql, cn))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
cmd.Parameters.AddWithValue("@dept", dept);
|
||||
cmd.ExecuteNonQuery();
|
||||
return JsonConvert.SerializeObject(new { Success = true, Message = "삭제되었습니다." });
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 권한 정보 목록 (프론트엔드용)
|
||||
/// </summary>
|
||||
public string UserGroup_GetPermissionInfo()
|
||||
{
|
||||
try
|
||||
{
|
||||
var permissions = new[]
|
||||
{
|
||||
new { index = 0, name = "menu_purchase", label = "구매신청", description = "구매신청 메뉴 표시" },
|
||||
new { index = 1, name = "menu_project", label = "프로젝트", description = "프로젝트 메뉴 표시" },
|
||||
new { index = 2, name = "menu_history", label = "업무일지", description = "업무일지 메뉴 표시" },
|
||||
new { index = 3, name = "menu_jago", label = "품목재고", description = "품목재고 메뉴 표시" },
|
||||
new { index = 4, name = "menu_equipment", label = "장비목록", description = "장비목록 메뉴 표시" },
|
||||
new { index = 5, name = "menu_workday", label = "근태관리", description = "근태관리 메뉴 표시" },
|
||||
new { index = 6, name = "purchase_adv", label = "(구매)상세입력", description = "구매신청 상세입력 권한" },
|
||||
new { index = 7, name = "menu_docu", label = "문서", description = "문서 메뉴 표시" },
|
||||
new { index = 8, name = "menu_logdata", label = "운영기록", description = "운영기록 메뉴 표시" },
|
||||
new { index = 9, name = "jobreport_kisul", label = "업무일지-기술료", description = "업무일지 기술료 보기 권한" },
|
||||
new { index = 10, name = "jobreport_editblock", label = "업무일지-편집제한", description = "업무일지 편집 제한" },
|
||||
};
|
||||
|
||||
return JsonConvert.SerializeObject(new { Success = true, Data = permissions });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
378
Project/Web/MachineBridge/MachineBridge.UserList.cs
Normal file
378
Project/Web/MachineBridge/MachineBridge.UserList.cs
Normal file
@@ -0,0 +1,378 @@
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using Newtonsoft.Json;
|
||||
using FCOMMON;
|
||||
|
||||
namespace Project.Web
|
||||
{
|
||||
public partial class MachineBridge
|
||||
{
|
||||
#region UserList API
|
||||
|
||||
/// <summary>
|
||||
/// 현재 사용자 권한 레벨 조회 (로그인 레벨 + account 권한 중 높은 값)
|
||||
/// </summary>
|
||||
public string UserList_GetCurrentLevel()
|
||||
{
|
||||
try
|
||||
{
|
||||
int curLevel = Math.Max(info.Login.level, FCOMMON.DBM.getAuth(FCOMMON.DBM.eAuthType.account));
|
||||
return JsonConvert.SerializeObject(new
|
||||
{
|
||||
Success = true,
|
||||
Data = new
|
||||
{
|
||||
Level = curLevel,
|
||||
CurrentUserId = info.Login.no,
|
||||
CanEdit = curLevel >= 5
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "권한 조회 실패: " + ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 부서 목록 조회
|
||||
/// </summary>
|
||||
public string UserList_GetDepts()
|
||||
{
|
||||
try
|
||||
{
|
||||
var sql = "SELECT DISTINCT dept FROM UserGroup WITH (NOLOCK) WHERE gcode = @gcode AND ISNULL(dept,'') <> '' ORDER BY dept";
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
var cn = new SqlConnection(cs);
|
||||
var cmd = new SqlCommand(sql, cn);
|
||||
cmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
|
||||
var da = new SqlDataAdapter(cmd);
|
||||
var dt = new DataTable();
|
||||
da.Fill(dt);
|
||||
da.Dispose();
|
||||
cmd.Dispose();
|
||||
cn.Dispose();
|
||||
|
||||
var result = new System.Collections.Generic.List<string>();
|
||||
foreach (DataRow dr in dt.Rows)
|
||||
{
|
||||
result.Add(dr["dept"]?.ToString() ?? "");
|
||||
}
|
||||
|
||||
return JsonConvert.SerializeObject(new { Success = true, Data = result });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "부서 조회 실패: " + ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 사용자 목록 조회
|
||||
/// </summary>
|
||||
public string UserList_GetList(string process)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(process) || process == "%") process = "%";
|
||||
else process = "%" + process + "%";
|
||||
|
||||
var gcode = info.Login.gcode;
|
||||
System.Diagnostics.Debug.WriteLine($"[UserList_GetList] gcode={gcode}, process={process}");
|
||||
|
||||
var sql = @"SELECT gcode, dept, level, name, nameE, grade, email, tel, indate, outdate, hp,
|
||||
memo, processs, id, state, useJobReport, useUserState, exceptHoly
|
||||
FROM vGroupUser WITH (NOLOCK)
|
||||
WHERE gcode = @gcode
|
||||
AND ISNULL(processs,'') LIKE @process
|
||||
ORDER BY useUserState DESC, useJobReport DESC, name";
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
var cn = new SqlConnection(cs);
|
||||
var cmd = new SqlCommand(sql, cn);
|
||||
cmd.Parameters.AddWithValue("@gcode", gcode);
|
||||
cmd.Parameters.AddWithValue("@process", process);
|
||||
|
||||
var da = new SqlDataAdapter(cmd);
|
||||
var dt = new DataTable();
|
||||
da.Fill(dt);
|
||||
|
||||
System.Diagnostics.Debug.WriteLine($"[UserList_GetList] 결과 행 수: {dt.Rows.Count}");
|
||||
|
||||
da.Dispose();
|
||||
cmd.Dispose();
|
||||
cn.Dispose();
|
||||
|
||||
return JsonConvert.SerializeObject(dt, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "사용자 목록 조회 실패: " + ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 사용자 상세 정보 조회
|
||||
/// </summary>
|
||||
public string UserList_GetUser(string userId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var sql = @"SELECT
|
||||
u.id,
|
||||
u.name,
|
||||
u.nameE,
|
||||
u.grade,
|
||||
u.email,
|
||||
u.tel,
|
||||
u.indate,
|
||||
u.outdate,
|
||||
u.hp,
|
||||
u.processs,
|
||||
u.state,
|
||||
u.memo,
|
||||
gu.level,
|
||||
gu.useUserState,
|
||||
gu.useJobReport,
|
||||
gu.exceptHoly,
|
||||
gu.dept,
|
||||
gu.gcode
|
||||
FROM EETGW_GroupUser gu WITH (NOLOCK)
|
||||
INNER JOIN Users u WITH (NOLOCK) ON gu.uid = u.id
|
||||
WHERE gu.gcode = @gcode AND gu.uid = @uid";
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
var cn = new SqlConnection(cs);
|
||||
var cmd = new SqlCommand(sql, cn);
|
||||
cmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
cmd.Parameters.AddWithValue("@uid", userId);
|
||||
|
||||
var da = new SqlDataAdapter(cmd);
|
||||
var dt = new DataTable();
|
||||
da.Fill(dt);
|
||||
da.Dispose();
|
||||
cmd.Dispose();
|
||||
cn.Dispose();
|
||||
|
||||
if (dt.Rows.Count > 0)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = true, Data = dt.Rows[0] },
|
||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
||||
}
|
||||
else
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "사용자를 찾을 수 없습니다." });
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "사용자 조회 실패: " + ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 사용자 전체 정보 저장 (Users + GroupUser)
|
||||
/// </summary>
|
||||
public string UserList_SaveUserFull(string jsonData)
|
||||
{
|
||||
try
|
||||
{
|
||||
var userData = JsonConvert.DeserializeObject<UserListFullData>(jsonData);
|
||||
if (userData == null)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "잘못된 데이터 형식입니다." });
|
||||
}
|
||||
|
||||
// 권한 체크
|
||||
int curLevel = Math.Max(info.Login.level, FCOMMON.DBM.getAuth(FCOMMON.DBM.eAuthType.account));
|
||||
bool isSelf = info.Login.no == userData.id;
|
||||
|
||||
// 본인이 아니고 권한이 없으면 거부
|
||||
if (!isSelf && curLevel < 5)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "타인의 계정은 편집할 수 없습니다." });
|
||||
}
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
using (var cn = new SqlConnection(cs))
|
||||
{
|
||||
cn.Open();
|
||||
|
||||
// Users 테이블 업데이트
|
||||
var sqlUser = @"UPDATE Users SET
|
||||
name = @name,
|
||||
nameE = @nameE,
|
||||
grade = @grade,
|
||||
email = @email,
|
||||
tel = @tel,
|
||||
hp = @hp,
|
||||
indate = @indate,
|
||||
outdate = @outdate,
|
||||
memo = @memo,
|
||||
processs = @processs,
|
||||
state = @state
|
||||
WHERE id = @id";
|
||||
|
||||
using (var cmdUser = new SqlCommand(sqlUser, cn))
|
||||
{
|
||||
cmdUser.Parameters.AddWithValue("@id", userData.id);
|
||||
cmdUser.Parameters.AddWithValue("@name", userData.name ?? "");
|
||||
cmdUser.Parameters.AddWithValue("@nameE", userData.nameE ?? "");
|
||||
cmdUser.Parameters.AddWithValue("@grade", userData.grade ?? "");
|
||||
cmdUser.Parameters.AddWithValue("@email", userData.email ?? "");
|
||||
cmdUser.Parameters.AddWithValue("@tel", userData.tel ?? "");
|
||||
cmdUser.Parameters.AddWithValue("@hp", userData.hp ?? "");
|
||||
cmdUser.Parameters.AddWithValue("@indate", userData.indate ?? "");
|
||||
cmdUser.Parameters.AddWithValue("@outdate", userData.outdate ?? "");
|
||||
cmdUser.Parameters.AddWithValue("@memo", userData.memo ?? "");
|
||||
cmdUser.Parameters.AddWithValue("@processs", userData.processs ?? "");
|
||||
cmdUser.Parameters.AddWithValue("@state", userData.state ?? "");
|
||||
cmdUser.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
// EETGW_GroupUser 테이블 업데이트 (관리자만)
|
||||
if (curLevel >= 5)
|
||||
{
|
||||
var sqlGroup = @"UPDATE EETGW_GroupUser SET
|
||||
level = @level,
|
||||
useUserState = @useUserState,
|
||||
useJobReport = @useJobReport,
|
||||
exceptHoly = @exceptHoly
|
||||
WHERE gcode = @gcode AND uid = @uid";
|
||||
|
||||
using (var cmdGroup = new SqlCommand(sqlGroup, cn))
|
||||
{
|
||||
cmdGroup.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
cmdGroup.Parameters.AddWithValue("@uid", userData.id);
|
||||
cmdGroup.Parameters.AddWithValue("@level", userData.level);
|
||||
cmdGroup.Parameters.AddWithValue("@useUserState", userData.useUserState);
|
||||
cmdGroup.Parameters.AddWithValue("@useJobReport", userData.useJobReport);
|
||||
cmdGroup.Parameters.AddWithValue("@exceptHoly", userData.exceptHoly);
|
||||
cmdGroup.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return JsonConvert.SerializeObject(new { Success = true, Message = "저장되었습니다." });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "저장 실패: " + ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 사용자 저장 (그룹 설정만)
|
||||
/// </summary>
|
||||
public string UserList_SaveGroupUser(string userId, string dept, int level, bool useUserState, bool useJobReport, bool exceptHoly)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 권한 체크
|
||||
int curLevel = Math.Max(info.Login.level, FCOMMON.DBM.getAuth(FCOMMON.DBM.eAuthType.account));
|
||||
if (curLevel < 5)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "사용자 관리 권한이 없습니다." });
|
||||
}
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
var cn = new SqlConnection(cs);
|
||||
|
||||
var sql = @"UPDATE EETGW_GroupUser SET
|
||||
dept = @dept,
|
||||
level = @level,
|
||||
useUserState = @useUserState,
|
||||
useJobReport = @useJobReport,
|
||||
exceptHoly = @exceptHoly
|
||||
WHERE gcode = @gcode AND uid = @uid";
|
||||
|
||||
var cmd = new SqlCommand(sql, cn);
|
||||
cmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
cmd.Parameters.AddWithValue("@uid", userId);
|
||||
cmd.Parameters.AddWithValue("@dept", dept ?? "");
|
||||
cmd.Parameters.AddWithValue("@level", level);
|
||||
cmd.Parameters.AddWithValue("@useUserState", useUserState);
|
||||
cmd.Parameters.AddWithValue("@useJobReport", useJobReport);
|
||||
cmd.Parameters.AddWithValue("@exceptHoly", exceptHoly);
|
||||
|
||||
cn.Open();
|
||||
var result = cmd.ExecuteNonQuery();
|
||||
cn.Close();
|
||||
|
||||
cmd.Dispose();
|
||||
cn.Dispose();
|
||||
|
||||
return JsonConvert.SerializeObject(new { Success = result > 0, Message = result > 0 ? "저장되었습니다." : "저장에 실패했습니다." });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "저장 실패: " + ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 사용자 삭제 (그룹에서 제거)
|
||||
/// </summary>
|
||||
public string UserList_DeleteGroupUser(string userId)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 권한 체크
|
||||
int curLevel = Math.Max(info.Login.level, FCOMMON.DBM.getAuth(FCOMMON.DBM.eAuthType.account));
|
||||
if (curLevel < 5)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "계정 관리자만 사용할 수 있습니다." });
|
||||
}
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
var cn = new SqlConnection(cs);
|
||||
var sql = "DELETE FROM EETGW_GroupUser WHERE gcode = @gcode AND uid = @uid";
|
||||
var cmd = new SqlCommand(sql, cn);
|
||||
|
||||
cmd.Parameters.AddWithValue("@gcode", info.Login.gcode);
|
||||
cmd.Parameters.AddWithValue("@uid", userId);
|
||||
|
||||
cn.Open();
|
||||
var result = cmd.ExecuteNonQuery();
|
||||
cn.Close();
|
||||
|
||||
cmd.Dispose();
|
||||
cn.Dispose();
|
||||
|
||||
return JsonConvert.SerializeObject(new { Success = result > 0, Message = result > 0 ? "삭제되었습니다." : "삭제에 실패했습니다." });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = "삭제 실패: " + ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 사용자 전체 정보 데이터 클래스
|
||||
/// </summary>
|
||||
public class UserListFullData
|
||||
{
|
||||
public string id { get; set; }
|
||||
public string name { get; set; }
|
||||
public string nameE { get; set; }
|
||||
public string grade { get; set; }
|
||||
public string email { get; set; }
|
||||
public string tel { get; set; }
|
||||
public string hp { get; set; }
|
||||
public string indate { get; set; }
|
||||
public string outdate { get; set; }
|
||||
public string memo { get; set; }
|
||||
public string processs { get; set; }
|
||||
public string state { get; set; }
|
||||
public int level { get; set; }
|
||||
public bool useUserState { get; set; }
|
||||
public bool useJobReport { get; set; }
|
||||
public bool exceptHoly { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -20,12 +20,102 @@ namespace Project.Web
|
||||
public partial class MachineBridge
|
||||
{
|
||||
// Reference to the main form to update logic
|
||||
private Dialog.fDashboardNew _host;
|
||||
private Dialog.fDashboard _host;
|
||||
|
||||
public MachineBridge(Dialog.fDashboardNew host)
|
||||
// WebSocket 서버 인스턴스
|
||||
private static Project.Web.WebSocketServer _wsServer;
|
||||
private static readonly object _wsLock = new object();
|
||||
|
||||
private const int WS_PORT = 8082;
|
||||
|
||||
public MachineBridge(Dialog.fDashboard host)
|
||||
{
|
||||
_host = host;
|
||||
StartWebSocketServer();
|
||||
}
|
||||
|
||||
#region WebSocket Server Control
|
||||
|
||||
/// <summary>
|
||||
/// WebSocket 서버 시작
|
||||
/// </summary>
|
||||
private void StartWebSocketServer()
|
||||
{
|
||||
lock (_wsLock)
|
||||
{
|
||||
if (_wsServer != null)
|
||||
{
|
||||
Console.WriteLine("[WS] WebSocket server already running");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
string url = $"http://localhost:{WS_PORT}/";
|
||||
_wsServer = new Project.Web.WebSocketServer(url, this);
|
||||
_wsServer.Start();
|
||||
Console.WriteLine($"[WS] WebSocket server started on port {WS_PORT}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"[WS] Failed to start WebSocket server: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WebSocket 서버 중지
|
||||
/// </summary>
|
||||
public static void StopWebSocketServer()
|
||||
{
|
||||
lock (_wsLock)
|
||||
{
|
||||
if (_wsServer != null)
|
||||
{
|
||||
_wsServer.Stop();
|
||||
_wsServer = null;
|
||||
Console.WriteLine("[WS] WebSocket server stopped");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WebSocket 서버 실행 여부 확인
|
||||
/// </summary>
|
||||
public static bool IsWebSocketServerRunning()
|
||||
{
|
||||
lock (_wsLock)
|
||||
{
|
||||
return _wsServer != null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region App Info
|
||||
|
||||
/// <summary>
|
||||
/// 애플리케이션 버전 정보 반환
|
||||
/// </summary>
|
||||
public string GetAppVersion()
|
||||
{
|
||||
try
|
||||
{
|
||||
return JsonConvert.SerializeObject(new
|
||||
{
|
||||
Success = true,
|
||||
ProductName = Application.ProductName,
|
||||
ProductVersion = Application.ProductVersion,
|
||||
DisplayVersion = $"{Application.ProductName} v{Application.ProductVersion}"
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
705
Project/Web/MachineBridge/WebSocketServer.cs
Normal file
705
Project/Web/MachineBridge/WebSocketServer.cs
Normal file
@@ -0,0 +1,705 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.WebSockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Project.Web
|
||||
{
|
||||
/// <summary>
|
||||
/// GroupWare WebSocket 서버
|
||||
/// npm run dev 환경에서 핫 리로드 개발을 위한 WebSocket 통신 지원
|
||||
/// </summary>
|
||||
public class WebSocketServer
|
||||
{
|
||||
private HttpListener _httpListener;
|
||||
private List<WebSocket> _clients = new List<WebSocket>();
|
||||
private ConcurrentDictionary<WebSocket, SemaphoreSlim> _socketLocks = new ConcurrentDictionary<WebSocket, SemaphoreSlim>();
|
||||
private MachineBridge _bridge;
|
||||
private bool _isRunning = false;
|
||||
|
||||
public WebSocketServer(string url, MachineBridge bridge)
|
||||
{
|
||||
_bridge = bridge;
|
||||
_httpListener = new HttpListener();
|
||||
_httpListener.Prefixes.Add(url);
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
if (_isRunning) return;
|
||||
|
||||
try
|
||||
{
|
||||
_httpListener.Start();
|
||||
_isRunning = true;
|
||||
Console.WriteLine($"[WS] GroupWare WebSocket Server Started");
|
||||
Task.Run(AcceptConnections);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"[WS] Start Error: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
_isRunning = false;
|
||||
try
|
||||
{
|
||||
_httpListener.Stop();
|
||||
_httpListener.Close();
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
private async Task AcceptConnections()
|
||||
{
|
||||
while (_httpListener.IsListening && _isRunning)
|
||||
{
|
||||
try
|
||||
{
|
||||
var context = await _httpListener.GetContextAsync();
|
||||
if (context.Request.IsWebSocketRequest)
|
||||
{
|
||||
ProcessRequest(context);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Response.StatusCode = 400;
|
||||
context.Response.Close();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (_isRunning)
|
||||
Console.WriteLine($"[WS] Accept Error: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async void ProcessRequest(HttpListenerContext context)
|
||||
{
|
||||
WebSocketContext wsContext = null;
|
||||
try
|
||||
{
|
||||
wsContext = await context.AcceptWebSocketAsync(subProtocol: null);
|
||||
WebSocket socket = wsContext.WebSocket;
|
||||
_socketLocks.TryAdd(socket, new SemaphoreSlim(1, 1));
|
||||
|
||||
lock (_clients) { _clients.Add(socket); }
|
||||
Console.WriteLine("[WS] Client Connected");
|
||||
|
||||
await ReceiveLoop(socket);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"[WS] Process Error: {ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (wsContext != null)
|
||||
{
|
||||
WebSocket socket = wsContext.WebSocket;
|
||||
lock (_clients) { _clients.Remove(socket); }
|
||||
|
||||
if (_socketLocks.TryRemove(socket, out var semaphore))
|
||||
{
|
||||
semaphore.Dispose();
|
||||
}
|
||||
socket.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ReceiveLoop(WebSocket socket)
|
||||
{
|
||||
var buffer = new byte[1024 * 4];
|
||||
while (socket.State == WebSocketState.Open && _isRunning)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
|
||||
if (result.MessageType == WebSocketMessageType.Close)
|
||||
{
|
||||
await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None);
|
||||
}
|
||||
else if (result.MessageType == WebSocketMessageType.Text)
|
||||
{
|
||||
string msg = Encoding.UTF8.GetString(buffer, 0, result.Count);
|
||||
await HandleMessage(msg, socket);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task HandleMessage(string msg, WebSocket socket)
|
||||
{
|
||||
try
|
||||
{
|
||||
dynamic json = JsonConvert.DeserializeObject(msg);
|
||||
string type = json.type;
|
||||
|
||||
Console.WriteLine($"[WS] Message: {type}");
|
||||
|
||||
switch (type)
|
||||
{
|
||||
// ===== Todo API =====
|
||||
case "GET_TODOS":
|
||||
{
|
||||
string result = _bridge.Todo_GetTodos();
|
||||
var response = new { type = "TODOS_DATA", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "GET_TODO":
|
||||
{
|
||||
int id = json.id;
|
||||
string result = _bridge.GetTodo(id);
|
||||
var response = new { type = "TODO_DATA", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "CREATE_TODO":
|
||||
{
|
||||
string title = json.title ?? "";
|
||||
string remark = json.remark ?? "";
|
||||
string expire = json.expire;
|
||||
int seqno = json.seqno ?? 0;
|
||||
bool flag = json.flag ?? false;
|
||||
string request = json.request;
|
||||
string status = json.status ?? "0";
|
||||
|
||||
string result = _bridge.CreateTodo(title, remark, expire, seqno, flag, request, status);
|
||||
var response = new { type = "TODO_CREATED", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "UPDATE_TODO":
|
||||
{
|
||||
int idx = json.idx;
|
||||
string title = json.title ?? "";
|
||||
string remark = json.remark ?? "";
|
||||
string expire = json.expire;
|
||||
int seqno = json.seqno ?? 0;
|
||||
bool flag = json.flag ?? false;
|
||||
string request = json.request;
|
||||
string status = json.status ?? "0";
|
||||
|
||||
string result = _bridge.Todo_UpdateTodo(idx, title, remark, expire, seqno, flag, request, status);
|
||||
var response = new { type = "TODO_UPDATED", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "DELETE_TODO":
|
||||
{
|
||||
int id = json.id;
|
||||
string result = _bridge.Todo_DeleteTodo(id);
|
||||
var response = new { type = "TODO_DELETED", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "GET_URGENT_TODOS":
|
||||
{
|
||||
string result = _bridge.GetUrgentTodos();
|
||||
var response = new { type = "URGENT_TODOS_DATA", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
// ===== Dashboard API =====
|
||||
case "GET_PURCHASE_WAIT_COUNT":
|
||||
{
|
||||
string result = _bridge.GetPurchaseWaitCount();
|
||||
var response = new { type = "PURCHASE_WAIT_COUNT_DATA", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "GET_TODAY_COUNT_H":
|
||||
{
|
||||
string result = _bridge.TodayCountH();
|
||||
var response = new { type = "TODAY_COUNT_H_DATA", count = int.Parse(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "GET_HOLY_USER":
|
||||
{
|
||||
string result = _bridge.GetHolyUser();
|
||||
var response = new { type = "HOLY_USER_DATA", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "GET_HOLY_REQUEST_USER":
|
||||
{
|
||||
string result = _bridge.GetHolyRequestUser();
|
||||
var response = new { type = "HOLY_REQUEST_USER_DATA", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "GET_PURCHASE_NR_LIST":
|
||||
{
|
||||
string result = _bridge.GetPurchaseNRList();
|
||||
var response = new { type = "PURCHASE_NR_LIST_DATA", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "GET_PURCHASE_CR_LIST":
|
||||
{
|
||||
string result = _bridge.GetPurchaseCRList();
|
||||
var response = new { type = "PURCHASE_CR_LIST_DATA", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "GET_HOLYDAY_REQUEST_COUNT":
|
||||
{
|
||||
string result = _bridge.GetHolydayRequestCount();
|
||||
var response = new { type = "HOLYDAY_REQUEST_COUNT_DATA", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "GET_CURRENT_USER_COUNT":
|
||||
{
|
||||
string result = _bridge.GetCurrentUserCount();
|
||||
var response = new { type = "CURRENT_USER_COUNT_DATA", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
// ===== Login API =====
|
||||
case "CHECK_LOGIN_STATUS":
|
||||
{
|
||||
string result = _bridge.CheckLoginStatus();
|
||||
var response = new { type = "LOGIN_STATUS_DATA", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "LOGIN":
|
||||
{
|
||||
string gcode = json.gcode ?? "";
|
||||
string id = json.id ?? "";
|
||||
string password = json.password ?? "";
|
||||
bool rememberMe = json.rememberMe ?? false;
|
||||
string result = _bridge.Login(gcode, id, password, rememberMe);
|
||||
var response = new { type = "LOGIN_RESULT", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "LOGOUT":
|
||||
{
|
||||
string result = _bridge.Logout();
|
||||
var response = new { type = "LOGOUT_RESULT", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "GET_USER_GROUPS":
|
||||
{
|
||||
string result = _bridge.GetUserGroups();
|
||||
var response = new { type = "USER_GROUPS_DATA", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "GET_PREVIOUS_LOGIN_INFO":
|
||||
{
|
||||
string result = _bridge.GetPreviousLoginInfo();
|
||||
var response = new { type = "PREVIOUS_LOGIN_INFO_DATA", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
// ===== User API =====
|
||||
case "GET_CURRENT_USER_INFO":
|
||||
{
|
||||
string result = _bridge.GetCurrentUserInfo();
|
||||
var response = new { type = "CURRENT_USER_INFO_DATA", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "GET_USER_INFO_BY_ID":
|
||||
{
|
||||
string userId = json.userId ?? "";
|
||||
string result = _bridge.GetUserInfoById(userId);
|
||||
var response = new { type = "USER_INFO_DATA", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "SAVE_USER_INFO":
|
||||
{
|
||||
string userData = JsonConvert.SerializeObject(json.userData);
|
||||
string result = _bridge.SaveUserInfo(userData);
|
||||
var response = new { type = "USER_INFO_SAVED", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "CHANGE_PASSWORD":
|
||||
{
|
||||
string oldPassword = json.oldPassword ?? "";
|
||||
string newPassword = json.newPassword ?? "";
|
||||
string result = _bridge.ChangePassword(oldPassword, newPassword);
|
||||
var response = new { type = "PASSWORD_CHANGED", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
// ===== Common Code API =====
|
||||
case "COMMON_GET_GROUPS":
|
||||
{
|
||||
string result = _bridge.Common_GetGroups();
|
||||
var response = new { type = "COMMON_GROUPS_DATA", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "COMMON_GET_LIST":
|
||||
{
|
||||
string grp = json.grp ?? "99";
|
||||
string result = _bridge.Common_GetList(grp);
|
||||
var response = new { type = "COMMON_LIST_DATA", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "COMMON_SAVE":
|
||||
{
|
||||
int idx = json.idx ?? 0;
|
||||
string grp = json.grp ?? "";
|
||||
string code = json.code ?? "";
|
||||
string svalue = json.svalue ?? "";
|
||||
int ivalue = json.ivalue ?? 0;
|
||||
float fvalue = json.fvalue ?? 0f;
|
||||
string svalue2 = json.svalue2 ?? "";
|
||||
string memo = json.memo ?? "";
|
||||
string result = _bridge.Common_Save(idx, grp, code, svalue, ivalue, fvalue, svalue2, memo);
|
||||
var response = new { type = "COMMON_SAVED", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "COMMON_DELETE":
|
||||
{
|
||||
int idx = json.idx ?? 0;
|
||||
string result = _bridge.Common_Delete(idx);
|
||||
var response = new { type = "COMMON_DELETED", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
// ===== Items API =====
|
||||
case "ITEMS_GET_CATEGORIES":
|
||||
{
|
||||
string result = _bridge.Items_GetCategories();
|
||||
var response = new { type = "ITEMS_CATEGORIES_DATA", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "ITEMS_GET_LIST":
|
||||
{
|
||||
string category = json.category ?? "";
|
||||
string searchKey = json.searchKey ?? "";
|
||||
string result = _bridge.Items_GetList(category, searchKey);
|
||||
var response = new { type = "ITEMS_LIST_DATA", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "ITEMS_SAVE":
|
||||
{
|
||||
int idx = json.idx ?? 0;
|
||||
string sid = json.sid ?? "";
|
||||
string cate = json.cate ?? "";
|
||||
string name = json.name ?? "";
|
||||
string model = json.model ?? "";
|
||||
string scale = json.scale ?? "";
|
||||
string unit = json.unit ?? "";
|
||||
decimal price = json.price ?? 0m;
|
||||
string supply = json.supply ?? "";
|
||||
string manu = json.manu ?? "";
|
||||
string storage = json.storage ?? "";
|
||||
bool disable = json.disable ?? false;
|
||||
string memo = json.memo ?? "";
|
||||
string result = _bridge.Items_Save(idx, sid, cate, name, model, scale, unit, price, supply, manu, storage, disable, memo);
|
||||
var response = new { type = "ITEMS_SAVED", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "ITEMS_DELETE":
|
||||
{
|
||||
int idx = json.idx ?? 0;
|
||||
string result = _bridge.Items_Delete(idx);
|
||||
var response = new { type = "ITEMS_DELETED", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
// ===== UserList API =====
|
||||
case "USERLIST_GET_CURRENT_LEVEL":
|
||||
{
|
||||
string result = _bridge.UserList_GetCurrentLevel();
|
||||
var response = new { type = "USERLIST_CURRENT_LEVEL_DATA", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "USERLIST_GET_DEPTS":
|
||||
{
|
||||
string result = _bridge.UserList_GetDepts();
|
||||
var response = new { type = "USERLIST_DEPTS_DATA", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "USERLIST_GET_LIST":
|
||||
{
|
||||
string process = json.process ?? "%";
|
||||
string result = _bridge.UserList_GetList(process);
|
||||
var response = new { type = "USERLIST_LIST_DATA", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "USERLIST_GET_USER":
|
||||
{
|
||||
string userId = json.userId ?? "";
|
||||
string result = _bridge.UserList_GetUser(userId);
|
||||
var response = new { type = "USERLIST_USER_DATA", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "USERLIST_SAVE_GROUP_USER":
|
||||
{
|
||||
string userId = json.userId ?? "";
|
||||
string dept = json.dept ?? "";
|
||||
int level = json.level ?? 1;
|
||||
bool useUserState = json.useUserState ?? false;
|
||||
bool useJobReport = json.useJobReport ?? false;
|
||||
bool exceptHoly = json.exceptHoly ?? false;
|
||||
string result = _bridge.UserList_SaveGroupUser(userId, dept, level, useUserState, useJobReport, exceptHoly);
|
||||
var response = new { type = "USERLIST_SAVED", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "USERLIST_SAVE_USER_FULL":
|
||||
{
|
||||
string userData = JsonConvert.SerializeObject(json.userData);
|
||||
string result = _bridge.UserList_SaveUserFull(userData);
|
||||
var response = new { type = "USERLIST_USER_FULL_SAVED", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "USERLIST_DELETE_GROUP_USER":
|
||||
{
|
||||
string userId = json.userId ?? "";
|
||||
string result = _bridge.UserList_DeleteGroupUser(userId);
|
||||
var response = new { type = "USERLIST_DELETED", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
// ===== JobReport API (JobReport 뷰/테이블) =====
|
||||
case "JOBREPORT_GET_LIST":
|
||||
{
|
||||
string sd = json.sd ?? "";
|
||||
string ed = json.ed ?? "";
|
||||
string uid = json.uid ?? "";
|
||||
string cate = json.cate ?? ""; // 사용안함 (호환성)
|
||||
string searchKey = json.searchKey ?? "";
|
||||
Console.WriteLine($"[WS] JOBREPORT_GET_LIST: sd={sd}, ed={ed}, uid={uid}, searchKey={searchKey}");
|
||||
string result = _bridge.Jobreport_GetList(sd, ed, uid, cate, searchKey);
|
||||
var response = new { type = "JOBREPORT_LIST_DATA", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "JOBREPORT_GET_USERS":
|
||||
{
|
||||
string result = _bridge.Jobreport_GetUsers();
|
||||
var response = new { type = "JOBREPORT_USERS_DATA", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "JOBREPORT_GET_DETAIL":
|
||||
{
|
||||
int idx = json.idx ?? 0;
|
||||
string result = _bridge.Jobreport_GetDetail(idx);
|
||||
var response = new { type = "JOBREPORT_DETAIL_DATA", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "JOBREPORT_ADD":
|
||||
{
|
||||
string pdate = json.pdate ?? "";
|
||||
string projectName = json.projectName ?? "";
|
||||
string requestpart = json.requestpart ?? "";
|
||||
string package = json.package ?? "";
|
||||
string type1 = json.type ?? "";
|
||||
string process = json.process ?? "";
|
||||
string status = json.status ?? "진행 완료";
|
||||
string description = json.description ?? "";
|
||||
double hrs = json.hrs ?? 0.0;
|
||||
double ot = json.ot ?? 0.0;
|
||||
string jobgrp = json.jobgrp ?? "";
|
||||
string tag = json.tag ?? "";
|
||||
string result = _bridge.Jobreport_Add(pdate, projectName, requestpart, package, type1, process, status, description, hrs, ot, jobgrp, tag);
|
||||
var response = new { type = "JOBREPORT_ADDED", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "JOBREPORT_EDIT":
|
||||
{
|
||||
int idx = json.idx ?? 0;
|
||||
string pdate = json.pdate ?? "";
|
||||
string projectName = json.projectName ?? "";
|
||||
string requestpart = json.requestpart ?? "";
|
||||
string package = json.package ?? "";
|
||||
string type2 = json.type ?? "";
|
||||
string process = json.process ?? "";
|
||||
string status = json.status ?? "";
|
||||
string description = json.description ?? "";
|
||||
double hrs = json.hrs ?? 0.0;
|
||||
double ot = json.ot ?? 0.0;
|
||||
string jobgrp = json.jobgrp ?? "";
|
||||
string tag = json.tag ?? "";
|
||||
string result = _bridge.Jobreport_Edit(idx, pdate, projectName, requestpart, package, type2, process, status, description, hrs, ot, jobgrp, tag);
|
||||
var response = new { type = "JOBREPORT_EDITED", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "JOBREPORT_DELETE":
|
||||
{
|
||||
int idx = json.idx ?? 0;
|
||||
string result = _bridge.Jobreport_Delete(idx);
|
||||
var response = new { type = "JOBREPORT_DELETED", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "JOBREPORT_GET_PERMISSION":
|
||||
{
|
||||
string targetUserId = json.targetUserId ?? "";
|
||||
string result = _bridge.Jobreport_GetPermission(targetUserId);
|
||||
var response = new { type = "JOBREPORT_PERMISSION", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "JOBREPORT_GET_JOBTYPES":
|
||||
{
|
||||
string process = json.process ?? "";
|
||||
string result = _bridge.Jobreport_GetJobTypes(process);
|
||||
var response = new { type = "JOBREPORT_JOBTYPES", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
case "GET_APP_VERSION":
|
||||
{
|
||||
string result = _bridge.GetAppVersion();
|
||||
var response = new { type = "APP_VERSION", data = JsonConvert.DeserializeObject(result) };
|
||||
await Send(socket, JsonConvert.SerializeObject(response));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Console.WriteLine($"[WS] Unknown message type: {type}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"[WS] Handle Error: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Send(WebSocket socket, string message)
|
||||
{
|
||||
if (_socketLocks.TryGetValue(socket, out var semaphore))
|
||||
{
|
||||
await semaphore.WaitAsync();
|
||||
try
|
||||
{
|
||||
if (socket.State == WebSocketState.Open)
|
||||
{
|
||||
byte[] buffer = Encoding.UTF8.GetBytes(message);
|
||||
await socket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, CancellationToken.None);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
semaphore.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async void Broadcast(string message)
|
||||
{
|
||||
byte[] buffer = Encoding.UTF8.GetBytes(message);
|
||||
WebSocket[] clientsCopy;
|
||||
|
||||
lock (_clients)
|
||||
{
|
||||
clientsCopy = _clients.ToArray();
|
||||
}
|
||||
|
||||
foreach (var client in clientsCopy)
|
||||
{
|
||||
if (client.State == WebSocketState.Open && _socketLocks.TryGetValue(client, out var semaphore))
|
||||
{
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
if (await semaphore.WaitAsync(0))
|
||||
{
|
||||
try
|
||||
{
|
||||
if (client.State == WebSocketState.Open)
|
||||
{
|
||||
await client.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, CancellationToken.None);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
finally
|
||||
{
|
||||
semaphore.Release();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user