..
This commit is contained in:
@@ -22,9 +22,9 @@ namespace Project.Dialog
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
#if WEB
|
||||
|
||||
InitializeWebView2();
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
private void InitializeWebView2()
|
||||
|
||||
63
Project/Dialog/fWarning.Designer.cs
generated
Normal file
63
Project/Dialog/fWarning.Designer.cs
generated
Normal file
@@ -0,0 +1,63 @@
|
||||
namespace Project.Dialog
|
||||
{
|
||||
partial class fWarning
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.label1.Location = new System.Drawing.Point(0, 0);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(543, 66);
|
||||
this.label1.TabIndex = 0;
|
||||
this.label1.Text = " 실행 환경을 검사하고 있습니다";
|
||||
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
|
||||
//
|
||||
// fWarning
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 12F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(543, 66);
|
||||
this.Controls.Add(this.label1);
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "fWarning";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "fWarning";
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Label label1;
|
||||
}
|
||||
}
|
||||
20
Project/Dialog/fWarning.cs
Normal file
20
Project/Dialog/fWarning.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Project.Dialog
|
||||
{
|
||||
public partial class fWarning : Form
|
||||
{
|
||||
public fWarning()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
120
Project/Dialog/fWarning.resx
Normal file
120
Project/Dialog/fWarning.resx
Normal file
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -51,7 +51,7 @@
|
||||
<DebugType>Full</DebugType>
|
||||
<Optimize>False</Optimize>
|
||||
<OutputPath>..\..\..\..\..\Amkor\GroupWare\</OutputPath>
|
||||
<DefineConstants>TRACE;DEBUG;WEB</DefineConstants>
|
||||
<DefineConstants>TRACE;DEBUG;WEB1</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
@@ -265,6 +265,12 @@
|
||||
<Compile Include="Dialog\fLogin_WB.Designer.cs">
|
||||
<DependentUpon>fLogin_WB.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Dialog\fWarning.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Dialog\fWarning.Designer.cs">
|
||||
<DependentUpon>fWarning.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Web\Controller\BaseController.cs" />
|
||||
<Compile Include="Web\Controller\APIController.cs" />
|
||||
<Compile Include="Web\Controller\DashBoardController.cs" />
|
||||
@@ -493,6 +499,9 @@
|
||||
<EmbeddedResource Include="Dialog\fUnZip.resx">
|
||||
<DependentUpon>fUnZip.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Dialog\fWarning.resx">
|
||||
<DependentUpon>fWarning.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="fLog.resx">
|
||||
<DependentUpon>fLog.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
||||
@@ -9,6 +9,10 @@ using System.Net.NetworkInformation;
|
||||
using System.Net;
|
||||
using System.Data.SqlClient;
|
||||
using System.Data;
|
||||
using Microsoft.Web.WebView2.Core;
|
||||
using Microsoft.Web.WebView2.WinForms;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Project
|
||||
{
|
||||
@@ -55,6 +59,55 @@ namespace Project
|
||||
Lang.Loading(Pub.setting.Language + ".ini");
|
||||
}
|
||||
|
||||
private static WebView2 webView21;
|
||||
public static void InitializeWebView2()
|
||||
{
|
||||
// 수동으로 WebView2 컨트롤 생성
|
||||
webView21 = new WebView2();
|
||||
|
||||
// 기본 속성 설정
|
||||
webView21.CreationProperties = null;
|
||||
webView21.DefaultBackgroundColor = Color.White;
|
||||
webView21.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
webView21.Location = new Point(0, 0);
|
||||
webView21.Name = "webView21";
|
||||
webView21.Size = new Size(800, 600);
|
||||
webView21.TabIndex = 0;
|
||||
webView21.ZoomFactor = 1D;
|
||||
|
||||
// 비동기 초기화
|
||||
InitializeAsync();
|
||||
}
|
||||
async private static void InitializeAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Fixed Version 경로 설정
|
||||
string runtimePath = System.IO.Path.Combine(Application.StartupPath, "WebView2Runtime");
|
||||
|
||||
if (System.IO.Directory.Exists(runtimePath))
|
||||
{
|
||||
var env = await CoreWebView2Environment.CreateAsync(runtimePath);
|
||||
await webView21.EnsureCoreWebView2Async(env);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// 시스템에 설치된 WebView2 사용
|
||||
await webView21.EnsureCoreWebView2Async();
|
||||
}
|
||||
|
||||
// OWIN 서버의 Login 페이지로 연결
|
||||
//webView21.Source = new Uri("http://127.0.0.1:9000/Home/Login");
|
||||
InitWebView = 1;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
InitWebView = 2;
|
||||
}
|
||||
}
|
||||
public static byte InitWebView = 0;
|
||||
|
||||
public static string MakePasswordEnc(string data)
|
||||
{
|
||||
var sha1 = new System.Security.Cryptography.SHA1CryptoServiceProvider();
|
||||
@@ -65,7 +118,7 @@ namespace Project
|
||||
encpass = encpass.Replace(" ", "");
|
||||
return encpass;
|
||||
}
|
||||
public static void SetFormStatus(ref System.Windows.Forms.Form f, string formid,Boolean read)
|
||||
public static void SetFormStatus(ref System.Windows.Forms.Form f, string formid, Boolean read)
|
||||
{
|
||||
var fi = new System.IO.FileInfo(Util.CurrentPath + "formSetting\\" + formid + ".xml");
|
||||
if (fi.Directory.Exists == false) fi.Directory.Create();
|
||||
|
||||
@@ -28,9 +28,6 @@ namespace Project.Web.Controllers
|
||||
if (p_order.Key != null) sql += " order by " + p_order.Value;
|
||||
}
|
||||
|
||||
|
||||
if (FCOMMON.info.Login.gcode == null)
|
||||
FCOMMON.info.Login.gcode = "EET1P";
|
||||
sql = sql.Replace("{gcode}", FCOMMON.info.Login.gcode);
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs; // "Data Source=K4FASQL.kr.ds.amkor.com,50150;Initial Catalog=EE;Persist Security Info=True;User ID=eeadm;Password=uJnU8a8q&DJ+ug-D!";
|
||||
@@ -80,8 +77,6 @@ namespace Project.Web.Controllers
|
||||
}
|
||||
|
||||
|
||||
if (FCOMMON.info.Login.gcode == null)
|
||||
FCOMMON.info.Login.gcode = "EET1P";
|
||||
sql = sql.Replace("{gcode}", FCOMMON.info.Login.gcode);
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;// "Data Source=K4FASQL.kr.ds.amkor.com,50150;Initial Catalog=EE;Persist Security Info=True;User ID=eeadm;Password=uJnU8a8q&DJ+ug-D!";
|
||||
|
||||
@@ -17,26 +17,35 @@ namespace Project.Web.Controllers
|
||||
|
||||
}
|
||||
|
||||
// PUT api/values/5
|
||||
public void Put(int id, [FromBody] string value)
|
||||
{
|
||||
}
|
||||
//// PUT api/values/5
|
||||
//public void Put(int id, [FromBody] string value)
|
||||
//{
|
||||
//}
|
||||
|
||||
// DELETE api/values/5
|
||||
public void Delete(int id)
|
||||
{
|
||||
}
|
||||
//// DELETE api/values/5
|
||||
//public void Delete(int id)
|
||||
//{
|
||||
//}
|
||||
|
||||
[HttpGet]
|
||||
public string TodayCountH()
|
||||
{
|
||||
|
||||
var sql = "select count(*) from EETGW_HolydayRequest " +
|
||||
"where gcode = 'EET1P' and conf = 1 and HolyDays > 0 and " +
|
||||
"sdate <= GETDATE() and edate >= GETDATE()";
|
||||
var cnt = DBM.ExecuteScalar(sql);
|
||||
return cnt.ToString();
|
||||
" where gcode = @gcode and isnull(conf,0) = 1 "+
|
||||
" and HolyDays > 0 and " +
|
||||
" sdate <= GETDATE() and edate >= GETDATE()";
|
||||
|
||||
var cn = DBM.getCn();
|
||||
cn.Open();
|
||||
|
||||
var cmd = new System.Data.SqlClient.SqlCommand(sql, cn);
|
||||
cmd.Parameters.Add("gcode", SqlDbType.VarChar).Value = FCOMMON.info.Login.gcode;
|
||||
var cnt1 = (int)cmd.ExecuteScalar();
|
||||
cmd.Dispose();
|
||||
cn.Dispose();
|
||||
|
||||
return cnt1.ToString();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
@@ -74,11 +83,88 @@ namespace Project.Web.Controllers
|
||||
};
|
||||
return CreateJsonResponse(response);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
[HttpGet]
|
||||
public HttpResponseMessage GetholyRequestUser()
|
||||
{
|
||||
var sql = string.Empty;
|
||||
sql = $" select uid,cate,sdate,edate,HolyReason,Users.name,holydays,holytimes,remark " +
|
||||
$" from EETGW_HolydayRequest INNER JOIN " +
|
||||
$" Users ON EETGW_HolydayRequest.uid = Users.id " +
|
||||
$" where EETGW_HolydayRequest.gcode = @gcode" +
|
||||
$" and isnull(conf,0) = 0 and HolyDays > 0 and sdate <= GETDATE() and edate >= GETDATE()";
|
||||
|
||||
//sql = sql.Replace("{gcode}", FCOMMON.info.Login.gcode);
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;// "Data Source=K4FASQL.kr.ds.amkor.com,50150;Initial Catalog=EE;Persist Security Info=True;User ID=eeadm;Password=uJnU8a8q&DJ+ug-D!";
|
||||
var cn = new System.Data.SqlClient.SqlConnection(cs);
|
||||
var cmd = new System.Data.SqlClient.SqlCommand(sql, cn);
|
||||
cmd.Parameters.AddWithValue("gcode", FCOMMON.info.Login.gcode);
|
||||
var da = new System.Data.SqlClient.SqlDataAdapter(cmd);
|
||||
var dt = new System.Data.DataTable();
|
||||
da.Fill(dt);
|
||||
da.Dispose();
|
||||
cmd.Dispose();
|
||||
cn.Dispose();
|
||||
|
||||
var txtjson = JsonConvert.SerializeObject(dt, new JsonSerializerSettings
|
||||
{
|
||||
NullValueHandling = NullValueHandling.Ignore
|
||||
});
|
||||
|
||||
var resp = new HttpResponseMessage()
|
||||
{
|
||||
Content = new StringContent(
|
||||
txtjson,
|
||||
System.Text.Encoding.UTF8,
|
||||
"application/json")
|
||||
};
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
|
||||
[HttpGet]
|
||||
public HttpResponseMessage GetCurrentUserCount()
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
var cn = DBM.getCn();
|
||||
|
||||
var sql = "select count(*) " +
|
||||
" from EETGW_GroupUser" +
|
||||
" where gcode = @gcode" +
|
||||
" and useUserState = 1 and useJobReport =1";
|
||||
|
||||
cn.Open();
|
||||
|
||||
var cmd = new System.Data.SqlClient.SqlCommand(sql, cn);
|
||||
cmd.Parameters.Add("gcode", SqlDbType.VarChar).Value = FCOMMON.info.Login.gcode;
|
||||
var cnt1 = (int)cmd.ExecuteScalar();
|
||||
cn.Dispose();
|
||||
|
||||
var response = new
|
||||
{
|
||||
Count = cnt1,
|
||||
Message = string.Empty,
|
||||
};
|
||||
return CreateJsonResponse(response);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var response = new
|
||||
{
|
||||
Count = 0,
|
||||
Message = ex.Message,
|
||||
};
|
||||
return CreateJsonResponse(response);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public HttpResponseMessage GetPurchaseWaitCount()
|
||||
@@ -171,6 +257,135 @@ namespace Project.Web.Controllers
|
||||
return resp;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public HttpResponseMessage GetPresentUserList()
|
||||
{
|
||||
try
|
||||
{
|
||||
var sql = "select * from vGroupUser where gcode = @gcode and useUserState = 1 and useJobReport = 1";
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
var cn = new System.Data.SqlClient.SqlConnection(cs);
|
||||
var cmd = new System.Data.SqlClient.SqlCommand(sql, cn);
|
||||
cmd.Parameters.AddWithValue("gcode", FCOMMON.info.Login.gcode);
|
||||
var da = new System.Data.SqlClient.SqlDataAdapter(cmd);
|
||||
var dt = new System.Data.DataTable();
|
||||
da.Fill(dt);
|
||||
da.Dispose();
|
||||
cmd.Dispose();
|
||||
cn.Dispose();
|
||||
|
||||
var txtjson = JsonConvert.SerializeObject(dt, new JsonSerializerSettings
|
||||
{
|
||||
NullValueHandling = NullValueHandling.Ignore
|
||||
});
|
||||
|
||||
var resp = new HttpResponseMessage()
|
||||
{
|
||||
Content = new StringContent(
|
||||
txtjson,
|
||||
System.Text.Encoding.UTF8,
|
||||
"application/json")
|
||||
};
|
||||
|
||||
return resp;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var response = new
|
||||
{
|
||||
Message = ex.Message,
|
||||
};
|
||||
return CreateJsonResponse(response);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public HttpResponseMessage GetPurchaseNRList()
|
||||
{
|
||||
try
|
||||
{
|
||||
var sql = "select pdate, process, pumname, pumscale, pumunit, pumqtyreq, pumprice, pumamt from Purchase where gcode = @gcode and state = '---' order by pdate desc";
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
var cn = new System.Data.SqlClient.SqlConnection(cs);
|
||||
var cmd = new System.Data.SqlClient.SqlCommand(sql, cn);
|
||||
cmd.Parameters.AddWithValue("gcode", FCOMMON.info.Login.gcode);
|
||||
var da = new System.Data.SqlClient.SqlDataAdapter(cmd);
|
||||
var dt = new System.Data.DataTable();
|
||||
da.Fill(dt);
|
||||
da.Dispose();
|
||||
cmd.Dispose();
|
||||
cn.Dispose();
|
||||
|
||||
var txtjson = JsonConvert.SerializeObject(dt, new JsonSerializerSettings
|
||||
{
|
||||
NullValueHandling = NullValueHandling.Ignore
|
||||
});
|
||||
|
||||
var resp = new HttpResponseMessage()
|
||||
{
|
||||
Content = new StringContent(
|
||||
txtjson,
|
||||
System.Text.Encoding.UTF8,
|
||||
"application/json")
|
||||
};
|
||||
|
||||
return resp;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var response = new
|
||||
{
|
||||
Message = ex.Message,
|
||||
};
|
||||
return CreateJsonResponse(response);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public HttpResponseMessage GetPurchaseCRList()
|
||||
{
|
||||
try
|
||||
{
|
||||
var sql = "select pdate, process, pumname, pumscale, pumunit, pumqtyreq, pumprice, pumamt from EETGW_PurchaseCR where gcode = @gcode and state = '---' order by pdate desc";
|
||||
|
||||
var cs = Properties.Settings.Default.gwcs;
|
||||
var cn = new System.Data.SqlClient.SqlConnection(cs);
|
||||
var cmd = new System.Data.SqlClient.SqlCommand(sql, cn);
|
||||
cmd.Parameters.AddWithValue("gcode", FCOMMON.info.Login.gcode);
|
||||
var da = new System.Data.SqlClient.SqlDataAdapter(cmd);
|
||||
var dt = new System.Data.DataTable();
|
||||
da.Fill(dt);
|
||||
da.Dispose();
|
||||
cmd.Dispose();
|
||||
cn.Dispose();
|
||||
|
||||
var txtjson = JsonConvert.SerializeObject(dt, new JsonSerializerSettings
|
||||
{
|
||||
NullValueHandling = NullValueHandling.Ignore
|
||||
});
|
||||
|
||||
var resp = new HttpResponseMessage()
|
||||
{
|
||||
Content = new StringContent(
|
||||
txtjson,
|
||||
System.Text.Encoding.UTF8,
|
||||
"application/json")
|
||||
};
|
||||
|
||||
return resp;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var response = new
|
||||
{
|
||||
Message = ex.Message,
|
||||
};
|
||||
return CreateJsonResponse(response);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[HttpGet]
|
||||
public HttpResponseMessage Index()
|
||||
|
||||
@@ -94,6 +94,26 @@
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
/* 스크롤바 스타일링 */
|
||||
.custom-scrollbar::-webkit-scrollbar {
|
||||
width: var(--scrollbar-width, 16px); /* 동적 스크롤바 너비 */
|
||||
}
|
||||
|
||||
.custom-scrollbar::-webkit-scrollbar-track {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.custom-scrollbar::-webkit-scrollbar-thumb {
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
border-radius: 8px;
|
||||
border: 2px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="gradient-bg min-h-screen">
|
||||
@@ -101,14 +121,27 @@
|
||||
<!-- 헤더 -->
|
||||
<div class="text-center mb-8 animate-fade-in">
|
||||
<h1 class="text-4xl font-bold text-white mb-2">근태현황 대시보드</h1>
|
||||
<p class="text-white/80 text-lg">실시간 근태 현황을 확인하세요</p>
|
||||
<p class="text-white/80 text-lg">-- 기능 테스트 중입니다 --</p>
|
||||
|
||||
<!-- 스크롤바 설정 -->
|
||||
<div class="mt-4 flex items-center justify-center gap-4">
|
||||
<label class="text-white/70 text-sm font-medium">스크롤바 크기:</label>
|
||||
<select id="scrollbarSize" class="bg-white/20 backdrop-blur-sm border border-white/30 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:ring-2 focus:ring-primary-400 transition-all">
|
||||
<option value="8">작게 (8px)</option>
|
||||
<option value="12">보통 (12px)</option>
|
||||
<option value="16" selected>크게 (16px)</option>
|
||||
<option value="20">매우 크게 (20px)</option>
|
||||
<option value="24">터치용 (24px)</option>
|
||||
<option value="32">매우 터치용 (32px)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 통계 카드 -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-6 mb-8">
|
||||
|
||||
<!-- 출근 카드 -->
|
||||
<div class="glass-effect rounded-2xl p-6 card-hover animate-slide-up">
|
||||
<div class="glass-effect rounded-2xl p-6 card-hover animate-slide-up cursor-pointer" onclick="showPresentUserModal()">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-white/70 text-sm font-medium">출근</p>
|
||||
@@ -138,7 +171,7 @@
|
||||
</div>
|
||||
|
||||
<!-- 휴가요청 카드 -->
|
||||
<div class="glass-effect rounded-2xl p-6 card-hover animate-slide-up">
|
||||
<div class="glass-effect rounded-2xl p-6 card-hover animate-slide-up cursor-pointer" onclick="showHolidayRequestModal()">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-white/70 text-sm font-medium">휴가요청</p>
|
||||
@@ -153,7 +186,7 @@
|
||||
</div>
|
||||
|
||||
<!-- 구매요청 카드(NR) -->
|
||||
<div class="glass-effect rounded-2xl p-6 card-hover animate-slide-up">
|
||||
<div class="glass-effect rounded-2xl p-6 card-hover animate-slide-up cursor-pointer" onclick="showPurchaseNRModal()">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-white/70 text-sm font-medium">구매요청(NR)</p>
|
||||
@@ -168,7 +201,7 @@
|
||||
</div>
|
||||
|
||||
<!-- 구매요청 카드(CR) -->
|
||||
<div class="glass-effect rounded-2xl p-6 card-hover animate-slide-up">
|
||||
<div class="glass-effect rounded-2xl p-6 card-hover animate-slide-up cursor-pointer" onclick="showPurchaseCRModal()">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<p class="text-white/70 text-sm font-medium">구매요청(CR)</p>
|
||||
@@ -220,6 +253,207 @@
|
||||
데이터 업데이트 중...
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 출근 대상자 모달 -->
|
||||
<div id="presentUserModal" class="fixed inset-0 bg-black/50 backdrop-blur-sm hidden z-50">
|
||||
<div class="flex items-center justify-center min-h-screen p-4">
|
||||
<div class="glass-effect rounded-2xl w-full max-w-4xl max-h-[80vh] overflow-hidden animate-slide-up">
|
||||
<!-- 모달 헤더 -->
|
||||
<div class="px-6 py-4 border-b border-white/10 flex items-center justify-between">
|
||||
<h2 class="text-xl font-semibold text-white flex items-center">
|
||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
||||
</svg>
|
||||
금일 출근 대상자 목록
|
||||
</h2>
|
||||
<button onclick="hidePresentUserModal()" class="text-white/70 hover:text-white transition-colors">
|
||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 모달 내용 -->
|
||||
<div class="overflow-x-auto max-h-[60vh] custom-scrollbar">
|
||||
<table class="w-full">
|
||||
<thead class="bg-white/10 sticky top-0">
|
||||
<tr>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">사번</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">이름</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">공정</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">직급</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">상태</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">이메일</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="presentUserTable" class="divide-y divide-white/10">
|
||||
<!-- 데이터가 여기에 표시됩니다 -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 모달 푸터 -->
|
||||
<div class="px-6 py-4 border-t border-white/10 flex justify-between items-center">
|
||||
<p class="text-white/70 text-sm">총 <span id="presentUserCount">0</span>명</p>
|
||||
<button onclick="hidePresentUserModal()" class="bg-white/20 hover:bg-white/30 text-white px-4 py-2 rounded-lg transition-colors">
|
||||
닫기
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 휴가요청 모달 -->
|
||||
<div id="holidayRequestModal" class="fixed inset-0 bg-black/50 backdrop-blur-sm hidden z-50">
|
||||
<div class="flex items-center justify-center min-h-screen p-4">
|
||||
<div class="glass-effect rounded-2xl w-full max-w-6xl max-h-[80vh] overflow-hidden animate-slide-up">
|
||||
<!-- 모달 헤더 -->
|
||||
<div class="px-6 py-4 border-b border-white/10 flex items-center justify-between">
|
||||
<h2 class="text-xl font-semibold text-white flex items-center">
|
||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
|
||||
</svg>
|
||||
휴가 신청 목록
|
||||
</h2>
|
||||
<button onclick="hideHolidayRequestModal()" class="text-white/70 hover:text-white transition-colors">
|
||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 모달 내용 -->
|
||||
<div class="overflow-x-auto max-h-[60vh] custom-scrollbar">
|
||||
<table class="w-full">
|
||||
<thead class="bg-white/10 sticky top-0">
|
||||
<tr>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">사번</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">이름</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">항목</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">일자</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">요청일</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">요청시간</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">비고</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="holidayRequestTable" class="divide-y divide-white/10">
|
||||
<!-- 데이터가 여기에 표시됩니다 -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 모달 푸터 -->
|
||||
<div class="px-6 py-4 border-t border-white/10 flex justify-between items-center">
|
||||
<p class="text-white/70 text-sm">총 <span id="holidayRequestCount">0</span>건</p>
|
||||
<button onclick="hideHolidayRequestModal()" class="bg-white/20 hover:bg-white/30 text-white px-4 py-2 rounded-lg transition-colors">
|
||||
닫기
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 구매NR 모달 -->
|
||||
<div id="purchaseNRModal" class="fixed inset-0 bg-black/50 backdrop-blur-sm hidden z-50">
|
||||
<div class="flex items-center justify-center min-h-screen p-4">
|
||||
<div class="glass-effect rounded-2xl w-full max-w-7xl max-h-[80vh] overflow-hidden animate-slide-up">
|
||||
<!-- 모달 헤더 -->
|
||||
<div class="px-6 py-4 border-b border-white/10 flex items-center justify-between">
|
||||
<h2 class="text-xl font-semibold text-white flex items-center">
|
||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z"></path>
|
||||
</svg>
|
||||
구매요청(NR) 목록
|
||||
</h2>
|
||||
<button onclick="hidePurchaseNRModal()" class="text-white/70 hover:text-white transition-colors">
|
||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 모달 내용 -->
|
||||
<div class="overflow-x-auto max-h-[60vh] custom-scrollbar">
|
||||
<table class="w-full">
|
||||
<thead class="bg-white/10 sticky top-0">
|
||||
<tr>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">요청일</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">공정</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">품명</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">규격</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">단위</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">수량</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">단가</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">금액</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="purchaseNRTable" class="divide-y divide-white/10">
|
||||
<!-- 데이터가 여기에 표시됩니다 -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 모달 푸터 -->
|
||||
<div class="px-6 py-4 border-t border-white/10 flex justify-between items-center">
|
||||
<p class="text-white/70 text-sm">총 <span id="purchaseNRCount">0</span>건</p>
|
||||
<button onclick="hidePurchaseNRModal()" class="bg-white/20 hover:bg-white/30 text-white px-4 py-2 rounded-lg transition-colors">
|
||||
닫기
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 구매CR 모달 -->
|
||||
<div id="purchaseCRModal" class="fixed inset-0 bg-black/50 backdrop-blur-sm hidden z-50">
|
||||
<div class="flex items-center justify-center min-h-screen p-4">
|
||||
<div class="glass-effect rounded-2xl w-full max-w-7xl max-h-[80vh] overflow-hidden animate-slide-up">
|
||||
<!-- 모달 헤더 -->
|
||||
<div class="px-6 py-4 border-b border-white/10 flex items-center justify-between">
|
||||
<h2 class="text-xl font-semibold text-white flex items-center">
|
||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z"></path>
|
||||
</svg>
|
||||
구매요청(CR) 목록
|
||||
</h2>
|
||||
<button onclick="hidePurchaseCRModal()" class="text-white/70 hover:text-white transition-colors">
|
||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 모달 내용 -->
|
||||
<div class="overflow-x-auto max-h-[60vh] custom-scrollbar">
|
||||
<table class="w-full">
|
||||
<thead class="bg-white/10 sticky top-0">
|
||||
<tr>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">요청일</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">공정</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">품명</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">규격</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">단위</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">수량</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">단가</th>
|
||||
<th class="px-6 py-4 text-left text-xs font-medium text-white/70 uppercase tracking-wider">금액</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="purchaseCRTable" class="divide-y divide-white/10">
|
||||
<!-- 데이터가 여기에 표시됩니다 -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 모달 푸터 -->
|
||||
<div class="px-6 py-4 border-t border-white/10 flex justify-between items-center">
|
||||
<p class="text-white/70 text-sm">총 <span id="purchaseCRCount">0</span>건</p>
|
||||
<button onclick="hidePurchaseCRModal()" class="bg-white/20 hover:bg-white/30 text-white px-4 py-2 rounded-lg transition-colors">
|
||||
닫기
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
@@ -333,6 +567,25 @@
|
||||
});
|
||||
}
|
||||
|
||||
// 사용자카운트 데이터 Ajax 업데이트
|
||||
function updateCurrentUserCount() {
|
||||
showLoading();
|
||||
fetch('http://127.0.0.1:9000/DashBoard/GetCurrentUserCount')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data) {
|
||||
// NR 구매요청 카운트 업데이트
|
||||
if (data.Count !== undefined) {
|
||||
animateNumberChange('presentCount', data.Count);
|
||||
}
|
||||
}
|
||||
hideLoading();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('현재유저 카운트 업데이트 중 오류 발생:', error);
|
||||
hideLoading();
|
||||
});
|
||||
}
|
||||
|
||||
// 숫자 애니메이션
|
||||
function animateNumberChange(elementId, newValue) {
|
||||
@@ -366,13 +619,351 @@
|
||||
updateHolidayList();
|
||||
updatePurchaseCount();
|
||||
updateHolydayRequestCount();
|
||||
updateCurrentUserCount();
|
||||
|
||||
// 스크롤바 크기 설정 초기화
|
||||
initializeScrollbarSize();
|
||||
|
||||
// 30초마다 데이터 새로고침
|
||||
setInterval(() => {
|
||||
updateLeaveCount();
|
||||
updateHolidayList();
|
||||
updatePurchaseCount();
|
||||
updateHolydayRequestCount();
|
||||
updateCurrentUserCount();
|
||||
}, 30000);
|
||||
|
||||
// 출근 대상자 모달 표시
|
||||
function showPresentUserModal() {
|
||||
document.getElementById('presentUserModal').classList.remove('hidden');
|
||||
loadPresentUserList();
|
||||
}
|
||||
|
||||
// 출근 대상자 모달 숨기기
|
||||
function hidePresentUserModal() {
|
||||
document.getElementById('presentUserModal').classList.add('hidden');
|
||||
}
|
||||
|
||||
// 출근 대상자 목록 로드
|
||||
function loadPresentUserList() {
|
||||
showLoading();
|
||||
fetch('http://127.0.0.1:9000/DashBoard/GetPresentUserList')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
let tableRows = '';
|
||||
if (data && data.length > 0) {
|
||||
data.forEach(item => {
|
||||
const statusClass = item.useUserState == 1 ? 'bg-success-500/20 text-success-300' : 'bg-danger-500/20 text-danger-300';
|
||||
const statusText = item.useUserState == 1 ? '활성' : '비활성';
|
||||
|
||||
tableRows += `
|
||||
<tr class="hover:bg-white/5 transition-colors">
|
||||
<td class="px-6 py-4 whitespace-nowrap text-white">${item.id || '-'}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-white">${item.name || '-'}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-white/80">${item.processs || '-'}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-white/80">${item.grade || '-'}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${statusClass}">
|
||||
${statusText}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-white/80">${item.email || '-'}</td>
|
||||
</tr>
|
||||
`;
|
||||
});
|
||||
document.getElementById('presentUserCount').textContent = data.length;
|
||||
} else {
|
||||
tableRows = `
|
||||
<tr>
|
||||
<td colspan="5" class="px-6 py-8 text-center text-white/50">
|
||||
출근 대상자가 없습니다
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
document.getElementById('presentUserCount').textContent = '0';
|
||||
}
|
||||
document.getElementById('presentUserTable').innerHTML = tableRows;
|
||||
hideLoading();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('출근 대상자 목록 로드 중 오류 발생:', error);
|
||||
document.getElementById('presentUserTable').innerHTML = `
|
||||
<tr>
|
||||
<td colspan="5" class="px-6 py-8 text-center text-danger-400">
|
||||
데이터를 불러오는 중 오류가 발생했습니다
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
document.getElementById('presentUserCount').textContent = '0';
|
||||
hideLoading();
|
||||
});
|
||||
}
|
||||
|
||||
// ESC 키로 모달 닫기
|
||||
document.addEventListener('keydown', function(event) {
|
||||
if (event.key === 'Escape') {
|
||||
hidePresentUserModal();
|
||||
hideHolidayRequestModal();
|
||||
hidePurchaseNRModal();
|
||||
hidePurchaseCRModal();
|
||||
}
|
||||
});
|
||||
|
||||
// 모달 외부 클릭으로 닫기
|
||||
document.getElementById('presentUserModal').addEventListener('click', function(event) {
|
||||
if (event.target === this) {
|
||||
hidePresentUserModal();
|
||||
}
|
||||
});
|
||||
|
||||
// 휴가요청 모달 표시
|
||||
function showHolidayRequestModal() {
|
||||
document.getElementById('holidayRequestModal').classList.remove('hidden');
|
||||
loadHolidayRequestList();
|
||||
}
|
||||
|
||||
// 휴가요청 모달 숨기기
|
||||
function hideHolidayRequestModal() {
|
||||
document.getElementById('holidayRequestModal').classList.add('hidden');
|
||||
}
|
||||
|
||||
// 휴가요청 목록 로드
|
||||
function loadHolidayRequestList() {
|
||||
showLoading();
|
||||
fetch('http://127.0.0.1:9000/DashBoard/GetholyRequestUser')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
let tableRows = '';
|
||||
if (data && data.length > 0) {
|
||||
data.forEach(item => {
|
||||
// 일자 포맷팅 (시작일 ~ 종료일)
|
||||
const startDate = item.sdate ? new Date(item.sdate).toLocaleDateString('ko-KR') : '-';
|
||||
const endDate = item.edate ? new Date(item.edate).toLocaleDateString('ko-KR') : '-';
|
||||
const dateRange = startDate !== '-' && endDate !== '-' ? `${startDate} ~ ${endDate}` : '-';
|
||||
|
||||
// 요청일 포맷팅
|
||||
const requestDate = item.holyday ? new Date(item.holyday).toLocaleDateString('ko-KR') : '-';
|
||||
|
||||
tableRows += `
|
||||
<tr class="hover:bg-white/5 transition-colors">
|
||||
<td class="px-6 py-4 whitespace-nowrap text-white">${item.uid || '-'}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-white">${item.name || '-'}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-primary-500/20 text-primary-300">
|
||||
${item.cate || '-'}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-white/80">${dateRange}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-white/80">${requestDate}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-white/80">${item.holytime || '-'}</td>
|
||||
<td class="px-6 py-4 text-white/80">${item.remakr || '-'}</td>
|
||||
</tr>
|
||||
`;
|
||||
});
|
||||
document.getElementById('holidayRequestCount').textContent = data.length;
|
||||
} else {
|
||||
tableRows = `
|
||||
<tr>
|
||||
<td colspan="7" class="px-6 py-8 text-center text-white/50">
|
||||
휴가 신청이 없습니다
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
document.getElementById('holidayRequestCount').textContent = '0';
|
||||
}
|
||||
document.getElementById('holidayRequestTable').innerHTML = tableRows;
|
||||
hideLoading();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('휴가요청 목록 로드 중 오류 발생:', error);
|
||||
document.getElementById('holidayRequestTable').innerHTML = `
|
||||
<tr>
|
||||
<td colspan="7" class="px-6 py-8 text-center text-danger-400">
|
||||
데이터를 불러오는 중 오류가 발생했습니다
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
document.getElementById('holidayRequestCount').textContent = '0';
|
||||
hideLoading();
|
||||
});
|
||||
}
|
||||
|
||||
// 휴가요청 모달 외부 클릭으로 닫기
|
||||
document.getElementById('holidayRequestModal').addEventListener('click', function(event) {
|
||||
if (event.target === this) {
|
||||
hideHolidayRequestModal();
|
||||
}
|
||||
});
|
||||
|
||||
// 구매NR 모달 표시
|
||||
function showPurchaseNRModal() {
|
||||
document.getElementById('purchaseNRModal').classList.remove('hidden');
|
||||
loadPurchaseNRList();
|
||||
}
|
||||
|
||||
// 구매NR 모달 숨기기
|
||||
function hidePurchaseNRModal() {
|
||||
document.getElementById('purchaseNRModal').classList.add('hidden');
|
||||
}
|
||||
|
||||
// 구매NR 목록 로드
|
||||
function loadPurchaseNRList() {
|
||||
showLoading();
|
||||
fetch('http://127.0.0.1:9000/DashBoard/GetPurchaseNRList')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
let tableRows = '';
|
||||
if (data && data.length > 0) {
|
||||
data.forEach(item => {
|
||||
// 요청일 포맷팅
|
||||
const requestDate = item.pdate ? new Date(item.pdate).toLocaleDateString('ko-KR') : '-';
|
||||
|
||||
// 금액 포맷팅 (천 단위 콤마)
|
||||
const amount = item.pumamt ? Number(item.pumamt).toLocaleString() : '-';
|
||||
const price = item.pumprice ? Number(item.pumprice).toLocaleString() : '-';
|
||||
|
||||
tableRows += `
|
||||
<tr class="hover:bg-white/5 transition-colors">
|
||||
<td class="px-6 py-4 whitespace-nowrap text-white/80">${requestDate}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-white/80">${item.process || '-'}</td>
|
||||
<td class="px-6 py-4 text-white">${item.pumname || '-'}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-white/80">${item.pumscale || '-'}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-white/80">${item.pumunit || '-'}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-white/80">${item.pumqtyreq || '-'}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-white/80">${price}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-white font-medium">${amount}</td>
|
||||
</tr>
|
||||
`;
|
||||
});
|
||||
document.getElementById('purchaseNRCount').textContent = data.length;
|
||||
} else {
|
||||
tableRows = `
|
||||
<tr>
|
||||
<td colspan="8" class="px-6 py-8 text-center text-white/50">
|
||||
구매요청이 없습니다
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
document.getElementById('purchaseNRCount').textContent = '0';
|
||||
}
|
||||
document.getElementById('purchaseNRTable').innerHTML = tableRows;
|
||||
hideLoading();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('구매NR 목록 로드 중 오류 발생:', error);
|
||||
document.getElementById('purchaseNRTable').innerHTML = `
|
||||
<tr>
|
||||
<td colspan="8" class="px-6 py-8 text-center text-danger-400">
|
||||
데이터를 불러오는 중 오류가 발생했습니다
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
document.getElementById('purchaseNRCount').textContent = '0';
|
||||
hideLoading();
|
||||
});
|
||||
}
|
||||
|
||||
// 구매NR 모달 외부 클릭으로 닫기
|
||||
document.getElementById('purchaseNRModal').addEventListener('click', function(event) {
|
||||
if (event.target === this) {
|
||||
hidePurchaseNRModal();
|
||||
}
|
||||
});
|
||||
|
||||
// 구매CR 모달 표시
|
||||
function showPurchaseCRModal() {
|
||||
document.getElementById('purchaseCRModal').classList.remove('hidden');
|
||||
loadPurchaseCRList();
|
||||
}
|
||||
|
||||
// 구매CR 모달 숨기기
|
||||
function hidePurchaseCRModal() {
|
||||
document.getElementById('purchaseCRModal').classList.add('hidden');
|
||||
}
|
||||
|
||||
// 구매CR 목록 로드
|
||||
function loadPurchaseCRList() {
|
||||
showLoading();
|
||||
fetch('http://127.0.0.1:9000/DashBoard/GetPurchaseCRList')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
let tableRows = '';
|
||||
if (data && data.length > 0) {
|
||||
data.forEach(item => {
|
||||
// 요청일 포맷팅
|
||||
const requestDate = item.pdate ? new Date(item.pdate).toLocaleDateString('ko-KR') : '-';
|
||||
|
||||
// 금액 포맷팅 (천 단위 콤마)
|
||||
const amount = item.pumamt ? Number(item.pumamt).toLocaleString() : '-';
|
||||
const price = item.pumprice ? Number(item.pumprice).toLocaleString() : '-';
|
||||
|
||||
tableRows += `
|
||||
<tr class="hover:bg-white/5 transition-colors">
|
||||
<td class="px-6 py-4 whitespace-nowrap text-white/80">${requestDate}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-white/80">${item.process || '-'}</td>
|
||||
<td class="px-6 py-4 text-white">${item.pumname || '-'}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-white/80">${item.pumscale || '-'}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-white/80">${item.pumunit || '-'}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-white/80">${item.pumqtyreq || '-'}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-white/80">${price}</td>
|
||||
<td class="px-6 py-4 whitespace-nowrap text-white font-medium">${amount}</td>
|
||||
</tr>
|
||||
`;
|
||||
});
|
||||
document.getElementById('purchaseCRCount').textContent = data.length;
|
||||
} else {
|
||||
tableRows = `
|
||||
<tr>
|
||||
<td colspan="8" class="px-6 py-8 text-center text-white/50">
|
||||
구매요청이 없습니다
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
document.getElementById('purchaseCRCount').textContent = '0';
|
||||
}
|
||||
document.getElementById('purchaseCRTable').innerHTML = tableRows;
|
||||
hideLoading();
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('구매CR 목록 로드 중 오류 발생:', error);
|
||||
document.getElementById('purchaseCRTable').innerHTML = `
|
||||
<tr>
|
||||
<td colspan="8" class="px-6 py-8 text-center text-danger-400">
|
||||
데이터를 불러오는 중 오류가 발생했습니다
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
document.getElementById('purchaseCRCount').textContent = '0';
|
||||
hideLoading();
|
||||
});
|
||||
}
|
||||
|
||||
// 구매CR 모달 외부 클릭으로 닫기
|
||||
document.getElementById('purchaseCRModal').addEventListener('click', function(event) {
|
||||
if (event.target === this) {
|
||||
hidePurchaseCRModal();
|
||||
}
|
||||
});
|
||||
|
||||
// 스크롤바 크기 초기화
|
||||
function initializeScrollbarSize() {
|
||||
const savedSize = localStorage.getItem('scrollbarSize') || '16';
|
||||
const select = document.getElementById('scrollbarSize');
|
||||
select.value = savedSize;
|
||||
updateScrollbarSize(savedSize);
|
||||
|
||||
// 콤보박스 변경 이벤트 리스너
|
||||
select.addEventListener('change', function() {
|
||||
const size = this.value;
|
||||
updateScrollbarSize(size);
|
||||
localStorage.setItem('scrollbarSize', size);
|
||||
});
|
||||
}
|
||||
|
||||
// 스크롤바 크기 업데이트
|
||||
function updateScrollbarSize(size) {
|
||||
document.documentElement.style.setProperty('--scrollbar-width', size + 'px');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -154,11 +154,8 @@
|
||||
class="input-field w-full px-4 py-3 bg-white/10 border border-white/20 rounded-xl text-white focus:outline-none focus:border-primary-400 input-focus appearance-none"
|
||||
required
|
||||
>
|
||||
<option value="" class="text-gray-800">부서를 선택하세요</option>
|
||||
<option value="" class="text-white/60">부서를 선택하세요</option>
|
||||
</select>
|
||||
<label for="gcode" class="floating-label absolute left-4 top-3 text-white/60 text-sm pointer-events-none">
|
||||
부서 선택
|
||||
</label>
|
||||
<div class="absolute right-3 top-3 pointer-events-none">
|
||||
<svg class="w-5 h-5 text-white/40" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
|
||||
@@ -172,13 +169,10 @@
|
||||
type="text"
|
||||
id="userId"
|
||||
name="userId"
|
||||
class="input-field w-full px-4 py-3 bg-white/10 border border-white/20 rounded-xl text-white placeholder-transparent focus:outline-none focus:border-primary-400 input-focus"
|
||||
placeholder="사용자 ID"
|
||||
class="input-field w-full px-4 py-3 bg-white/10 border border-white/20 rounded-xl text-white placeholder-white/60 focus:outline-none focus:border-primary-400 input-focus"
|
||||
placeholder="사원번호"
|
||||
required
|
||||
>
|
||||
<label for="userId" class="floating-label absolute left-4 top-3 text-white/60 text-sm pointer-events-none">
|
||||
사용자 ID
|
||||
</label>
|
||||
<div class="absolute right-3 top-3">
|
||||
<svg class="w-5 h-5 text-white/40" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"></path>
|
||||
@@ -192,13 +186,10 @@
|
||||
type="password"
|
||||
id="password"
|
||||
name="password"
|
||||
class="input-field w-full px-4 py-3 bg-white/10 border border-white/20 rounded-xl text-white placeholder-transparent focus:outline-none focus:border-primary-400 input-focus"
|
||||
class="input-field w-full px-4 py-3 bg-white/10 border border-white/20 rounded-xl text-white placeholder-white/60 focus:outline-none focus:border-primary-400 input-focus"
|
||||
placeholder="비밀번호"
|
||||
required
|
||||
>
|
||||
<label for="password" class="floating-label absolute left-4 top-3 text-white/60 text-sm pointer-events-none">
|
||||
비밀번호
|
||||
</label>
|
||||
<div class="absolute right-3 top-3">
|
||||
<svg class="w-5 h-5 text-white/40" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"></path>
|
||||
@@ -439,27 +430,13 @@
|
||||
// 부서 선택
|
||||
const gcodeSelect = document.getElementById('gcode');
|
||||
gcodeSelect.value = data.Gcode;
|
||||
|
||||
// 부서 선택 시 라벨 애니메이션 적용
|
||||
const label = gcodeSelect.nextElementSibling;
|
||||
if (label && label.classList.contains('floating-label')) {
|
||||
label.style.transform = 'translateY(-1.5rem) scale(0.85)';
|
||||
label.style.color = '#3b82f6';
|
||||
}
|
||||
hasPreviousInfo = true;
|
||||
}
|
||||
|
||||
if (data && data.UserId) {
|
||||
// 사용자 ID 설정
|
||||
document.getElementById('userId').value = data.UserId;
|
||||
|
||||
// 사용자 ID 입력 시 라벨 애니메이션 적용
|
||||
const userIdInput = document.getElementById('userId');
|
||||
const label = userIdInput.nextElementSibling;
|
||||
if (label && label.classList.contains('floating-label')) {
|
||||
label.style.transform = 'translateY(-1.5rem) scale(0.85)';
|
||||
label.style.color = '#3b82f6';
|
||||
}
|
||||
// 사용자 ID 설정 - 세미콜론으로 구분된 경우 첫 번째 요소만 사용
|
||||
const userId = data.UserId.split(';')[0];
|
||||
document.getElementById('userId').value = userId;
|
||||
hasPreviousInfo = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -105,10 +105,12 @@ namespace Project
|
||||
this.Text = Application.ProductName + " v" + Application.ProductVersion;
|
||||
Pub.init();
|
||||
|
||||
|
||||
|
||||
Pub.InitializeWebView2();
|
||||
setToolbar();
|
||||
|
||||
var f = new Dialog.fWarning();
|
||||
f.TopMost = true;
|
||||
f.Show();
|
||||
|
||||
_SetLang();
|
||||
if (Pub.setting.FullScreen) this.WindowState = FormWindowState.Maximized;
|
||||
@@ -137,10 +139,6 @@ namespace Project
|
||||
//Data Source=K4FASQL.kr.ds.amkor.com,50150;Initial Catalog=EE;Persist Security Info=True;User ID=eeadm;Password=uJnU8a8q&DJ+ug-D;Encrypt=False;TrustServerCertificate=True
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Pub.barcode = new Device.Barcode();
|
||||
if (!Pub.setting.Barcode.isEmpty()) Pub.barcode.PortName = Pub.setting.Barcode;
|
||||
Pub.barcode.ReceiveData += barcode_ReceiveData;
|
||||
@@ -167,8 +165,22 @@ namespace Project
|
||||
webok = false;
|
||||
}
|
||||
|
||||
var wat = new System.Diagnostics.Stopwatch();
|
||||
wat.Restart();
|
||||
while(true)
|
||||
{
|
||||
if (Pub.InitWebView != 0) break;
|
||||
if (wat.ElapsedMilliseconds > 5000) break;
|
||||
System.Threading.Thread.Sleep(1000);
|
||||
Application.DoEvents();
|
||||
}
|
||||
|
||||
f.Dispose();
|
||||
|
||||
Func_Login();
|
||||
|
||||
|
||||
|
||||
///즐겨찾기 목록 갱신
|
||||
Update_FavoriteSite();
|
||||
|
||||
@@ -204,18 +216,19 @@ namespace Project
|
||||
|
||||
void Func_Login()
|
||||
{
|
||||
#if WEB
|
||||
|
||||
//Pub.InitWebView = 2;
|
||||
if (Pub.InitWebView == 1)
|
||||
{
|
||||
using (var f = new Dialog.fLogin_WB())
|
||||
if (f.ShowDialog() != System.Windows.Forms.DialogResult.OK)
|
||||
Application.ExitThread();
|
||||
|
||||
#else
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var f = new Dialog.fLogin())
|
||||
if (f.ShowDialog() != System.Windows.Forms.DialogResult.OK)
|
||||
Application.ExitThread();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
this.mn_purchase.Visible = FCOMMON.Util.getBit(FCOMMON.info.Login.gpermission, (int)FCOMMON.eGroupPermission.menu_purchase);
|
||||
|
||||
Submodule Sub/AmkorRestfulService deleted from 69b33b6e3c
@@ -78,7 +78,7 @@ namespace FCOMMON
|
||||
var retval = new UserGroupModel();
|
||||
var cn = getCn();
|
||||
|
||||
var sql = "select * from UserGroup where gcode = @gcode";
|
||||
var sql = "select gcode,dept,isnull(permission,0) as permission from UserGroup where gcode = @gcode";
|
||||
var cmd = new System.Data.SqlClient.SqlCommand(sql, cn);
|
||||
cmd.Parameters.Add("gcode", SqlDbType.VarChar).Value = gcode;
|
||||
cn.Open();
|
||||
@@ -88,6 +88,7 @@ namespace FCOMMON
|
||||
{
|
||||
retval.gcode = rdr["gcode"].ToString();
|
||||
retval.name = rdr["dept"].ToString();
|
||||
retval.perm = int.Parse(rdr["permission"].ToString());
|
||||
cnt += 1;
|
||||
}
|
||||
cn.Dispose();
|
||||
|
||||
Reference in New Issue
Block a user