From 77f1ddab8029ed7fc049758788894aa88a3672b7 Mon Sep 17 00:00:00 2001 From: backuppc Date: Fri, 5 Dec 2025 17:33:12 +0900 Subject: [PATCH] .. --- Project/EETGW.csproj | 18 + Project/EETGW.csproj.user | 2 +- .../MachineBridge/MachineBridge.License.cs | 320 ++ .../MachineBridge/MachineBridge.MailData.cs | 162 + .../MachineBridge/MachineBridge.PartList.cs | 247 + .../MachineBridge/MachineBridge.Project.cs | 58 + Project/Web/MachineBridge/MachineBridge.cs | 19 +- Project/Web/MachineBridge/WebSocketServer.cs | 178 + Project/app.config | 30 +- Project/fMain.Designer.cs | 166 +- Project/fMain.cs | 79 +- Project/fMain.resx | 142 +- Project/frontend/src/App.tsx | 4 + Project/frontend/src/communication.ts | 244 + .../jobreport/JobreportEditModal.tsx | 4 +- .../frontend/src/components/layout/Header.tsx | 125 +- .../src/components/layout/StatusBar.tsx | 9 +- .../components/license/LicenseEditDialog.tsx | 293 ++ .../src/components/license/LicenseList.tsx | 387 ++ .../src/components/mail/MailTestDialog.tsx | 304 ++ .../src/components/project/PartListDialog.tsx | 519 ++ .../frontend/src/components/project/index.ts | 1 + Project/frontend/src/pages/Dashboard.tsx | 96 +- Project/frontend/src/pages/Jobreport.tsx | 54 +- Project/frontend/src/pages/MailList.tsx | 60 +- Project/frontend/src/pages/PartList.tsx | 588 +++ Project/frontend/src/pages/Project.tsx | 279 +- Project/frontend/src/pages/Todo.tsx | 75 +- Project/frontend/src/types.ts | 66 +- Project/packages.config | 6 +- .../Properties/Settings.Designer.cs | 2 +- .../Properties/Settings.settings | 4 +- SubProject/FCM0000/FCM0000.csproj | 18 - SubProject/FCM0000/Mail/fMailList.Designer.cs | 525 --- SubProject/FCM0000/Mail/fMailList.cs | 147 - SubProject/FCM0000/Mail/fMailList.resx | 250 - SubProject/FCM0000/Mail/fSendMail.Designer.cs | 295 -- SubProject/FCM0000/Mail/fSendMail.cs | 145 - SubProject/FCM0000/Mail/fSendMail.resx | 168 - SubProject/FED0000/EEDataSet.Designer.cs | 2211 +-------- SubProject/FED0000/EEDataSet.xsd | 302 +- SubProject/FED0000/EEDataSet.xss | 3 +- .../FED0000/Education/fEdulist.Designer.cs | 680 --- SubProject/FED0000/Education/fEdulist.cs | 781 --- SubProject/FED0000/Education/fEdulist.resx | 306 -- SubProject/FED0000/FED0000.csproj | 9 - .../FED0000/License/fLicenseList.Designer.cs | 1 - SubProject/FED0000/License/fLicenseList.cs | 806 ++-- SubProject/FPJ0000/DSNote.Designer.cs | 2335 --------- SubProject/FPJ0000/DSNote.xsc | 9 - SubProject/FPJ0000/DSNote.xsd | 237 - SubProject/FPJ0000/DSNote.xss | 12 - SubProject/FPJ0000/FPJ0000.csproj | 79 +- SubProject/FPJ0000/FPJ0000.csproj.user | 2 +- .../FPJ0000/JobReport_/fJobReport.Designer.cs | 1 - .../JobReport_/fJobReport_Add.Designer.cs | 1 - .../JobReport_/fJobReport_AddAI.Designer.cs | 1 - SubProject/FPJ0000/Note/fNote.Designer.cs | 597 --- SubProject/FPJ0000/Note/fNote.cs | 456 -- SubProject/FPJ0000/Note/fNote.resx | 303 -- SubProject/FPJ0000/Note/fNote_Add.Designer.cs | 260 - SubProject/FPJ0000/Note/fNote_Add.cs | 243 - SubProject/FPJ0000/Note/fNote_Add.resx | 132 - .../FPJ0000/OtConfirm/fOTConfirm.Designer.cs | 1 - SubProject/FPJ0000/Project/Project.zip | Bin 22787 -> 0 bytes .../FPJ0000/Project/fPartList.Designer.cs | 1 - .../Project/fProejctHistory.Designer.cs | 1 - .../FPJ0000/Project/fProjectData.Designer.cs | 1 - .../FPJ0000/Project/fProjectIOMap.Designer.cs | 1 - .../Project/fProjectLayout.Designer.cs | 1 - .../FPJ0000/Project/fProjectList.Designer.cs | 3 +- SubProject/FPJ0000/Project/fProjectList.resx | 520 +- .../FPJ0000/Project/fProjectListU.Designer.cs | 1 - .../Project/fProjectListUser.Designer.cs | 1 - .../fProjectListUserDetail.Designer.cs | 1 - .../Project/fProjectPartListEdit.Designer.cs | 1 - .../Project/fProjectSchedule.Designer.cs | 1 - .../Project/fProjectSummary.Designer.cs | 1 - .../SaveCost/fSaveCostData.Designer.cs | 1233 ----- SubProject/FPJ0000/SaveCost/fSaveCostData.cs | 216 - .../FPJ0000/SaveCost/fSaveCostData.resx | 248 - .../SaveCost/fSaveCostList.Designer.cs | 1069 ----- SubProject/FPJ0000/SaveCost/fSaveCostList.cs | 447 -- .../FPJ0000/SaveCost/fSaveCostList.resx | 325 -- .../SaveCost/fSaveCostReport.Designer.cs | 231 - .../FPJ0000/SaveCost/fSaveCostReport.cs | 257 - .../FPJ0000/SaveCost/fSaveCostReport.resx | 135 - SubProject/FPJ0000/dsPRJ.Designer.cs | 4187 +---------------- SubProject/FPJ0000/dsPRJ.xsc | 32 +- SubProject/FPJ0000/dsPRJ.xsd | 506 -- SubProject/FPJ0000/dsPRJ.xss | 35 +- SubProject/FPJ0000/fMailList.Designer.cs | 1 - 92 files changed, 4878 insertions(+), 20435 deletions(-) create mode 100644 Project/Web/MachineBridge/MachineBridge.License.cs create mode 100644 Project/Web/MachineBridge/MachineBridge.PartList.cs create mode 100644 Project/frontend/src/components/license/LicenseEditDialog.tsx create mode 100644 Project/frontend/src/components/license/LicenseList.tsx create mode 100644 Project/frontend/src/components/mail/MailTestDialog.tsx create mode 100644 Project/frontend/src/components/project/PartListDialog.tsx create mode 100644 Project/frontend/src/pages/PartList.tsx delete mode 100644 SubProject/FCM0000/Mail/fMailList.Designer.cs delete mode 100644 SubProject/FCM0000/Mail/fMailList.cs delete mode 100644 SubProject/FCM0000/Mail/fMailList.resx delete mode 100644 SubProject/FCM0000/Mail/fSendMail.Designer.cs delete mode 100644 SubProject/FCM0000/Mail/fSendMail.cs delete mode 100644 SubProject/FCM0000/Mail/fSendMail.resx delete mode 100644 SubProject/FED0000/Education/fEdulist.Designer.cs delete mode 100644 SubProject/FED0000/Education/fEdulist.cs delete mode 100644 SubProject/FED0000/Education/fEdulist.resx delete mode 100644 SubProject/FPJ0000/DSNote.Designer.cs delete mode 100644 SubProject/FPJ0000/DSNote.xsc delete mode 100644 SubProject/FPJ0000/DSNote.xsd delete mode 100644 SubProject/FPJ0000/DSNote.xss delete mode 100644 SubProject/FPJ0000/Note/fNote.Designer.cs delete mode 100644 SubProject/FPJ0000/Note/fNote.cs delete mode 100644 SubProject/FPJ0000/Note/fNote.resx delete mode 100644 SubProject/FPJ0000/Note/fNote_Add.Designer.cs delete mode 100644 SubProject/FPJ0000/Note/fNote_Add.cs delete mode 100644 SubProject/FPJ0000/Note/fNote_Add.resx delete mode 100644 SubProject/FPJ0000/Project/Project.zip delete mode 100644 SubProject/FPJ0000/SaveCost/fSaveCostData.Designer.cs delete mode 100644 SubProject/FPJ0000/SaveCost/fSaveCostData.cs delete mode 100644 SubProject/FPJ0000/SaveCost/fSaveCostData.resx delete mode 100644 SubProject/FPJ0000/SaveCost/fSaveCostList.Designer.cs delete mode 100644 SubProject/FPJ0000/SaveCost/fSaveCostList.cs delete mode 100644 SubProject/FPJ0000/SaveCost/fSaveCostList.resx delete mode 100644 SubProject/FPJ0000/SaveCost/fSaveCostReport.Designer.cs delete mode 100644 SubProject/FPJ0000/SaveCost/fSaveCostReport.cs delete mode 100644 SubProject/FPJ0000/SaveCost/fSaveCostReport.resx diff --git a/Project/EETGW.csproj b/Project/EETGW.csproj index 8c19575..5cff649 100644 --- a/Project/EETGW.csproj +++ b/Project/EETGW.csproj @@ -173,9 +173,21 @@ ..\packages\Microsoft.Web.WebView2.1.0.2210.55\lib\net45\Microsoft.Web.WebView2.Wpf.dll + + ..\packages\NetOfficeFw.Core.1.8.1\lib\net40\NetOffice.dll + False + ..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll + + ..\packages\NetOfficeFw.Core.1.8.1\lib\net40\OfficeApi.dll + False + + + ..\packages\NetOfficeFw.Outlook.1.8.1\lib\net40\OutlookApi.dll + False + ..\..\..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6\System.dll @@ -214,6 +226,10 @@ + + ..\packages\NetOfficeFw.Core.1.8.1\lib\net40\VBIDEApi.dll + False + ..\DLL\Winsock Orcas.dll @@ -369,6 +385,8 @@ + + diff --git a/Project/EETGW.csproj.user b/Project/EETGW.csproj.user index 0789c32..ca2fa97 100644 --- a/Project/EETGW.csproj.user +++ b/Project/EETGW.csproj.user @@ -9,7 +9,7 @@ ko-KR false - ProjectFiles + ShowAllFiles false diff --git a/Project/Web/MachineBridge/MachineBridge.License.cs b/Project/Web/MachineBridge/MachineBridge.License.cs new file mode 100644 index 0000000..322a5ec --- /dev/null +++ b/Project/Web/MachineBridge/MachineBridge.License.cs @@ -0,0 +1,320 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.SqlClient; +using System.Diagnostics; +using System.IO; +using System.Text; +using Newtonsoft.Json; +using FCOMMON; + +namespace Project.Web +{ + public partial class MachineBridge + { + /// + /// 라이선스 목록 조회 + /// + public string License_GetList() + { + try + { + if (string.IsNullOrEmpty(info.Login.no) || string.IsNullOrEmpty(info.Login.gcode)) + { + return JsonConvert.SerializeObject(new { Success = false, Message = "로그인이 필요합니다." }); + } + + var connStr = Project.Properties.Settings.Default.CS; + using (var conn = new SqlConnection(connStr)) + { + conn.Open(); + + var cmd = new SqlCommand(@" + SELECT + idx, gcode, expire, name, Version, MeterialNo, Supply, qty, + uids, SerialNo, Remark, sdate, edate, manu, wuid, wdate + FROM EETGW_License WITH (nolock) + WHERE gcode = @gcode + ORDER BY expire DESC, name, sdate", conn); + + cmd.Parameters.Add("@gcode", SqlDbType.VarChar).Value = info.Login.gcode; + + var list = new List(); + using (var reader = cmd.ExecuteReader()) + { + while (reader.Read()) + { + list.Add(new + { + idx = reader.GetInt32(0), + gcode = reader.IsDBNull(1) ? "" : reader.GetString(1), + expire = !reader.IsDBNull(2) && reader.GetBoolean(2), + name = reader.IsDBNull(3) ? "" : reader.GetString(3), + version = reader.IsDBNull(4) ? "" : reader.GetString(4), + meterialNo = reader.IsDBNull(5) ? "" : reader.GetString(5), + supply = reader.IsDBNull(6) ? "" : reader.GetString(6), + qty = reader.IsDBNull(7) ? 0 : reader.GetInt32(7), + uids = reader.IsDBNull(8) ? "" : reader.GetString(8), + serialNo = reader.IsDBNull(9) ? "" : reader.GetString(9), + remark = reader.IsDBNull(10) ? "" : reader.GetString(10), + sdate = reader.IsDBNull(11) ? "" : reader.GetString(11), + edate = reader.IsDBNull(12) ? "" : reader.GetString(12), + manu = reader.IsDBNull(13) ? "" : reader.GetString(13), + wuid = reader.IsDBNull(14) ? "" : reader.GetString(14), + wdate = reader.IsDBNull(15) ? "" : reader.GetDateTime(15).ToString("yyyy-MM-dd HH:mm:ss") + }); + } + } + + return JsonConvert.SerializeObject(new { Success = true, Data = list }); + } + } + catch (Exception ex) + { + return JsonConvert.SerializeObject(new { Success = false, Message = "라이선스 목록 조회 중 오류가 발생했습니다: " + ex.Message }); + } + } + + /// + /// 라이선스 추가 + /// + public string License_Add(string name, string version, string meterialNo, string supply, + int qty, string uids, string serialNo, string remark, string sdate, string edate, + string manu, bool expire) + { + try + { + + + if (string.IsNullOrEmpty(info.Login.no) || string.IsNullOrEmpty(info.Login.gcode)) + { + return JsonConvert.SerializeObject(new { Success = false, Message = "로그인이 필요합니다." }); + } + + var connStr = Project.Properties.Settings.Default.CS; + using (var conn = new SqlConnection(connStr)) + { + conn.Open(); + + var cmd = new SqlCommand(@" + INSERT INTO EETGW_License + (gcode, expire, name, manu, Supply, qty, uids, sdate, edate, Remark, wuid, wdate, Version, SerialNo, MeterialNo) + VALUES + (@gcode, @expire, @name, @manu, @Supply, @qty, @uids, @sdate, @edate, @Remark, @wuid, @wdate, @Version, @SerialNo, @MeterialNo); + SELECT SCOPE_IDENTITY();", conn); + + cmd.Parameters.Add("@gcode", SqlDbType.VarChar).Value = info.Login.gcode; + cmd.Parameters.Add("@expire", SqlDbType.Bit).Value = expire; + cmd.Parameters.Add("@name", SqlDbType.NVarChar).Value = name ?? ""; + cmd.Parameters.Add("@manu", SqlDbType.NVarChar).Value = manu ?? ""; + cmd.Parameters.Add("@Supply", SqlDbType.NVarChar).Value = supply ?? ""; + cmd.Parameters.Add("@qty", SqlDbType.Int).Value = qty; + cmd.Parameters.Add("@uids", SqlDbType.NVarChar).Value = uids ?? ""; + cmd.Parameters.Add("@sdate", SqlDbType.VarChar).Value = string.IsNullOrEmpty(sdate) ? DateTime.Now.ToString("yyyy-MM-dd") : sdate; + cmd.Parameters.Add("@edate", SqlDbType.VarChar).Value = (object)edate ?? DBNull.Value; + cmd.Parameters.Add("@Remark", SqlDbType.NVarChar).Value = remark ?? ""; + cmd.Parameters.Add("@wuid", SqlDbType.VarChar).Value = info.Login.no; + cmd.Parameters.Add("@wdate", SqlDbType.DateTime).Value = DateTime.Now; + cmd.Parameters.Add("@Version", SqlDbType.NVarChar).Value = version ?? ""; + cmd.Parameters.Add("@SerialNo", SqlDbType.NVarChar).Value = serialNo ?? ""; + cmd.Parameters.Add("@MeterialNo", SqlDbType.NVarChar).Value = meterialNo ?? ""; + + var idx = Convert.ToInt32(cmd.ExecuteScalar()); + + return JsonConvert.SerializeObject(new { Success = true, Message = "라이선스가 추가되었습니다.", Data = new { idx } }); + } + } + catch (Exception ex) + { + return JsonConvert.SerializeObject(new { Success = false, Message = "라이선스 추가 중 오류가 발생했습니다: " + ex.Message }); + } + } + + /// + /// 라이선스 수정 + /// + public string License_Update(int idx, string name, string version, string meterialNo, + string supply, int qty, string uids, string serialNo, string remark, string sdate, + string edate, string manu, bool expire) + { + try + { + if (string.IsNullOrEmpty(info.Login.no) || string.IsNullOrEmpty(info.Login.gcode)) + { + return JsonConvert.SerializeObject(new { Success = false, Message = "로그인이 필요합니다." }); + } + + var connStr = Project.Properties.Settings.Default.CS; + using (var conn = new SqlConnection(connStr)) + { + conn.Open(); + + var cmd = new SqlCommand(@" + UPDATE EETGW_License SET + expire = @expire, name = @name, manu = @manu, Supply = @Supply, + qty = @qty, uids = @uids, sdate = @sdate, edate = @edate, + Remark = @Remark, wuid = @wuid, wdate = @wdate, + Version = @Version, SerialNo = @SerialNo, MeterialNo = @MeterialNo + WHERE idx = @idx AND gcode = @gcode", conn); + + cmd.Parameters.Add("@idx", SqlDbType.Int).Value = idx; + cmd.Parameters.Add("@gcode", SqlDbType.VarChar).Value = info.Login.gcode; + cmd.Parameters.Add("@expire", SqlDbType.Bit).Value = expire; + cmd.Parameters.Add("@name", SqlDbType.NVarChar).Value = name ?? ""; + cmd.Parameters.Add("@manu", SqlDbType.NVarChar).Value = manu ?? ""; + cmd.Parameters.Add("@Supply", SqlDbType.NVarChar).Value = supply ?? ""; + cmd.Parameters.Add("@qty", SqlDbType.Int).Value = qty; + cmd.Parameters.Add("@uids", SqlDbType.NVarChar).Value = uids ?? ""; + cmd.Parameters.Add("@sdate", SqlDbType.VarChar).Value = string.IsNullOrEmpty(sdate) ? DateTime.Now.ToString("yyyy-MM-dd") : sdate; + cmd.Parameters.Add("@edate", SqlDbType.VarChar).Value = (object)edate ?? DBNull.Value; + cmd.Parameters.Add("@Remark", SqlDbType.NVarChar).Value = remark ?? ""; + cmd.Parameters.Add("@wuid", SqlDbType.VarChar).Value = info.Login.no; + cmd.Parameters.Add("@wdate", SqlDbType.DateTime).Value = DateTime.Now; + cmd.Parameters.Add("@Version", SqlDbType.NVarChar).Value = version ?? ""; + cmd.Parameters.Add("@SerialNo", SqlDbType.NVarChar).Value = serialNo ?? ""; + cmd.Parameters.Add("@MeterialNo", SqlDbType.NVarChar).Value = meterialNo ?? ""; + + var cnt = cmd.ExecuteNonQuery(); + + return JsonConvert.SerializeObject(new { Success = true, Message = "라이선스가 수정되었습니다.", Data = new { UpdatedCount = cnt } }); + } + } + catch (Exception ex) + { + return JsonConvert.SerializeObject(new { Success = false, Message = "라이선스 수정 중 오류가 발생했습니다: " + ex.Message }); + } + } + + /// + /// 라이선스 삭제 + /// + public string License_Delete(int idx) + { + try + { + if (string.IsNullOrEmpty(info.Login.no) || string.IsNullOrEmpty(info.Login.gcode)) + { + return JsonConvert.SerializeObject(new { Success = false, Message = "로그인이 필요합니다." }); + } + + var connStr = Project.Properties.Settings.Default.CS; + using (var conn = new SqlConnection(connStr)) + { + conn.Open(); + + var cmd = new SqlCommand(@" + DELETE FROM EETGW_License + WHERE idx = @idx AND gcode = @gcode", conn); + + cmd.Parameters.Add("@idx", SqlDbType.Int).Value = idx; + cmd.Parameters.Add("@gcode", SqlDbType.VarChar).Value = info.Login.gcode; + + var cnt = cmd.ExecuteNonQuery(); + + return JsonConvert.SerializeObject(new { Success = true, Message = "라이선스가 삭제되었습니다.", Data = new { DeletedCount = cnt } }); + } + } + catch (Exception ex) + { + return JsonConvert.SerializeObject(new { Success = false, Message = "라이선스 삭제 중 오류가 발생했습니다: " + ex.Message }); + } + } + + /// + /// 라이선스 폴더 열기 + /// + public string License_OpenFolder(int idx) + { + try + { + if (string.IsNullOrEmpty(info.Login.no) || string.IsNullOrEmpty(info.Login.gcode)) + { + return JsonConvert.SerializeObject(new { Success = false, Message = "로그인이 필요합니다." }); + } + + var serverpath = DBM.getCodeSvalue("55", "01"); + if (string.IsNullOrEmpty(serverpath) || !Directory.Exists(serverpath)) + { + return JsonConvert.SerializeObject(new { Success = false, Message = "프로젝트 기본경로가 존재하지 않습니다.\\n\\n공용정보->공용코드->55-01 데이터를 설정 하시기 바랍니다." }); + } + + var folderPath = Path.Combine(serverpath, "Data", "License", idx.ToString()); + + // 폴더가 없으면 생성 + if (!Directory.Exists(folderPath)) + { + Directory.CreateDirectory(folderPath); + } + + // 탐색기로 폴더 열기 + Process.Start("explorer.exe", folderPath); + + return JsonConvert.SerializeObject(new { Success = true, Message = "폴더를 열었습니다.", Data = new { Path = folderPath } }); + } + catch (Exception ex) + { + return JsonConvert.SerializeObject(new { Success = false, Message = "폴더 열기 중 오류가 발생했습니다: " + ex.Message }); + } + } + + /// + /// CSV로 내보내기 + /// + public string License_ExportCSV(string filePath) + { + try + { + if (string.IsNullOrEmpty(info.Login.no) || string.IsNullOrEmpty(info.Login.gcode)) + { + return JsonConvert.SerializeObject(new { Success = false, Message = "로그인이 필요합니다." }); + } + + var connStr = Project.Properties.Settings.Default.CS; + using (var conn = new SqlConnection(connStr)) + { + conn.Open(); + + var cmd = new SqlCommand(@" + SELECT + idx, expire, name, Version, MeterialNo, Supply, qty, + uids, SerialNo, Remark, sdate, edate, manu + FROM EETGW_License WITH (nolock) + WHERE gcode = @gcode + ORDER BY expire DESC, name, sdate", conn); + + cmd.Parameters.Add("@gcode", SqlDbType.VarChar).Value = info.Login.gcode; + + var sb = new StringBuilder(); + sb.AppendLine("idx,expire,name,Version,MeterialNo,Supply,qty,uids,SerialNo,Remark,sdate,edate,manu"); + + using (var reader = cmd.ExecuteReader()) + { + while (reader.Read()) + { + var values = new List(); + for (int i = 0; i < reader.FieldCount; i++) + { + var value = reader.IsDBNull(i) ? "" : reader.GetValue(i).ToString(); + // CSV 이스케이프 처리 + if (value.Contains(",") || value.Contains("\"") || value.Contains("\n")) + { + value = "\"" + value.Replace("\"", "\"\"") + "\""; + } + values.Add(value); + } + sb.AppendLine(string.Join(",", values)); + } + } + + File.WriteAllText(filePath, sb.ToString(), Encoding.UTF8); + + return JsonConvert.SerializeObject(new { Success = true, Message = "CSV 파일이 생성되었습니다.", Data = new { Path = filePath } }); + } + } + catch (Exception ex) + { + return JsonConvert.SerializeObject(new { Success = false, Message = "CSV 내보내기 중 오류가 발생했습니다: " + ex.Message }); + } + } + } +} diff --git a/Project/Web/MachineBridge/MachineBridge.MailData.cs b/Project/Web/MachineBridge/MachineBridge.MailData.cs index a20750c..6de9dc9 100644 --- a/Project/Web/MachineBridge/MachineBridge.MailData.cs +++ b/Project/Web/MachineBridge/MachineBridge.MailData.cs @@ -5,6 +5,9 @@ using System.Data; using System.Data.SqlClient; using System.Linq; using FCOMMON; +using NetOffice; +using Outlook = NetOffice.OutlookApi; +using NetOffice.OutlookApi.Enums; namespace Project.Web { @@ -71,5 +74,164 @@ namespace Project.Web return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message }); } } + + /// + /// 메일 데이터 추가 (발송 대기열) + /// + public string Mail_AddData(string cate, string subject, string fromlist, string tolist, string cc, string bcc, string body) + { + try + { + if (string.IsNullOrEmpty(info.Login.no) || string.IsNullOrEmpty(info.Login.gcode)) + { + return JsonConvert.SerializeObject(new { Success = false, Message = "로그인이 필요합니다." }); + } + + var connStr = Project.Properties.Settings.Default.CS; + using (var conn = new SqlConnection(connStr)) + { + conn.Open(); + + var cmd = new SqlCommand(@" + INSERT INTO MailData + (gcode, cate, pdate, subject, fromlist, tolist, cc, bcc, body, SendOK, wuid, wdate) + VALUES + (@gcode, @cate, @pdate, @subject, @fromlist, @tolist, @cc, @bcc, @body, 0, @wuid, GETDATE())", conn); + + cmd.Parameters.Add("@gcode", SqlDbType.VarChar).Value = info.Login.gcode; + cmd.Parameters.Add("@cate", SqlDbType.VarChar).Value = cate ?? ""; + cmd.Parameters.Add("@pdate", SqlDbType.VarChar).Value = DateTime.Now.ToString("yyyy-MM-dd"); + cmd.Parameters.Add("@subject", SqlDbType.VarChar).Value = subject ?? ""; + cmd.Parameters.Add("@fromlist", SqlDbType.VarChar).Value = fromlist ?? ""; + cmd.Parameters.Add("@tolist", SqlDbType.VarChar).Value = tolist ?? ""; + cmd.Parameters.Add("@cc", SqlDbType.VarChar).Value = cc ?? ""; + cmd.Parameters.Add("@bcc", SqlDbType.VarChar).Value = bcc ?? ""; + cmd.Parameters.Add("@body", SqlDbType.VarChar).Value = body ?? ""; + cmd.Parameters.Add("@wuid", SqlDbType.VarChar).Value = info.Login.no; + + int affected = cmd.ExecuteNonQuery(); + + if (affected > 0) + { + return JsonConvert.SerializeObject(new { Success = true, Message = "메일이 발송 대기열에 추가되었습니다." }); + } + else + { + return JsonConvert.SerializeObject(new { Success = false, Message = "메일 등록에 실패했습니다." }); + } + } + } + catch (Exception ex) + { + return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message }); + } + } + + /// + /// 메일 직접 발송 (SMTP) + /// + public string Mail_SendDirect(string cate, string subject, string fromlist, string tolist, string cc, string bcc, string body) + { + try + { + if (string.IsNullOrEmpty(info.Login.no) || string.IsNullOrEmpty(info.Login.gcode)) + { + return JsonConvert.SerializeObject(new { Success = false, Message = "로그인이 필요합니다." }); + } + + // SMTP 직접 발송 + var mailserver = info.mailserver ?? "scwa.amkor.co.kr"; + var mc = new System.Net.Mail.SmtpClient(mailserver); + var msg = new System.Net.Mail.MailMessage( + string.IsNullOrEmpty(fromlist) ? "gw@amkor.co.kr" : fromlist, + tolist, + subject, + body + ); + + if (!string.IsNullOrEmpty(bcc)) msg.Bcc.Add(bcc); + if (!string.IsNullOrEmpty(cc)) msg.CC.Add(cc); + msg.IsBodyHtml = true; + + mc.Send(msg); + + // 발송 성공 시 MailData에도 저장 (SendOK=1) + var connStr = Project.Properties.Settings.Default.CS; + using (var conn = new SqlConnection(connStr)) + { + conn.Open(); + + var cmd = new SqlCommand(@" + INSERT INTO MailData + (gcode, cate, pdate, subject, fromlist, tolist, cc, bcc, body, SendOK, SendMsg, wuid, wdate, suid, sdate) + VALUES + (@gcode, @cate, @pdate, @subject, @fromlist, @tolist, @cc, @bcc, @body, 1, @SendMsg, @wuid, GETDATE(), @wuid, GETDATE())", conn); + + cmd.Parameters.Add("@gcode", SqlDbType.VarChar).Value = info.Login.gcode; + cmd.Parameters.Add("@cate", SqlDbType.VarChar).Value = cate ?? ""; + cmd.Parameters.Add("@pdate", SqlDbType.VarChar).Value = DateTime.Now.ToString("yyyy-MM-dd"); + cmd.Parameters.Add("@subject", SqlDbType.VarChar).Value = subject ?? ""; + cmd.Parameters.Add("@fromlist", SqlDbType.VarChar).Value = string.IsNullOrEmpty(fromlist) ? "gw@amkor.co.kr" : fromlist; + cmd.Parameters.Add("@tolist", SqlDbType.VarChar).Value = tolist ?? ""; + cmd.Parameters.Add("@cc", SqlDbType.VarChar).Value = cc ?? ""; + cmd.Parameters.Add("@bcc", SqlDbType.VarChar).Value = bcc ?? ""; + cmd.Parameters.Add("@body", SqlDbType.VarChar).Value = body ?? ""; + cmd.Parameters.Add("@SendMsg", SqlDbType.VarChar).Value = "Direct Send"; + cmd.Parameters.Add("@wuid", SqlDbType.VarChar).Value = info.Login.no; + + cmd.ExecuteNonQuery(); + } + + return JsonConvert.SerializeObject(new { Success = true, Message = "메일이 발송되었습니다." }); + } + catch (Exception ex) + { + return JsonConvert.SerializeObject(new { Success = false, Message = $"메일 발송 실패: {ex.Message}" }); + } + } + + /// + /// Outlook으로 메일 미리보기/발송 + /// + public string Mail_SendOutlook(string subject, string _tolist, string cc, string bcc, string body) + { + try + { + if (string.IsNullOrEmpty(info.Login.no) || string.IsNullOrEmpty(info.Login.gcode)) + { + return JsonConvert.SerializeObject(new { Success = false, Message = "로그인이 필요합니다." }); + } + + // Outlook COM 객체 생성 + var tolist = new string[] { "Chikyun.kim@amkor.co.kr" }; //dr.tolist.Split(','); + Outlook.Application outlookApplication = new Outlook.Application(); + + foreach (var to in tolist) + { + if (to.isEmpty()) continue; + var newMail = outlookApplication.CreateItem(OlItemType.olMailItem) as Outlook.MailItem; + newMail.Display(); + newMail.Subject = subject.Trim(); // dr.title; + newMail.To = to; + newMail.CC = cc; + newMail.BCC = bcc; + // newMail.BodyFormat = OlBodyFormat.olFormatHTML; + newMail.HTMLBody = body + .Replace("{USER}", FCOMMON.info.Login.nameK) + .Replace("{EUSER}", FCOMMON.info.Login.nameE) + .Replace("{EMAIL}", FCOMMON.info.Login.email) + .Replace("%7BEMAIL%7D", FCOMMON.info.Login.email) + .Replace("{HP}", FCOMMON.info.Login.hp) + .Replace("{TEL}", FCOMMON.info.Login.tel) + .Replace("{ITEM}", subject) + newMail.HTMLBody; + } + + return JsonConvert.SerializeObject(new { Success = true, Message = "Outlook 메일 창이 열렸습니다." }); + } + catch (Exception ex) + { + return JsonConvert.SerializeObject(new { Success = false, Message = $"Outlook 실행 실패: {ex.Message}" }); + } + } } } diff --git a/Project/Web/MachineBridge/MachineBridge.PartList.cs b/Project/Web/MachineBridge/MachineBridge.PartList.cs new file mode 100644 index 0000000..0f38789 --- /dev/null +++ b/Project/Web/MachineBridge/MachineBridge.PartList.cs @@ -0,0 +1,247 @@ +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 + { + /// + /// 프로젝트별 파트리스트 조회 + /// + public string PartList_GetList(int projectIdx) + { + try + { + var connStr = Properties.Settings.Default.CS; + using (var conn = new SqlConnection(connStr)) + { + conn.Open(); + + + var cmd = new SqlCommand(@" + SELECT + idx, no, Project, ItemGroup, ItemModel, ItemUnit, ItemName, + ItemSid, ItemSupply, ItemSupplyidx, ItemManu, Item, + option1, qty, qtyn, price, amt, remark, qtybuy + FROM ProjectsPart + WHERE Project = @ProjectIdx + ORDER BY ItemGroup, option1, no, ItemName + ", conn); + + cmd.Parameters.Add("@ProjectIdx", SqlDbType.Int).Value = projectIdx; + + var list = new List(); + using (var reader = cmd.ExecuteReader()) + { + while (reader.Read()) + { + list.Add(new + { + idx = reader.GetInt32(0), + no = reader.IsDBNull(1) ? 0 : reader.GetInt32(1), + Project = reader.GetInt32(2), + itemgroup = reader.IsDBNull(3) ? "" : reader.GetString(3), + itemmodel = reader.IsDBNull(4) ? "" : reader.GetString(4), + itemunit = reader.IsDBNull(5) ? "" : reader.GetString(5), + itemname = reader.IsDBNull(6) ? "" : reader.GetString(6), + itemsid = reader.IsDBNull(7) ? "" : reader.GetString(7), + itemsupply = reader.IsDBNull(8) ? "" : reader.GetString(8), + itemsupplyidx = reader.IsDBNull(9) ? 0 : reader.GetInt32(9), + itemmanu = reader.IsDBNull(10) ? "" : reader.GetString(10), + item = reader.IsDBNull(11) ? "" : reader.GetInt32(11).ToString(), + option1 = reader.IsDBNull(12) ? "" : reader.GetString(12), + qty = reader.IsDBNull(13) ? 0 : reader.GetInt32(13), + qtyn = reader.IsDBNull(14) ? 0 : reader.GetInt32(14), + price = reader.IsDBNull(15) ? 0.0 : (double)reader.GetDecimal(15), + amt = reader.IsDBNull(16) ? 0.0 : (double)reader.GetDecimal(16), + remark = reader.IsDBNull(17) ? "" : reader.GetString(17), + qtybuy = reader.IsDBNull(18) ? 0 : reader.GetInt32(18) + }); + } + } var result = new + { + Success = true, + Data = list + }; + return JsonConvert.SerializeObject(result); + } + } + catch (Exception ex) + { + return JsonConvert.SerializeObject(new + { + Success = false, + Message = "파트리스트 조회 실패: " + ex.Message + }); + } + } + + /// + /// 파트리스트 항목 저장 (추가/수정) + /// + public string PartList_Save( + int idx, + int projectIdx, + string itemgroup, + string itemname, + string item, + string itemmodel, + string itemscale, + string itemunit, + double qty, + double price, + string itemsupply, + int itemsupplyidx, + string itemmanu, + string itemsid, + string option1, + string remark, + int no, + double qtybuy) + { + try + { + var connStr = Properties.Settings.Default.CS; + using (var con = new SqlConnection(connStr)) + { + con.Open(); + + if (idx == 0 || idx == -1) // 새로 추가 + { + using (var cmd = new SqlCommand(@" + INSERT INTO ProjectsPart ( + Project, ItemGroup, ItemName, Item, ItemModel, + ItemUnit, Qty, Price, ItemSupply, + ItemSupplyIdx, ItemManu, ItemSid, option1, + remark, no, qtybuy, wuid, wdate + ) VALUES ( + @Project, @ItemGroup, @ItemName, @Item, @ItemModel, + @ItemUnit, @Qty, @Price, @ItemSupply, + @ItemSupplyIdx, @ItemManu, @ItemSid, @option1, + @remark, @no, @qtybuy, @wuid, @wdate + ) + ", con)) + { + cmd.Parameters.AddWithValue("@Project", projectIdx); + cmd.Parameters.AddWithValue("@ItemGroup", itemgroup ?? ""); + cmd.Parameters.AddWithValue("@ItemName", itemname ?? ""); + cmd.Parameters.AddWithValue("@Item", item ?? ""); + cmd.Parameters.AddWithValue("@ItemModel", itemmodel ?? ""); + cmd.Parameters.AddWithValue("@ItemUnit", itemunit ?? ""); + cmd.Parameters.AddWithValue("@Qty", qty); + cmd.Parameters.AddWithValue("@Price", price); + cmd.Parameters.AddWithValue("@ItemSupply", itemsupply ?? ""); + cmd.Parameters.AddWithValue("@ItemSupplyIdx", itemsupplyidx); + cmd.Parameters.AddWithValue("@ItemManu", itemmanu ?? ""); + cmd.Parameters.AddWithValue("@ItemSid", itemsid ?? ""); + cmd.Parameters.AddWithValue("@option1", option1 ?? ""); + cmd.Parameters.AddWithValue("@remark", remark ?? ""); + cmd.Parameters.AddWithValue("@no", no); + cmd.Parameters.AddWithValue("@qtybuy", qtybuy); + cmd.Parameters.AddWithValue("@wuid", info.Login.no); + cmd.Parameters.AddWithValue("@wdate", DateTime.Now); + + cmd.ExecuteNonQuery(); + } + } + else // 수정 + { + using (var cmd = new SqlCommand(@" + UPDATE ProjectsPart SET + ItemGroup = @ItemGroup, + ItemName = @ItemName, + Item = @Item, + ItemModel = @ItemModel, + ItemUnit = @ItemUnit, + Qty = @Qty, + Price = @Price, + ItemSupply = @ItemSupply, + ItemSupplyIdx = @ItemSupplyIdx, + ItemManu = @ItemManu, + ItemSid = @ItemSid, + option1 = @option1, + remark = @remark, + no = @no, + qtybuy = @qtybuy + WHERE idx = @idx + ", con)) + { + cmd.Parameters.AddWithValue("@idx", idx); + cmd.Parameters.AddWithValue("@ItemGroup", itemgroup ?? ""); + cmd.Parameters.AddWithValue("@ItemName", itemname ?? ""); + cmd.Parameters.AddWithValue("@Item", item ?? ""); + cmd.Parameters.AddWithValue("@ItemModel", itemmodel ?? ""); + cmd.Parameters.AddWithValue("@ItemUnit", itemunit ?? ""); + cmd.Parameters.AddWithValue("@Qty", qty); + cmd.Parameters.AddWithValue("@Price", price); + cmd.Parameters.AddWithValue("@ItemSupply", itemsupply ?? ""); + cmd.Parameters.AddWithValue("@ItemSupplyIdx", itemsupplyidx); + cmd.Parameters.AddWithValue("@ItemManu", itemmanu ?? ""); + cmd.Parameters.AddWithValue("@ItemSid", itemsid ?? ""); + cmd.Parameters.AddWithValue("@option1", option1 ?? ""); + cmd.Parameters.AddWithValue("@remark", remark ?? ""); + cmd.Parameters.AddWithValue("@no", no); + cmd.Parameters.AddWithValue("@qtybuy", qtybuy); + + cmd.ExecuteNonQuery(); + } + } + + return JsonConvert.SerializeObject(new + { + Success = true, + Message = "저장되었습니다." + }); + } + } + catch (Exception ex) + { + return JsonConvert.SerializeObject(new + { + Success = false, + Message = "저장 실패: " + ex.Message + }); + } + } + + /// + /// 파트리스트 항목 삭제 + /// + public string PartList_Delete(int idx) + { + try + { + var connStr = Properties.Settings.Default.CS; + using (var con = new SqlConnection(connStr)) + { + con.Open(); + + var cmd = new SqlCommand(@" + DELETE FROM ProjectsPart WHERE idx = @idx + ", con); + + cmd.Parameters.Add("@idx", SqlDbType.Int).Value = idx; + cmd.ExecuteNonQuery(); + + return JsonConvert.SerializeObject(new + { + Success = true, + Message = "삭제되었습니다." + }); + } + } + catch (Exception ex) + { + return JsonConvert.SerializeObject(new + { + Success = false, + Message = "삭제 실패: " + ex.Message + }); + } + } + } +} diff --git a/Project/Web/MachineBridge/MachineBridge.Project.cs b/Project/Web/MachineBridge/MachineBridge.Project.cs index 451855b..2344ae4 100644 --- a/Project/Web/MachineBridge/MachineBridge.Project.cs +++ b/Project/Web/MachineBridge/MachineBridge.Project.cs @@ -606,6 +606,64 @@ namespace Project.Web } } + /// + /// 프로젝트 히스토리 저장 + /// + public string Project_SaveHistory(int idx, int pidx, string pdate, int progress, string remark) + { + try + { + var cs = Properties.Settings.Default.gwcs; + using (var cn = new SqlConnection(cs)) + { + cn.Open(); + string sql; + + if (idx > 0) + { + // 수정 + sql = @"UPDATE ProjectsHistory + SET remark = @remark, progress = @progress, wdate = GETDATE(), wuid = @wuid + WHERE idx = @idx"; + } + else + { + // 신규 등록 + sql = @"INSERT INTO ProjectsHistory (pidx, pdate, progress, remark, wuid, wdate) + VALUES (@pidx, @pdate, @progress, @remark, @wuid, GETDATE())"; + } + + using (var cmd = new SqlCommand(sql, cn)) + { + if (idx > 0) + { + cmd.Parameters.AddWithValue("@idx", idx); + } + cmd.Parameters.AddWithValue("@pidx", pidx); + cmd.Parameters.AddWithValue("@pdate", pdate); + cmd.Parameters.AddWithValue("@progress", progress); + cmd.Parameters.AddWithValue("@remark", remark ?? ""); + cmd.Parameters.AddWithValue("@wuid", info.Login.no); + + int affected = cmd.ExecuteNonQuery(); + + if (affected > 0) + { + return JsonConvert.SerializeObject(new { Success = true, Message = "저장되었습니다." }); + } + else + { + return JsonConvert.SerializeObject(new { Success = false, Message = "저장에 실패했습니다." }); + } + } + } + } + catch (Exception ex) + { + return JsonConvert.SerializeObject(new { Success = false, Message = ex.Message }); + } + } + /// /// 프로젝트 일일 메모 조회 /// diff --git a/Project/Web/MachineBridge/MachineBridge.cs b/Project/Web/MachineBridge/MachineBridge.cs index 45975d8..253c37d 100644 --- a/Project/Web/MachineBridge/MachineBridge.cs +++ b/Project/Web/MachineBridge/MachineBridge.cs @@ -101,12 +101,27 @@ namespace Project.Web { try { + var productVersion = Application.ProductVersion; + var maxVersion = DBM.GetMaxVersion(); + var hasNewVersion = false; + + if (!string.IsNullOrEmpty(maxVersion)) + { + var verchk = productVersion.CompareTo(maxVersion); + if (verchk < 0) + { + hasNewVersion = true; + } + } + return JsonConvert.SerializeObject(new { Success = true, ProductName = Application.ProductName, - ProductVersion = Application.ProductVersion, - DisplayVersion = $"{Application.ProductName} v{Application.ProductVersion}" + ProductVersion = productVersion, + DisplayVersion = $"{Application.ProductName} v{productVersion}", + MaxVersion = maxVersion, + HasNewVersion = hasNewVersion }); } catch (Exception ex) diff --git a/Project/Web/MachineBridge/WebSocketServer.cs b/Project/Web/MachineBridge/WebSocketServer.cs index f317e83..7826e7f 100644 --- a/Project/Web/MachineBridge/WebSocketServer.cs +++ b/Project/Web/MachineBridge/WebSocketServer.cs @@ -986,6 +986,171 @@ namespace Project.Web } break; + case "MAIL_ADD_DATA": + { + string cate = json.cate ?? ""; + string subject = json.subject ?? ""; + string fromlist = json.fromlist ?? ""; + string tolist = json.tolist ?? ""; + string cc = json.cc ?? ""; + string bcc = json.bcc ?? ""; + string body = json.body ?? ""; + string result = _bridge.Mail_AddData(cate, subject, fromlist, tolist, cc, bcc, body); + var response = new { type = "MAIL_ADD_DATA_RESULT", data = JsonConvert.DeserializeObject(result) }; + await Send(socket, JsonConvert.SerializeObject(response)); + } + break; + + case "MAIL_SEND_DIRECT": + { + string cate = json.cate ?? ""; + string subject = json.subject ?? ""; + string fromlist = json.fromlist ?? ""; + string tolist = json.tolist ?? ""; + string cc = json.cc ?? ""; + string bcc = json.bcc ?? ""; + string body = json.body ?? ""; + string result = _bridge.Mail_SendDirect(cate, subject, fromlist, tolist, cc, bcc, body); + var response = new { type = "MAIL_SEND_DIRECT_RESULT", data = JsonConvert.DeserializeObject(result) }; + await Send(socket, JsonConvert.SerializeObject(response)); + } + break; + + case "MAIL_SEND_OUTLOOK": + { + string subject = json.subject ?? ""; + string tolist = json.tolist ?? ""; + string cc = json.cc ?? ""; + string bcc = json.bcc ?? ""; + string body = json.body ?? ""; + string result = _bridge.Mail_SendOutlook(subject, tolist, cc, bcc, body); + var response = new { type = "MAIL_SEND_OUTLOOK_RESULT", data = JsonConvert.DeserializeObject(result) }; + await Send(socket, JsonConvert.SerializeObject(response)); + } + break; + + // ===== License API (라이선스 관리) ===== + case "LICENSE_GET_LIST": + { + string result = _bridge.License_GetList(); + var response = new { type = "LICENSE_LIST_DATA", data = JsonConvert.DeserializeObject(result) }; + await Send(socket, JsonConvert.SerializeObject(response)); + } + break; + + case "LICENSE_ADD": + { + string name = json.name ?? ""; + string version = json.version ?? ""; + string meterialNo = json.meterialNo ?? ""; + string supply = json.supply ?? ""; + int qty = json.qty ?? 0; + string uids = json.uids ?? ""; + string serialNo = json.serialNo ?? ""; + string remark = json.remark ?? ""; + string sdate = json.sdate ?? ""; + string edate = json.edate ?? ""; + string manu = json.manu ?? ""; + bool expire = json.expire ?? false; + string result = _bridge.License_Add(name, version, meterialNo, supply, qty, uids, serialNo, remark, sdate, edate, manu, expire); + var response = new { type = "LICENSE_ADD_RESULT", data = JsonConvert.DeserializeObject(result) }; + await Send(socket, JsonConvert.SerializeObject(response)); + } + break; + + case "LICENSE_UPDATE": + { + int idx = json.idx ?? 0; + string name = json.name ?? ""; + string version = json.version ?? ""; + string meterialNo = json.meterialNo ?? ""; + string supply = json.supply ?? ""; + int qty = json.qty ?? 0; + string uids = json.uids ?? ""; + string serialNo = json.serialNo ?? ""; + string remark = json.remark ?? ""; + string sdate = json.sdate ?? ""; + string edate = json.edate ?? ""; + string manu = json.manu ?? ""; + bool expire = json.expire ?? false; + string result = _bridge.License_Update(idx, name, version, meterialNo, supply, qty, uids, serialNo, remark, sdate, edate, manu, expire); + var response = new { type = "LICENSE_UPDATE_RESULT", data = JsonConvert.DeserializeObject(result) }; + await Send(socket, JsonConvert.SerializeObject(response)); + } + break; + + case "LICENSE_DELETE": + { + int idx = json.idx ?? 0; + string result = _bridge.License_Delete(idx); + var response = new { type = "LICENSE_DELETE_RESULT", data = JsonConvert.DeserializeObject(result) }; + await Send(socket, JsonConvert.SerializeObject(response)); + } + break; + + case "LICENSE_OPEN_FOLDER": + { + int idx = json.idx ?? 0; + string result = _bridge.License_OpenFolder(idx); + var response = new { type = "LICENSE_OPEN_FOLDER_RESULT", data = JsonConvert.DeserializeObject(result) }; + await Send(socket, JsonConvert.SerializeObject(response)); + } + break; + + case "LICENSE_EXPORT_CSV": + { + string filePath = json.filePath ?? ""; + string result = _bridge.License_ExportCSV(filePath); + var response = new { type = "LICENSE_EXPORT_CSV_RESULT", data = JsonConvert.DeserializeObject(result) }; + await Send(socket, JsonConvert.SerializeObject(response)); + } + break; + + // ===== PartList API (파트리스트) ===== + case "PARTLIST_GET_LIST": + { + int projectIdx = json.projectIdx ?? 0; + string result = _bridge.PartList_GetList(projectIdx); + var response = new { type = "PARTLIST_LIST_DATA", data = JsonConvert.DeserializeObject(result) }; + await Send(socket, JsonConvert.SerializeObject(response)); + } + break; + + case "PARTLIST_SAVE": + { + int idx = json.idx ?? 0; + int projectIdx = json.projectIdx ?? 0; + string itemgroup = json.itemgroup ?? ""; + string itemname = json.itemname ?? ""; + string item = json.item ?? ""; + string itemmodel = json.itemmodel ?? ""; + string itemscale = json.itemscale ?? ""; + string itemunit = json.itemunit ?? ""; + double qty = json.qty ?? 0.0; + double price = json.price ?? 0.0; + string itemsupply = json.itemsupply ?? ""; + int itemsupplyidx = json.itemsupplyidx ?? 0; + string itemmanu = json.itemmanu ?? ""; + string itemsid = json.itemsid ?? ""; + string option1 = json.option1 ?? ""; + string remark = json.remark ?? ""; + int no = json.no ?? 0; + double qtybuy = json.qtybuy ?? 0.0; + string result = _bridge.PartList_Save(idx, projectIdx, itemgroup, itemname, item, itemmodel, itemscale, itemunit, qty, price, itemsupply, itemsupplyidx, itemmanu, itemsid, option1, remark, no, qtybuy); + var response = new { type = "PARTLIST_SAVE_RESULT", data = JsonConvert.DeserializeObject(result) }; + await Send(socket, JsonConvert.SerializeObject(response)); + } + break; + + case "PARTLIST_DELETE": + { + int idx = json.idx ?? 0; + string result = _bridge.PartList_Delete(idx); + var response = new { type = "PARTLIST_DELETE_RESULT", data = JsonConvert.DeserializeObject(result) }; + await Send(socket, JsonConvert.SerializeObject(response)); + } + break; + // ===== Customs API (업체정보) ===== case "CUSTOMS_GET_LIST": { @@ -1295,6 +1460,19 @@ namespace Project.Web } break; + case "PROJECT_SAVE_HISTORY": + { + int idx = json.idx ?? 0; + int pidx = json.pidx ?? 0; + string pdate = json.pdate ?? ""; + int progress = json.progress ?? 0; + string remark = json.remark ?? ""; + string result = _bridge.Project_SaveHistory(idx, pidx, pdate, progress, remark); + var response = new { type = "PROJECT_SAVE_HISTORY_RESULT", data = JsonConvert.DeserializeObject(result) }; + await Send(socket, JsonConvert.SerializeObject(response)); + } + break; + case "PROJECT_GET_DAILY_MEMO": { int projectIdx = json.projectIdx ?? 0; diff --git a/Project/app.config b/Project/app.config index 8cbec29..7f92479 100644 --- a/Project/app.config +++ b/Project/app.config @@ -3,26 +3,16 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/Project/fMain.Designer.cs b/Project/fMain.Designer.cs index 7818b87..705209b 100644 --- a/Project/fMain.Designer.cs +++ b/Project/fMain.Designer.cs @@ -78,8 +78,6 @@ this.업무분류및형태설정ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.자동입력ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator(); - this.교육목록ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.비용절감ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.라이선스ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.mn_jago = new System.Windows.Forms.ToolStripMenuItem(); this.관리ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -102,14 +100,6 @@ this.근태마감ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.대체시간이월ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.personalInventoryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.mn_docu = new System.Windows.Forms.ToolStripMenuItem(); - this.메모장ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.메일내역ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.기타ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.품목검색ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.대쉬보드ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripMenuItem17 = new System.Windows.Forms.ToolStripSeparator(); - this.webview2TestToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.즐겨찾기ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.btDev = new System.Windows.Forms.ToolStripMenuItem(); this.purchaseImportToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -123,17 +113,11 @@ this.addSIdDataToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.계정목록ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.그룹정보ToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); - this.임의테이블조작ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.mailBackupToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.메일자동발신테스트ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripSeparator(); this.아이템비활성화하기ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.sPR설정ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItem13 = new System.Windows.Forms.ToolStripMenuItem(); this.프로젝트스케쥴담당자사번업데이트ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.버젼확인ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.설명서ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.tabControl1 = new System.Windows.Forms.TabControl(); this.toolStrip1 = new System.Windows.Forms.ToolStrip(); this.toolStripMenuItem8 = new System.Windows.Forms.ToolStripMenuItem(); @@ -236,12 +220,8 @@ this.btSetting, this.commonToolStripMenuItem, this.managementToolStripMenuItem, - this.mn_docu, - this.기타ToolStripMenuItem, this.즐겨찾기ToolStripMenuItem, - this.btDev, - this.버젼확인ToolStripMenuItem, - this.설명서ToolStripMenuItem}); + this.btDev}); this.menuStrip1.Location = new System.Drawing.Point(1, 1); this.menuStrip1.Name = "menuStrip1"; this.menuStrip1.Size = new System.Drawing.Size(1094, 27); @@ -368,8 +348,6 @@ this.mn_purchase, this.mn_project, this.mn_dailyhistory, - this.교육목록ToolStripMenuItem, - this.비용절감ToolStripMenuItem, this.라이선스ToolStripMenuItem, this.mn_jago, this.휴가관리ToolStripMenuItem, @@ -508,7 +486,6 @@ this.mn_dailyhistory.Name = "mn_dailyhistory"; this.mn_dailyhistory.Size = new System.Drawing.Size(203, 24); this.mn_dailyhistory.Text = "업무관리"; - this.mn_dailyhistory.Click += new System.EventHandler(this.업무일지ToolStripMenuItem1_Click); // // 목록ToolStripMenuItem1 // @@ -548,22 +525,6 @@ this.toolStripMenuItem2.Name = "toolStripMenuItem2"; this.toolStripMenuItem2.Size = new System.Drawing.Size(231, 6); // - // 교육목록ToolStripMenuItem - // - this.교육목록ToolStripMenuItem.Name = "교육목록ToolStripMenuItem"; - this.교육목록ToolStripMenuItem.Size = new System.Drawing.Size(203, 24); - this.교육목록ToolStripMenuItem.Text = "교육목록"; - this.교육목록ToolStripMenuItem.Click += new System.EventHandler(this.교육목록ToolStripMenuItem_Click); - // - // 비용절감ToolStripMenuItem - // - this.비용절감ToolStripMenuItem.ForeColor = System.Drawing.Color.Black; - this.비용절감ToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("비용절감ToolStripMenuItem.Image"))); - this.비용절감ToolStripMenuItem.Name = "비용절감ToolStripMenuItem"; - this.비용절감ToolStripMenuItem.Size = new System.Drawing.Size(203, 24); - this.비용절감ToolStripMenuItem.Text = "비용절감"; - this.비용절감ToolStripMenuItem.Click += new System.EventHandler(this.비용절감ToolStripMenuItem_Click); - // // 라이선스ToolStripMenuItem // this.라이선스ToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("라이선스ToolStripMenuItem.Image"))); @@ -740,68 +701,6 @@ this.personalInventoryToolStripMenuItem.Visible = false; this.personalInventoryToolStripMenuItem.Click += new System.EventHandler(this.personalInventoryToolStripMenuItem_Click); // - // mn_docu - // - this.mn_docu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.메모장ToolStripMenuItem, - this.메일내역ToolStripMenuItem}); - this.mn_docu.Image = ((System.Drawing.Image)(resources.GetObject("mn_docu.Image"))); - this.mn_docu.Name = "mn_docu"; - this.mn_docu.Size = new System.Drawing.Size(65, 23); - this.mn_docu.Text = "문서"; - // - // 메모장ToolStripMenuItem - // - this.메모장ToolStripMenuItem.Name = "메모장ToolStripMenuItem"; - this.메모장ToolStripMenuItem.Size = new System.Drawing.Size(152, 24); - this.메모장ToolStripMenuItem.Text = "메모장"; - this.메모장ToolStripMenuItem.Click += new System.EventHandler(this.메모장ToolStripMenuItem_Click); - // - // 메일내역ToolStripMenuItem - // - this.메일내역ToolStripMenuItem.Name = "메일내역ToolStripMenuItem"; - this.메일내역ToolStripMenuItem.Size = new System.Drawing.Size(152, 24); - this.메일내역ToolStripMenuItem.Text = "메일 내역"; - this.메일내역ToolStripMenuItem.Click += new System.EventHandler(this.메일내역ToolStripMenuItem_Click); - // - // 기타ToolStripMenuItem - // - this.기타ToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.품목검색ToolStripMenuItem, - this.대쉬보드ToolStripMenuItem, - this.toolStripMenuItem17, - this.webview2TestToolStripMenuItem}); - this.기타ToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("기타ToolStripMenuItem.Image"))); - this.기타ToolStripMenuItem.Name = "기타ToolStripMenuItem"; - this.기타ToolStripMenuItem.Size = new System.Drawing.Size(65, 23); - this.기타ToolStripMenuItem.Text = "기타"; - // - // 품목검색ToolStripMenuItem - // - this.품목검색ToolStripMenuItem.Name = "품목검색ToolStripMenuItem"; - this.품목검색ToolStripMenuItem.Size = new System.Drawing.Size(171, 24); - this.품목검색ToolStripMenuItem.Text = "품목 검색"; - this.품목검색ToolStripMenuItem.Click += new System.EventHandler(this.품목검색ToolStripMenuItem_Click); - // - // 대쉬보드ToolStripMenuItem - // - this.대쉬보드ToolStripMenuItem.Name = "대쉬보드ToolStripMenuItem"; - this.대쉬보드ToolStripMenuItem.Size = new System.Drawing.Size(171, 24); - this.대쉬보드ToolStripMenuItem.Text = "대쉬보드"; - this.대쉬보드ToolStripMenuItem.Click += new System.EventHandler(this.대쉬보드ToolStripMenuItem_Click); - // - // toolStripMenuItem17 - // - this.toolStripMenuItem17.Name = "toolStripMenuItem17"; - this.toolStripMenuItem17.Size = new System.Drawing.Size(168, 6); - // - // webview2TestToolStripMenuItem - // - this.webview2TestToolStripMenuItem.Name = "webview2TestToolStripMenuItem"; - this.webview2TestToolStripMenuItem.Size = new System.Drawing.Size(171, 24); - this.webview2TestToolStripMenuItem.Text = "Webview2 Test"; - this.webview2TestToolStripMenuItem.Click += new System.EventHandler(this.webview2TestToolStripMenuItem_Click); - // // 즐겨찾기ToolStripMenuItem // this.즐겨찾기ToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("즐겨찾기ToolStripMenuItem.Image"))); @@ -823,11 +722,7 @@ this.addSIdDataToolStripMenuItem, this.계정목록ToolStripMenuItem, this.그룹정보ToolStripMenuItem1, - this.toolStripMenuItem1, - this.임의테이블조작ToolStripMenuItem, this.mailBackupToolStripMenuItem, - this.메일자동발신테스트ToolStripMenuItem, - this.toolStripMenuItem5, this.아이템비활성화하기ToolStripMenuItem, this.sPR설정ToolStripMenuItem, this.toolStripMenuItem13, @@ -916,21 +811,6 @@ this.그룹정보ToolStripMenuItem1.Text = "그룹정보"; this.그룹정보ToolStripMenuItem1.Click += new System.EventHandler(this.그룹정보ToolStripMenuItem1_Click); // - // toolStripMenuItem1 - // - this.toolStripMenuItem1.ForeColor = System.Drawing.Color.HotPink; - this.toolStripMenuItem1.Name = "toolStripMenuItem1"; - this.toolStripMenuItem1.Size = new System.Drawing.Size(302, 24); - this.toolStripMenuItem1.Text = "Staff Grid"; - this.toolStripMenuItem1.Click += new System.EventHandler(this.toolStripMenuItem1_Click); - // - // 임의테이블조작ToolStripMenuItem - // - this.임의테이블조작ToolStripMenuItem.Name = "임의테이블조작ToolStripMenuItem"; - this.임의테이블조작ToolStripMenuItem.Size = new System.Drawing.Size(302, 24); - this.임의테이블조작ToolStripMenuItem.Text = "구매내역 suuply 다시 설정 하기"; - this.임의테이블조작ToolStripMenuItem.Click += new System.EventHandler(this.임의테이블조작ToolStripMenuItem_Click); - // // mailBackupToolStripMenuItem // this.mailBackupToolStripMenuItem.Name = "mailBackupToolStripMenuItem"; @@ -938,18 +818,6 @@ this.mailBackupToolStripMenuItem.Text = "Mail Backup"; this.mailBackupToolStripMenuItem.Click += new System.EventHandler(this.mailBackupToolStripMenuItem_Click); // - // 메일자동발신테스트ToolStripMenuItem - // - this.메일자동발신테스트ToolStripMenuItem.Name = "메일자동발신테스트ToolStripMenuItem"; - this.메일자동발신테스트ToolStripMenuItem.Size = new System.Drawing.Size(302, 24); - this.메일자동발신테스트ToolStripMenuItem.Text = "메일자동발신(테스트)"; - this.메일자동발신테스트ToolStripMenuItem.Click += new System.EventHandler(this.메일자동발신테스트ToolStripMenuItem_Click); - // - // toolStripMenuItem5 - // - this.toolStripMenuItem5.Name = "toolStripMenuItem5"; - this.toolStripMenuItem5.Size = new System.Drawing.Size(299, 6); - // // 아이템비활성화하기ToolStripMenuItem // this.아이템비활성화하기ToolStripMenuItem.Name = "아이템비활성화하기ToolStripMenuItem"; @@ -978,22 +846,6 @@ this.프로젝트스케쥴담당자사번업데이트ToolStripMenuItem.Text = "프로젝트스케쥴담당자사번업데이트"; this.프로젝트스케쥴담당자사번업데이트ToolStripMenuItem.Click += new System.EventHandler(this.프로젝트스케쥴담당자사번업데이트ToolStripMenuItem_Click); // - // 버젼확인ToolStripMenuItem - // - this.버젼확인ToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("버젼확인ToolStripMenuItem.Image"))); - this.버젼확인ToolStripMenuItem.Name = "버젼확인ToolStripMenuItem"; - this.버젼확인ToolStripMenuItem.Size = new System.Drawing.Size(93, 23); - this.버젼확인ToolStripMenuItem.Text = "버젼확인"; - this.버젼확인ToolStripMenuItem.Click += new System.EventHandler(this.버젼확인ToolStripMenuItem_Click); - // - // 설명서ToolStripMenuItem - // - this.설명서ToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("설명서ToolStripMenuItem.Image"))); - this.설명서ToolStripMenuItem.Name = "설명서ToolStripMenuItem"; - this.설명서ToolStripMenuItem.Size = new System.Drawing.Size(79, 23); - this.설명서ToolStripMenuItem.Text = "설명서"; - this.설명서ToolStripMenuItem.Click += new System.EventHandler(this.설명서ToolStripMenuItem_Click); - // // tabControl1 // this.tabControl1.Appearance = System.Windows.Forms.TabAppearance.FlatButtons; @@ -1146,7 +998,6 @@ private System.Windows.Forms.ToolStripMenuItem itemsToolStripMenuItem; private System.Windows.Forms.ToolStripStatusLabel sbLogin; private System.Windows.Forms.ToolStripMenuItem codesToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem mn_docu; private System.Windows.Forms.ToolStripMenuItem managementToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem personalInventoryToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem userInfoToolStripMenuItem; @@ -1175,12 +1026,8 @@ private System.Windows.Forms.ToolStripMenuItem 권한설정ToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem 관리ToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem 재고현황ToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem1; - private System.Windows.Forms.ToolStripMenuItem 임의테이블조작ToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem 메일양식ToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem 메일내역ToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem mailBackupToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem 메모장ToolStripMenuItem; private System.Windows.Forms.ToolStrip toolStrip1; private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem6; private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem7; @@ -1189,32 +1036,24 @@ private System.Windows.Forms.ToolStripMenuItem 근태입력ToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem 근로명부ToolStripMenuItem; private System.Windows.Forms.ToolStripStatusLabel lbSvr; - private System.Windows.Forms.ToolStripMenuItem 비용절감ToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem 목록ToolStripMenuItem; private System.Windows.Forms.ToolStripButton toolStripButton1; private System.Windows.Forms.ToolStripButton toolStripButton2; private System.Windows.Forms.ToolStripMenuItem 목록ToolStripMenuItem1; private System.Windows.Forms.ToolStripMenuItem 자동입력ToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem 기타ToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem 품목검색ToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem layoutToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem 교육목록ToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem 양식ToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem 설명서ToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem 라이선스ToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem 휴일연장근무승인ToolStripMenuItem; private System.Windows.Forms.ToolStripSeparator toolStripMenuItem9; private System.Windows.Forms.ToolStripMenuItem 휴일연장근무집계표출력ToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem 메일자동발신테스트ToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem 출근부출력ToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem 휴가신청ToolStripMenuItem; private System.Windows.Forms.ToolStripSeparator toolStripMenuItem10; - private System.Windows.Forms.ToolStripSeparator toolStripMenuItem5; private System.Windows.Forms.ToolStripMenuItem 아이템비활성화하기ToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem 휴가사용현황ToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem 개인별근태원장ToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem 근태입력오류확인ToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem 버젼확인ToolStripMenuItem; private System.Windows.Forms.ToolStripSeparator toolStripMenuItem11; private System.Windows.Forms.ToolStripMenuItem 근태마감ToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem sPR설정ToolStripMenuItem; @@ -1233,7 +1072,6 @@ private System.Windows.Forms.ToolStripSeparator toolStripMenuItem15; private System.Windows.Forms.ToolStripMenuItem 개인별근태집계표ToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem 연차현황ToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem 대쉬보드ToolStripMenuItem; private System.Windows.Forms.ToolStripStatusLabel sbLoginUseTime; private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem16; private System.Windows.Forms.ToolStripMenuItem 담당자별업무현황ToolStripMenuItem; @@ -1242,8 +1080,6 @@ private System.Windows.Forms.ToolStripMenuItem 업무분류및형태설정ToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem 대체시간이월ToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem 월별NRCR기준금액입력ToolStripMenuItem; - private System.Windows.Forms.ToolStripSeparator toolStripMenuItem17; - private System.Windows.Forms.ToolStripMenuItem webview2TestToolStripMenuItem; private System.Windows.Forms.ToolStripStatusLabel sbWeb; private System.Windows.Forms.ToolStripStatusLabel sbChat; private System.Windows.Forms.ToolStripSeparator toolStripMenuItem18; diff --git a/Project/fMain.cs b/Project/fMain.cs index 28d6480..d35a433 100644 --- a/Project/fMain.cs +++ b/Project/fMain.cs @@ -183,8 +183,6 @@ namespace Project this.mn_jago.Visible = FCOMMON.Util.getBit(FCOMMON.info.Login.gpermission, (int)FCOMMON.eGroupPermission.menu_jago); //this.mn_eq.Visible = FCOMMON.Util.getBit(FCOMMON.info.Login.gpermission, (int)FCOMMON.eGroupPermission.menu_equipment); this.mn_kuntae.Visible = FCOMMON.Util.getBit(FCOMMON.info.Login.gpermission, (int)FCOMMON.eGroupPermission.menu_workday); - this.mn_docu.Visible = FCOMMON.Util.getBit(FCOMMON.info.Login.gpermission, (int)FCOMMON.eGroupPermission.menu_docu); - //this.mn_logdata.Visible = FCOMMON.Util.getBit(FCOMMON.info.Login.gpermission, (int)FCOMMON.eGroupPermission.menu_logdata); //220421 FCOMMON.info.Disable_8hourover = Pub.setting.Disable8HourOver; @@ -377,12 +375,7 @@ namespace Project } - void menu_save_cost() - { - string formkey = "SAVECOST"; - if (!ShowForm(formkey)) - AddForm(formkey, new FPJ0000.fSaveCostList()); - } + void menu_dayhistory() { @@ -680,23 +673,6 @@ namespace Project Menu_Dashboard(); } - private void 메일전송ToolStripMenuItem_Click(object sender, EventArgs e) - { - if (FCOMMON.info.Login.level < 10) - { - FCOMMON.Util.MsgE("테스트 기능이므로 개발자만 사용가능 합니다."); - return; - } - FCM0000.fSendMail f = new FCM0000.fSendMail(); - //f.MdiParent = this; - f.Show(); - } - - private void 업무일지ToolStripMenuItem1_Click(object sender, EventArgs e) - { - - } - private void workReportImportToolStripMenuItem_Click(object sender, EventArgs e) { @@ -801,12 +777,7 @@ namespace Project if (!ShowForm(formkey)) AddForm(formkey, new FCM0000.fInventoryJagoList()); } - void Menu_Note() - { - string formkey = "NOTELIST"; - if (!ShowForm(formkey)) - AddForm(formkey, new FPJ0000.Note.fNote()); - } + private void 재고현황ToolStripMenuItem_Click(object sender, EventArgs e) { Menu_InventoryList(); @@ -908,11 +879,6 @@ namespace Project FCOMMON.Util.MsgI("complete"); } - private void sMTRepairLogToolStripMenuItem_Click(object sender, EventArgs e) - { - - } - private void 메일양식ToolStripMenuItem_Click(object sender, EventArgs e) { string formkey = "MAILFORM"; @@ -920,20 +886,6 @@ namespace Project AddForm(formkey, new FCM0000.fMailform()); } - private void 메일내역ToolStripMenuItem_Click(object sender, EventArgs e) - { - string formkey = "MAILLIST"; - if (!ShowForm(formkey)) - AddForm(formkey, new FCM0000.Mail.fMailList()); - } - - - - private void pMP데이터베이스업데이트ToolStripMenuItem_Click(object sender, EventArgs e) - { - } - - private void mailBackupToolStripMenuItem_Click(object sender, EventArgs e) { var f = new FCM0000.Mail.fMailBackup(); @@ -941,11 +893,6 @@ namespace Project f.Show(); } - private void 메모장ToolStripMenuItem_Click(object sender, EventArgs e) - { - Menu_Note(); - } - private void toolStripMenuItem7_Click(object sender, EventArgs e) { @@ -976,11 +923,7 @@ namespace Project AddForm(formkey, new FBS0000.fWorkTableUser()); } - private void 비용절감ToolStripMenuItem_Click(object sender, EventArgs e) - { - menu_save_cost(); - } - + private void 목록ToolStripMenuItem_Click(object sender, EventArgs e) { menu_projecT_list(); @@ -1018,12 +961,6 @@ namespace Project AddForm(formkey, new FPJ0000.fProjectLayout()); } - private void 교육목록ToolStripMenuItem_Click(object sender, EventArgs e) - { - string formkey = "EDLIST"; - if (!ShowForm(formkey)) - AddForm(formkey, new FED0000.fEdulist()); - } private void 양식ToolStripMenuItem_Click(object sender, EventArgs e) { @@ -1032,16 +969,6 @@ namespace Project AddForm(formkey, new FCM0000.fJRForm()); } - private void 설명서ToolStripMenuItem_Click(object sender, EventArgs e) - { - // 로컬 PDF 파일 열기 - var pdfPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Manual.pdf"); - if (System.IO.File.Exists(pdfPath)) - Util.RunExplorer(pdfPath); - else - Util.MsgE("설명서 파일을 찾을 수 없습니다."); - } - private void 라이선스ToolStripMenuItem_Click(object sender, EventArgs e) { string formkey = "LICENSE"; diff --git a/Project/fMain.resx b/Project/fMain.resx index 180c9e6..6fd1143 100644 --- a/Project/fMain.resx +++ b/Project/fMain.resx @@ -150,94 +150,6 @@ Mi4wAwEBAAAh+QQBAAAfACwAAAAAEAAQAAAIkAA/CByYwUOGgQgTfvDgwINChQw9IHD4UGBEABAuUETo oaNEDxg1erTo4IGDiQAGNFCA4QABAg4jdkxpoYOABAkUGKD4UaUFARUCMLCwk6NGCkADRKBQNKEHDB6E RpDQlCNUoRYkSJhQYKPFAyqZThjbleMBDxw07CxQYMKGBRs9vNTQcaGHBXjjjuS4t2LFgAA7 - - - - - R0lGODlhEAAQAIQQAP/cpv/GcNvb292RIP+kG/+5T6m5rMStgK13Jv+wOt2TJKmwrP/zcZOru////wAA - AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBF - Mi4wAwEBAAAh+QQBAAAQACwAAAAAEAAQAAAIZQAhCBxIsKBABgQBGCTIoCEEBgEWDmRAgMAAAwUgKJQ4 - QIEDBwciSmw4QMDHBRIBBCiQAIGABw8aSBSosgHMmCkH2oQpc6bAnTh9QgDa0ydRoUMffCw6s4FJB0wl - OoWKdGiDBgEBADs= - - - - - R0lGODlhEAAQAIQfAJrM+3OSsKfS++zx9uXt9Yis1FdwkZW51ElVa8fj/bba/NXb5PL2+o276b3d/VJh - e7TR4ENLXNXn8KLD536kwIyzzJ/E2KjL3t7n7ykxQz5FVa/W/OLp8I+w1P///////yH/C05FVFNDQVBF - Mi4wAwEBAAAh+QQBAAAfACwAAAAAEAAQAAAItgA9CBxIcOCHgx4kQIBwwcKBChQiBgjgASEECQQGZNRI - oGMDAxU9QCCQoGRJBygZNPgo8AKDBB1iyuzAoOYDgRZeonSgoGfPDQxuejjwcsLMAkgFBBVY4aVPBRui - ClCKQCCFojGRIm0ggEBVDxQG8IQqdSoAAhGsijWqdSsADmk9BBBLdqoAAHgxaBAYgAHPsnjxDtjrwcAC - Bhw5KOaAYQCEDHwNSH7wAAGCCBE0aMggtKBnggEBADs= - - - - - R0lGODlhEAAQAIQfAKnrVsfvlYnVOHy8KnfJLJneRWqyJLvth1W7GzGTEVWnHT2aFIPNMkuiGmrKJGKt - Io7eOXa5KU64GDiWE1yqIHK3KHa5J0WeGGC/IG+1JW/FKGjCJHnRLWrOIP///////yH/C05FVFNDQVBF - Mi4wAwEBAAAh+QQBAAAfACwAAAAAEAAQAAAIqwA/CBTooeDAgwg9DFjoAWHCAQEAFBjQ0CHBAQAEFLBQ - 8WDBjxEARPjY8YPChREiZshg4EFJhQFiFmBQAAIECh8vLoTAgAEBAgIUeGhwoaHCghUE/NTAgcCFAxAW - GDWZQamGDRgwIEAgYUJBjh4MCODAAYODBRMkSEhQMAJLARQUNODgwGsCtiYjHBDgsuCCDl4NmqxQAK7R - v3gHemD5QK4HtBMSEyRplOTBgAA7 - - - - - R0lGODlhEAAQAIMPAEWi6azap1WzS9LusYrSbApexXLHV+z41vH559Ltw8ns+pe75hBs0iCZEP////// - /yH/C05FVFNDQVBFMi4wAwEBAAAh+QQBAAAPACwAAAAAEAAQAAAIiwAfCBxIsKDBBw4SOjg4MGGDBgwY - JDzo4OEBBAgUMGiwkGBFBAcODAAAYMEAjh4ZIBgwQAAAAgZOdkTIQEGCAQRICoAZACVNBQACkHxpQEDP - jg5qLhgKQIDTowIrJoA5NGKDABIbNpjqlEGBAguyag3QEiLYsDOjPgwQYEFYsQUdRpSY1qDCugzzBgQA - Ow== - - - - - R0lGODlhEAAQAIQfAKxoR8VkLxFw1feVPITSWv+eQv7Qo0Cc6OyIN/v7+3PLTSCZEFy17Wa6XuT1x2bG - Q3nNUU6vRXPAa9mLXMTkwJZEHJt7LL5aJ/z8/O2KONx3L/ubP/r6+rtVI////////yH/C05FVFNDQVBF - Mi4wAwEBAAAh+QQBAAAfACwAAAAAEAAQAAAIpgA/CBxIsOBADBgEeljoweAHDB06eIi4QICAhRwOdjAQ - kaMDCgwELOiQ8WGHAQYMFIjIgMEBCBEzQkSwoUCBCR0OSGigIKZJDQM2cKxwoAGBBx0ykISoIcOGiAcO - EFCAVCkHphueAtgaIYKFpks7NM0qFIDFCxk0kPyQQCzZiB0CbLAqsO1YslnTrq0r9m4GvSUHcoioobDa - vQU5DIar2KFgxYEHBgQAOw== - - - - - R0lGODlhEAAQAIQfAGm6/idTd4yTmF+v8Xa37KvW+lyh3KHJ62aq41ee2bXZ98nm/2mt5W2Ck5XN/C1c - hEZieho8WXXA/2Gn4P39/W+y6V+l3qjP8Njt/lx2izxPYGyv51Oa1EJWZ////////yH/C05FVFNDQVBF - Mi4wAwEBAAAh+QQBAAAfACwAAAAAEAAQAAAIqgA/CPzgoaBBDwMTEoQgoGGDBhAQKvSQAcOCBQUcaHwg - USBFDARCEqhQgYEEjh47gKxwweAFBAgkREDooYMCAhs8XGCAwMOEmB1o2qywYSdMnxMABCVocwMDngUP - GLAAYCZTBTARHPAgdWpVoQV+TrBgoGwCA1+ZOkgwduuBBAk4pCWogUBcDnjxAgjQkS4BAAMCD9jrgcJE - DQ8eBAjwYKZhhQQPFoRMuXJAADs= - - - - - R0lGODlhEAAQAIQAAP/99v/qaOvOSem4M+zSSv/ypf/ug//1w//2zP/xnv/te//zrf/0uv/41/nWdufB - MP/vkevTVf/rcv/0s//wlv/57OvRM//vi+/OQtaXIuuYEuvTLNyhJ+vHUP///////yH/C05FVFNDQVBF - Mi4wAwEBAAAh+QQBAAAfACwAAAAAEAAQAAAIoAA/CBxIsCBBDwgTKizogUCEhwQIYLBgYYOHgR4cKPQA - oMEBBAgsfsjoAQGDCQsKJEhAAcKBChYQajyZkiWECwYMAHiAkAAAlCop4FRA9ABPDxgqABVqQIGEpxQG - IMTQoCaEphICaFXAAaEABCmZZtUawECGi0gRHGigloFWCgzOYhRAt0OHASg1yD24cUAFDRcNMhwAWLBB - D4UNMwz8ISAAOw== - - - - - R0lGODlhEAAQAIQAAHan1azQ4ldvj9vp9HSQruTr80lVa+vx9pu811SRuXifuj13uYyz2VFhe4Gt2UNL - XPL1+Orv+ufu9YOqxYyzzNHW3SkxQz5FVWag2T6CuZe3y5G0t+Do7+r0/77a9f///yH/C05FVFNDQVBF - Mi4wAwEBAAAh+QQAAAAAACwAAAAAEAAQAAAIrwA/CBxIsKDAAQESIkBAYYICBQQICCAgMMAACQMyaswo - oUKDih0SZMiwoKTJBQcEVDyAoEMHDy5hdnAg4eMHBBIQeNjJcyeDAjYRRNAQs+hMoAIpRNjQs6eDAgYE - TshpVCYAqAIV5GzKU0GBB1klMKjqEgMHsB8IiOW60+wFgQQgIGDgoC4AABgwADjw9oOAChAkSChAmIPh - AxUswBXAuEEDAwYePLhwwYJNg5gFBgQAOw== - - - - - R0lGODlhEAAQAIQfAHWSrbTY+6nU/I+74/r8/drj7FlxkUlVa9Xp/eLs9cvT2oWpxG+bwqPQ+57N++v1 - /lJgeabK7JnB5kNLXJG0z5nA1oyw0SkxQz5FVb7e/aC91tHl8qXB2n2gu////////yH/C05FVFNDQVBF - Mi4wAwEBAAAh+QQBAAAfACwAAAAAEAAQAAAIpAA/CBxIsKDBgwQ9KFzIsKHCDRUqUFhAsQOAiwAMQFBY - gYDHjyAJKNjogQIBChoQZAgQAEGCiQUOKFxAIEMEDhsQPEDAQEKDBzI9dKiZIYOFowwENPg5QeHQlRIi - SJAwYIADBwWaegCQIMAACQEEKK2KFYNCrgMihBXbwEHVBGY9GFCQIEGBu3jvKrhw1oBfCBAOHJgwAQOG - CyQdKlaIsLHjggEBADs= @@ -342,6 +254,54 @@ Nq7P2vgxc+6aH3lHuKt0Ou1PJpM2vUR2cdVbXL34iF+O65kFQWDmnQCSJEn+WCxm00tc/2IyS5K0Yb4X QIpGoz5RFG16YM1mc6d5L4AUiUR8oVDIJjPP81vm/wJIgiD4eJ5/8O98rT+Jli/+ECJFiAAAAABJRU5E rkJggg== + + + + + R0lGODlhEAAQAIQQAP/cpv/GcNvb292RIP+kG/+5T6m5rMStgK13Jv+wOt2TJKmwrP/zcZOru////wAA + AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBF + Mi4wAwEBAAAh+QQBAAAQACwAAAAAEAAQAAAIZQAhCBxIsKBABgQBGCTIoCEEBgEWDmRAgMAAAwUgKJQ4 + QIEDBwciSmw4QMDHBRIBBCiQAIGABw8aSBSosgHMmCkH2oQpc6bAnTh9QgDa0ydRoUMffCw6s4FJB0wl + OoWKdGiDBgEBADs= + + + + + R0lGODlhEAAQAIMPAEWi6azap1WzS9LusYrSbApexXLHV+z41vH559Ltw8ns+pe75hBs0iCZEP////// + /yH/C05FVFNDQVBFMi4wAwEBAAAh+QQBAAAPACwAAAAAEAAQAAAIiwAfCBxIsKDBBw4SOjg4MGGDBgwY + JDzo4OEBBAgUMGiwkGBFBAcODAAAYMEAjh4ZIBgwQAAAAgZOdkTIQEGCAQRICoAZACVNBQACkHxpQEDP + jg5qLhgKQIDTowIrJoA5NGKDABIbNpjqlEGBAguyag3QEiLYsDOjPgwQYEFYsQUdRpSY1qDCugzzBgQA + Ow== + + + + + R0lGODlhEAAQAIQfAKxoR8VkLxFw1feVPITSWv+eQv7Qo0Cc6OyIN/v7+3PLTSCZEFy17Wa6XuT1x2bG + Q3nNUU6vRXPAa9mLXMTkwJZEHJt7LL5aJ/z8/O2KONx3L/ubP/r6+rtVI////////yH/C05FVFNDQVBF + Mi4wAwEBAAAh+QQBAAAfACwAAAAAEAAQAAAIpgA/CBxIsOBADBgEeljoweAHDB06eIi4QICAhRwOdjAQ + kaMDCgwELOiQ8WGHAQYMFIjIgMEBCBEzQkSwoUCBCR0OSGigIKZJDQM2cKxwoAGBBx0ykISoIcOGiAcO + EFCAVCkHphueAtgaIYKFpks7NM0qFIDFCxk0kPyQQCzZiB0CbLAqsO1YslnTrq0r9m4GvSUHcoioobDa + vQU5DIar2KFgxYEHBgQAOw== + + + + + R0lGODlhEAAQAIQAAHan1azQ4ldvj9vp9HSQruTr80lVa+vx9pu811SRuXifuj13uYyz2VFhe4Gt2UNL + XPL1+Orv+ufu9YOqxYyzzNHW3SkxQz5FVWag2T6CuZe3y5G0t+Do7+r0/77a9f///yH/C05FVFNDQVBF + Mi4wAwEBAAAh+QQAAAAAACwAAAAAEAAQAAAIrwA/CBxIsKDAAQESIkBAYYICBQQICCAgMMAACQMyaswo + oUKDih0SZMiwoKTJBQcEVDyAoEMHDy5hdnAg4eMHBBIQeNjJcyeDAjYRRNAQs+hMoAIpRNjQs6eDAgYE + TshpVCYAqAIV5GzKU0GBB1klMKjqEgMHsB8IiOW60+wFgQQgIGDgoC4AABgwADjw9oOAChAkSChAmIPh + AxUswBXAuEEDAwYePLhwwYJNg5gFBgQAOw== + + + + + R0lGODlhEAAQAIQfAHWSrbTY+6nU/I+74/r8/drj7FlxkUlVa9Xp/eLs9cvT2oWpxG+bwqPQ+57N++v1 + /lJgeabK7JnB5kNLXJG0z5nA1oyw0SkxQz5FVb7e/aC91tHl8qXB2n2gu////////yH/C05FVFNDQVBF + Mi4wAwEBAAAh+QQBAAAfACwAAAAAEAAQAAAIpAA/CBxIsKDBgwQ9KFzIsKHCDRUqUFhAsQOAiwAMQFBY + gYDHjyAJKNjogQIBChoQZAgQAEGCiQUOKFxAIEMEDhsQPEDAQEKDBzI9dKiZIYOFowwENPg5QeHQlRIi + SJAwYIADBwWaegCQIMAACQEEKK2KFYNCrgMihBXbwEHVBGY9GFCQIEGBu3jvKrhw1oBfCBAOHJgwAQOG + CyQdKlaIsLHjggEBADs= @@ -445,14 +405,14 @@ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIHSURBVDhPY2CAgZnGrAxLtTMZluosYFim08KwWFcdLL5K i4dhmVYhwzLteQzLdFoZlqlLwfWggKU6qxmW6fyH48U6PxiWaHoyLNO8jiK+VOsJwyotCTTNWjYgSYG1 - lv/9Tub8T7lc/z/3ZMX/eXNiP9Q05f9LvdzwP/Jc2X/VbV5QQ7T7UA1YpjOBf435seQr9d+Kb/X8L7nZ + lv/9Tub8T7lc/z/3ZMX/eXNiP9TU5/9LvdzwP/Jc2X/VbV5QQ7T7UA1YpjOBf435seQr9d+Kb/X8L7nZ 8//QzJz/jzrT/l+dlPkTJAbDJrtDTzAs0bmGasBSXcHiW911MEUdh+r/Xy+N+L+/1f7v9UKvzz3bCuEG FN/qugBSj2oAAwND8c3uuTBFlZc6lp0vDDl4Odnt28Ugtf/bKpz2Fl/s+AiSK7jZ8w5dLxjAXFB0s6cE xH/RGiH+uMzz/5UMrT9Psm3UCm/26hff6vpcdKvnPLpeMCi+02NcfKPrOIz/uNjT81Gpx38wLvHyAKu5 2V1afKu7BUUjMii+0y0GYz+p8MqCGfCk0jsTJFZ/v54j99ZEPhRNuMCjCs++J+Ve/0H4cblXL7o8QfC4 zHMj3AulHhvQ5fGC//vrOV50RZ1+0xP3H4RfdkaeAomhq0MB/w70a/490Nv3/0DvmfsHen//P9D7HxlD - xc6A1ezv0UBo3DaR/e+B3vnH2uv/oWvChUFq/x7omQfSy/B3f28vugJiMUgvw78DfbZ/D/Qs/3+gdxUp - GKQHpBcAG6GqRqSz0QwAAAAASUVORK5CYII= + xc6A1ezv0UBo3DaR/e+B3vmHmuv/oWvChUFq/x7omQfSy/B3f28vugJiMUgvw78DfbZ/D/Qs/3+gdxUp + GKQHpBcAByWqM8i7D2wAAAAASUVORK5CYII= diff --git a/Project/frontend/src/App.tsx b/Project/frontend/src/App.tsx index 0817c7d..e1c4435 100644 --- a/Project/frontend/src/App.tsx +++ b/Project/frontend/src/App.tsx @@ -6,6 +6,8 @@ import { PatchList } from '@/pages/PatchList'; import { BugReport } from '@/pages/BugReport'; import { MailList } from '@/pages/MailList'; import { Customs } from '@/pages/Customs'; +import { LicenseList } from '@/components/license/LicenseList'; +import { PartList } from '@/pages/PartList'; import { comms } from '@/communication'; import { UserInfo } from '@/types'; import { Loader2 } from 'lucide-react'; @@ -101,6 +103,8 @@ export default function App() { } /> } /> } /> + } /> + } /> {/* Tailwind Breakpoint Indicator - 개발용 */} diff --git a/Project/frontend/src/communication.ts b/Project/frontend/src/communication.ts index 24c8028..3ab48ce 100644 --- a/Project/frontend/src/communication.ts +++ b/Project/frontend/src/communication.ts @@ -42,6 +42,8 @@ import type { BoardItem, MailItem, CustomItem, + LicenseItem, + PartListItem, } from '@/types'; // WebView2 환경 감지 @@ -464,6 +466,21 @@ class CommunicationLayer { } } + public async saveProjectHistory(historyData: { idx?: number; pidx: number; pdate: string; progress: number; remark: string }): Promise { + if (isWebView && machine) { + const result = await machine.Project_SaveHistory( + historyData.idx || 0, + historyData.pidx, + historyData.pdate, + historyData.progress, + historyData.remark + ); + return JSON.parse(result); + } else { + return this.wsRequest('PROJECT_SAVE_HISTORY', 'PROJECT_SAVE_HISTORY_RESULT', historyData); + } + } + // ===== Login API ===== @@ -1361,6 +1378,64 @@ class CommunicationLayer { } } + /** + * 메일 데이터 추가 (발송 대기열) + * @param cate 분류 + * @param subject 제목 + * @param fromlist 발신자 + * @param tolist 수신자 + * @param cc 참조 + * @param bcc 숨은참조 + * @param body 내용 + * @returns ApiResponse + */ + public async addMailData(cate: string, subject: string, fromlist: string, tolist: string, cc: string, bcc: string, body: string): Promise { + if (isWebView && machine) { + const result = await machine.Mail_AddData(cate, subject, fromlist, tolist, cc, bcc, body); + return JSON.parse(result); + } else { + return this.wsRequest('MAIL_ADD_DATA', 'MAIL_ADD_DATA_RESULT', { cate, subject, fromlist, tolist, cc, bcc, body }); + } + } + + /** + * 메일 직접 발송 (SMTP) + * @param cate 분류 + * @param subject 제목 + * @param fromlist 발신자 + * @param tolist 수신자 + * @param cc 참조 + * @param bcc 숨은참조 + * @param body 내용 + * @returns ApiResponse + */ + public async sendMailDirect(cate: string, subject: string, fromlist: string, tolist: string, cc: string, bcc: string, body: string): Promise { + if (isWebView && machine) { + const result = await machine.Mail_SendDirect(cate, subject, fromlist, tolist, cc, bcc, body); + return JSON.parse(result); + } else { + return this.wsRequest('MAIL_SEND_DIRECT', 'MAIL_SEND_DIRECT_RESULT', { cate, subject, fromlist, tolist, cc, bcc, body }); + } + } + + /** + * Outlook으로 메일 미리보기/발송 + * @param subject 제목 + * @param tolist 수신자 + * @param cc 참조 + * @param bcc 숨은참조 + * @param body 내용 + * @returns ApiResponse + */ + public async sendMailOutlook(subject: string, tolist: string, cc: string, bcc: string, body: string): Promise { + if (isWebView && machine) { + const result = await machine.Mail_SendOutlook(subject, tolist, cc, bcc, body); + return JSON.parse(result); + } else { + return this.wsRequest('MAIL_SEND_OUTLOOK', 'MAIL_SEND_OUTLOOK_RESULT', { subject, tolist, cc, bcc, body }); + } + } + /** * 업체정보 목록 조회 * @param searchKey 검색어 @@ -1388,6 +1463,175 @@ class CommunicationLayer { return this.wsRequest>('CUSTOMS_GET_DETAIL', 'CUSTOMS_DETAIL_DATA', { idx }); } } + + /** + * 라이선스 목록 조회 + * @returns ApiResponse + */ + public async getLicenseList(): Promise> { + if (isWebView && machine) { + const result = await machine.License_GetList(); + return JSON.parse(result); + } else { + return this.wsRequest>('LICENSE_GET_LIST', 'LICENSE_LIST_DATA', {}); + } + } + + /** + * 라이선스 추가 + */ + public async addLicense( + name: string, + version: string, + meterialNo: string, + supply: string, + qty: number, + uids: string, + serialNo: string, + remark: string, + sdate: string, + edate: string, + manu: string, + expire: boolean + ): Promise { + if (isWebView && machine) { + const result = await machine.License_Add(name, version, meterialNo, supply, qty, uids, serialNo, remark, sdate, edate, manu, expire); + return JSON.parse(result); + } else { + return this.wsRequest('LICENSE_ADD', 'LICENSE_ADD_RESULT', { + name, version, meterialNo, supply, qty, uids, serialNo, remark, sdate, edate, manu, expire + }); + } + } + + /** + * 라이선스 수정 + */ + public async updateLicense( + idx: number, + name: string, + version: string, + meterialNo: string, + supply: string, + qty: number, + uids: string, + serialNo: string, + remark: string, + sdate: string, + edate: string, + manu: string, + expire: boolean + ): Promise { + if (isWebView && machine) { + const result = await machine.License_Update(idx, name, version, meterialNo, supply, qty, uids, serialNo, remark, sdate, edate, manu, expire); + return JSON.parse(result); + } else { + return this.wsRequest('LICENSE_UPDATE', 'LICENSE_UPDATE_RESULT', { + idx, name, version, meterialNo, supply, qty, uids, serialNo, remark, sdate, edate, manu, expire + }); + } + } + + /** + * 라이선스 삭제 + */ + public async deleteLicense(idx: number): Promise { + if (isWebView && machine) { + const result = await machine.License_Delete(idx); + return JSON.parse(result); + } else { + return this.wsRequest('LICENSE_DELETE', 'LICENSE_DELETE_RESULT', { idx }); + } + } + + /** + * 라이선스 폴더 열기 + */ + public async openLicenseFolder(idx: number): Promise { + if (isWebView && machine) { + const result = await machine.License_OpenFolder(idx); + return JSON.parse(result); + } else { + return this.wsRequest('LICENSE_OPEN_FOLDER', 'LICENSE_OPEN_FOLDER_RESULT', { idx }); + } + } + + /** + * 라이선스 CSV 내보내기 + */ + public async exportLicenseCSV(filePath: string): Promise { + if (isWebView && machine) { + const result = await machine.License_ExportCSV(filePath); + return JSON.parse(result); + } else { + return this.wsRequest('LICENSE_EXPORT_CSV', 'LICENSE_EXPORT_CSV_RESULT', { filePath }); + } + } + + // ===== PartList API ===== + + /** + * 프로젝트별 파트리스트 조회 + */ + public async getPartList(projectIdx: number): Promise> { + if (isWebView && machine) { + const result = await machine.PartList_GetList(projectIdx); + return JSON.parse(result); + } else { + return this.wsRequest>('PARTLIST_GET_LIST', 'PARTLIST_LIST_DATA', { projectIdx }); + } + } + + /** + * 파트리스트 항목 저장 (추가/수정) + */ + public async savePartList( + idx: number, + projectIdx: number, + itemgroup: string, + itemname: string, + item: string, + itemmodel: string, + itemscale: string, + itemunit: string, + qty: number, + price: number, + itemsupply: string, + itemsupplyidx: number, + itemmanu: string, + itemsid: string, + option1: string, + remark: string, + no: number, + qtybuy: number + ): Promise { + if (isWebView && machine) { + const result = await machine.PartList_Save( + idx, projectIdx, itemgroup, itemname, item, itemmodel, itemscale, + itemunit, qty, price, itemsupply, itemsupplyidx, itemmanu, itemsid, + option1, remark, no, qtybuy + ); + return JSON.parse(result); + } else { + return this.wsRequest('PARTLIST_SAVE', 'PARTLIST_SAVE_RESULT', { + idx, projectIdx, itemgroup, itemname, item, itemmodel, itemscale, + itemunit, qty, price, itemsupply, itemsupplyidx, itemmanu, itemsid, + option1, remark, no, qtybuy + }); + } + } + + /** + * 파트리스트 항목 삭제 + */ + public async deletePartList(idx: number): Promise { + if (isWebView && machine) { + const result = await machine.PartList_Delete(idx); + return JSON.parse(result); + } else { + return this.wsRequest('PARTLIST_DELETE', 'PARTLIST_DELETE_RESULT', { idx }); + } + } } export const comms = new CommunicationLayer(); diff --git a/Project/frontend/src/components/jobreport/JobreportEditModal.tsx b/Project/frontend/src/components/jobreport/JobreportEditModal.tsx index a82f9f4..f90cd44 100644 --- a/Project/frontend/src/components/jobreport/JobreportEditModal.tsx +++ b/Project/frontend/src/components/jobreport/JobreportEditModal.tsx @@ -262,7 +262,9 @@ export function JobreportEditModal({ onMouseDown={(e) => e.stopPropagation()} > {/* 헤더 */} -
+

{editingItem ? '업무일지 수정' : '업무일지 등록'} diff --git a/Project/frontend/src/components/layout/Header.tsx b/Project/frontend/src/components/layout/Header.tsx index 098514c..d635bb6 100644 --- a/Project/frontend/src/components/layout/Header.tsx +++ b/Project/frontend/src/components/layout/Header.tsx @@ -22,8 +22,11 @@ import { Building, Star, Bug, + Settings, + Key, } from 'lucide-react'; import { clsx } from 'clsx'; +import { comms } from '@/communication'; import { UserInfoDialog } from '@/components/user/UserInfoDialog'; import { UserGroupDialog } from '@/components/user/UserGroupDialog'; import { KuntaeErrorCheckDialog } from '@/components/kuntae/KuntaeErrorCheckDialog'; @@ -39,6 +42,7 @@ interface NavItem { icon: React.ElementType; label: string; action?: string; + className?: string; // 추가: 클래스 이름 } interface SubMenu { @@ -54,6 +58,7 @@ interface MenuItem { label: string; submenu?: SubMenu; action?: string; + className?: string; // gold 등 스타일 적용용 } interface DropdownMenuConfig { @@ -78,6 +83,13 @@ const leftDropdownMenus: DropdownMenuConfig[] = [ { type: 'action', icon: AlertTriangle, label: '오류검사', action: 'kuntaeErrorCheck' }, ], }, + { + label: '관리', + icon: Settings, + items: [ + { type: 'link', path: '/license', icon: Key, label: '라이선스' }, + ], + }, ]; // 좌측 단독 액션 버튼 @@ -90,44 +102,54 @@ const rightNavItems: NavItem[] = [ ]; // 드롭다운 메뉴 (2단계 지원) -const dropdownMenus: DropdownMenuConfig[] = [ - { - label: '공용정보', - icon: Database, - items: [ - { type: 'link', path: '/common', icon: Code, label: '공용코드' }, - { type: 'link', path: '/items', icon: Package, label: '품목정보' }, - { type: 'link', path: '/customs', icon: Building, label: '업체정보' }, - { - type: 'submenu', - icon: Users, - label: '사용자', - submenu: { - label: '사용자', +const getDropdownMenus = (userLevel: number, userCode: string): DropdownMenuConfig[] => { + const mailListItem = { + type: 'link' as const, + path: '/mail-list', + icon: Mail, + label: '메일 내역', + className: (userCode === '395552') ? 'text-[gold] font-bold' : '', + }; + + return [ + { + label: '공용정보', + icon: Database, + items: [ + { type: 'link', path: '/common', icon: Code, label: '공용코드' }, + { type: 'link', path: '/items', icon: Package, label: '품목정보' }, + { type: 'link', path: '/customs', icon: Building, label: '업체정보' }, + { + type: 'submenu', icon: Users, - items: [ - { icon: User, label: '정보', action: 'userInfo' }, - { path: '/user/list', icon: Users, label: '목록' }, - { path: '/user/auth', icon: Shield, label: '권한' }, - { icon: Users, label: '그룹정보', action: 'userGroup' }, - ], + label: '사용자', + submenu: { + label: '사용자', + icon: Users, + items: [ + { icon: User, label: '정보', action: 'userInfo' }, + { path: '/user/list', icon: Users, label: '목록' }, + { path: '/user/auth', icon: Shield, label: '권한' }, + { icon: Users, label: '그룹정보', action: 'userGroup' }, + ], + }, }, - }, - { type: 'link', path: '/monthly-work', icon: CalendarDays, label: '월별근무표' }, - { type: 'link', path: '/mail-form', icon: Mail, label: '메일양식' }, - ], - }, - { - label: '문서', - icon: FileText, - items: [ - { type: 'link', path: '/note', icon: FileText, label: '메모장' }, - { type: 'link', path: '/patch-list', icon: FileText, label: '패치 내역' }, - { type: 'link', path: '/bug-report', icon: Bug, label: '버그 신고' }, - { type: 'link', path: '/mail-list', icon: Mail, label: '메일 내역' }, - ], - }, -]; + { type: 'link', path: '/monthly-work', icon: CalendarDays, label: '월별근무표' }, + { type: 'link', path: '/mail-form', icon: Mail, label: '메일양식' }, + ], + }, + { + label: '문서', + icon: FileText, + items: [ + { type: 'link', path: '/note', icon: FileText, label: '메모장' }, + { type: 'link', path: '/patch-list', icon: FileText, label: '패치 내역' }, + { type: 'link', path: '/bug-report', icon: Bug, label: '버그 신고' }, + ...(userLevel >= 9 || userCode === '395552' ? [mailListItem] : []), + ], + }, + ]; +}; function DropdownNavMenu({ menu, @@ -194,7 +216,7 @@ function DropdownNavMenu({ 'flex items-center space-x-2 px-4 py-2 text-sm transition-colors', isActive ? 'bg-white/20 text-white' - : 'text-white/70 hover:bg-white/10 hover:text-white' + : (item.className || 'text-white/70 hover:bg-white/10 hover:text-white') ) } > @@ -326,7 +348,7 @@ function MobileDropdownMenu({ 'flex items-center space-x-3 px-4 py-2 rounded-lg transition-all duration-200', isActive ? 'bg-white/20 text-white' - : 'text-white/70 hover:bg-white/10 hover:text-white' + : (item.className || 'text-white/70 hover:bg-white/10 hover:text-white') ) } > @@ -373,7 +395,7 @@ function MobileDropdownMenu({ 'flex items-center space-x-3 px-4 py-2 rounded-lg transition-all duration-200', isActive ? 'bg-white/20 text-white' - : 'text-white/70 hover:bg-white/10 hover:text-white' + : (item.className || 'text-white/70 hover:bg-white/10 hover:text-white') ) } > @@ -409,6 +431,27 @@ export function Header(_props: HeaderProps) { const [showUserGroupDialog, setShowUserGroupDialog] = useState(false); const [showKuntaeErrorCheckDialog, setShowKuntaeErrorCheckDialog] = useState(false); const [showFavoriteDialog, setShowFavoriteDialog] = useState(false); + const [userLevel, setUserLevel] = useState(0); + const [userCode, setUserCode] = useState(''); + + // 사용자 정보 로드 + useEffect(() => { + const loadUserInfo = async () => { + try { + const loginStatus = await comms.checkLoginStatus(); + console.log('Login Status:', loginStatus); + if (loginStatus.Success && loginStatus.IsLoggedIn && loginStatus.User) { + const user = loginStatus.User as { Level?: number; Id?: string }; + setUserLevel(user.Level || 0); + setUserCode(user.Id || ''); + console.log('userLevel:', user.Level, 'userCode:', user.Id); + } + } catch (error) { + console.error('사용자 정보 로드 오류:', error); + } + }; + loadUserInfo(); + }, []); const handleAction = (action: string) => { if (action === 'userInfo') { @@ -485,7 +528,7 @@ export function Header(_props: HeaderProps) { {/* Desktop Navigation - Right */}