관리자페이지 개발

This commit is contained in:
hassong
2026-07-03 16:43:53 +09:00
parent 5d6ee943f6
commit 5022eba196
26 changed files with 3940 additions and 758 deletions

View File

@@ -3,44 +3,220 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D; // 둥근 모서리 그리기(GraphicsPath)에 필수
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;
namespace ControlServer
{
public partial class Form3 : Form
{
public Form3(string terminalName, string terminalIP) // 매개변수 추가
private Form1 _mainForm; // 메인 폼 참조 변수
private string _targetIP;
private string _filePath;
// 둥근 모서리 반지름 설정 (정수형 int로 선언)
private const int CornerRadiusValue = 15;
public Form3(Form1 mainForm, string terminalName, string terminalIP, string filePath)
{
InitializeComponent();
// 가져온 데이터를 Form3의 라벨이나 텍스트박스에 표시
// 1. 버튼 테두리 없애고 Flat 스타일 및 이벤트 연결
ConfigureModernStyles();
// 2. 그리드 디자인을 오른쪽 시안 스타일에 맞게 초기화
InitDataGridViewStyles();
_mainForm = mainForm;
_targetIP = terminalIP;
_filePath = filePath;
lblTerminalName.Text = terminalName;
lblTerminalIP.Text = terminalIP;
string[] timeData = _mainForm.GetProgramTimesByIp(_targetIP);
txtBoxDisplay.Text = string.IsNullOrEmpty(timeData[0]) ? "5" : timeData[0];
if (!string.IsNullOrEmpty(timeData[1]) && timeData[1].Contains(":"))
{
string[] onTime = timeData[1].Split(':');
txtBoxOnYY.Text = onTime[0];
txtBoxOnMM.Text = onTime[1];
txtBoxOnSS.Text = onTime[2];
}
if (!string.IsNullOrEmpty(timeData[2]) && timeData[2].Contains(":"))
{
string[] offTime = timeData[2].Split(':');
txtBoxOffYY.Text = offTime[0];
txtBoxOffMM.Text = offTime[1];
txtBoxOffSS.Text = offTime[2];
}
txtBoxOnYY.TextChanged += ValidateInputs;
txtBoxOnMM.TextChanged += ValidateInputs;
txtBoxOnSS.TextChanged += ValidateInputs;
txtBoxOffYY.TextChanged += ValidateInputs;
txtBoxOffMM.TextChanged += ValidateInputs;
txtBoxOffSS.TextChanged += ValidateInputs;
txtBoxOnYY.PlaceholderText = "YY";
txtBoxOnMM.PlaceholderText = "MM";
txtBoxOnSS.PlaceholderText = "SS";
txtBoxOffYY.PlaceholderText = "YY";
txtBoxOffMM.PlaceholderText = "MM";
txtBoxOffSS.PlaceholderText = "SS";
LoadAndParseFile();
}
// ⭐️ 오른쪽 그리드뷰 디자인 시안을 반영한 메서드
// ⭐️ 오른쪽 그리드뷰 디자인 시안을 반영한 메서드
private void InitDataGridViewStyles()
{
grdDataList.AllowUserToResizeRows = false;
grdDataList.AllowUserToResizeColumns = false;
grdDataList.RowHeadersVisible = false; // 왼쪽 화살표 열 숨김
grdDataList.AllowUserToAddRows = false; // 빈 칸 추가 방지
grdDataList.ReadOnly = true; // 읽기 전용
grdDataList.SelectionMode = DataGridViewSelectionMode.FullRowSelect; // 행 선택
grdDataList.MultiSelect = false;
// 커스텀 헤더 스타일을 적용하기 위해 반드시 false 설정
grdDataList.EnableHeadersVisualStyles = false;
// 그리드 전체 배경 및 기본 테두리 제거 (시안처럼 하얗고 투명하게)
grdDataList.BackgroundColor = Color.White;
grdDataList.BorderStyle = BorderStyle.None;
// 셀 구분선 설정 (옅은 회색 가로선만 남김)
grdDataList.CellBorderStyle = DataGridViewCellBorderStyle.SingleHorizontal;
grdDataList.GridColor = Color.FromArgb(240, 242, 245);
// [상단 헤더 스타일 수정]
DataGridViewCellStyle headerStyle = new DataGridViewCellStyle();
headerStyle.BackColor = Color.FromArgb(44, 62, 80);
headerStyle.ForeColor = Color.White;
headerStyle.Font = new Font("맑은 고딕", 9.5F, FontStyle.Bold);
headerStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
// 행을 선택하더라도 헤더의 선택 배경색/글자색이 기본 배경색과 똑같이 유지되도록 고정
headerStyle.SelectionBackColor = Color.FromArgb(44, 62, 80);
headerStyle.SelectionForeColor = Color.White;
grdDataList.ColumnHeadersDefaultCellStyle = headerStyle;
grdDataList.ColumnHeadersHeight = 38; // 헤더 높이 여유롭게 조정
grdDataList.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
// 행 선택 시 헤더 스타일 상속으로 인한 테두리 및 색상 왜곡 방지
grdDataList.EnableHeadersVisualStyles = false;
// [일반 데이터 셀 스타일 수정]
DataGridViewCellStyle cellStyle = new DataGridViewCellStyle();
cellStyle.BackColor = Color.White;
cellStyle.ForeColor = Color.FromArgb(50, 50, 50); // 부드러운 차콜 블랙
cellStyle.Font = new Font("맑은 고딕", 9F, FontStyle.Regular);
cellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
// 행 선택(클릭) 시 파란색 대신 부드러운 회청색으로 채우기
cellStyle.SelectionBackColor = Color.FromArgb(242, 246, 252);
cellStyle.SelectionForeColor = Color.FromArgb(50, 50, 50);
grdDataList.DefaultCellStyle = cellStyle;
// 시안처럼 행 간격(높이)을 시원하게 벌려 가시성을 높임
grdDataList.RowTemplate.Height = 38;
grdDataList.ClearSelection();
}
private void ConfigureModernStyles()
{
// 수정 버튼 스타일 설정 (테두리 삭제)
btnUpdate.FlatStyle = FlatStyle.Flat;
btnUpdate.FlatAppearance.BorderSize = 0;
// 취소 버튼 스타일 설정 (테두리 삭제 및 부드러운 회색)
btnCancel.FlatStyle = FlatStyle.Flat;
btnCancel.FlatAppearance.BorderSize = 0;
btnCancel.BackColor = Color.FromArgb(230, 235, 240);
btnCancel.ForeColor = Color.FromArgb(80, 80, 80);
// 둥근 처리를 위한 Paint 이벤트 연결
if (lblBox != null) lblBox.Paint += lblBox_Paint;
btnUpdate.Paint += Button_Paint;
btnCancel.Paint += Button_Paint;
}
// 둥근 모서리 경로를 만들어주는 공통 메서드
private GraphicsPath GetRoundPath(Rectangle bounds, int radius)
{
GraphicsPath path = new GraphicsPath();
int diameter = radius * 2;
path.AddArc(bounds.X, bounds.Y, diameter, diameter, 180, 90);
path.AddArc(bounds.Right - diameter, bounds.Y, diameter, diameter, 270, 90);
path.AddArc(bounds.Right - diameter, bounds.Bottom - diameter, diameter, diameter, 0, 90);
path.AddArc(bounds.X, bounds.Bottom - diameter, diameter, diameter, 90, 90);
path.CloseAllFigures();
return path;
}
// 흰색 배경 박스 둥글게 자르기
private void lblBox_Paint(object? sender, PaintEventArgs e)
{
if (sender is Control control)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
using (GraphicsPath path = GetRoundPath(new Rectangle(0, 0, control.Width, control.Height), CornerRadiusValue))
{
control.Region = new Region(path);
}
}
}
// 버튼들 둥글게 자르기
private void Button_Paint(object? sender, PaintEventArgs e)
{
if (sender is Button button)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
using (GraphicsPath path = GetRoundPath(new Rectangle(0, 0, button.Width, button.Height), 10))
{
button.Region = new Region(path);
}
}
}
private void ValidateInputs(object? sender, EventArgs e)
{
// 프로그램 시간 조건 체크
bool isOnYYEmpty = string.IsNullOrWhiteSpace(txtBoxOnYY.Text);
bool isOnMMEmpty = string.IsNullOrWhiteSpace(txtBoxOnMM.Text);
bool isOnSSEmpty = string.IsNullOrWhiteSpace(txtBoxOnSS.Text);
bool isOffYYEmpty = string.IsNullOrWhiteSpace(txtBoxOffYY.Text);
bool isOffMMEmpty = string.IsNullOrWhiteSpace(@txtBoxOffMM.Text);
bool isOffMMEmpty = string.IsNullOrWhiteSpace(txtBoxOffMM.Text);
bool isOffSSEmpty = string.IsNullOrWhiteSpace(txtBoxOffSS.Text);
// 둘 다 비어있거나(AND), 둘 다 비어있지 않거나(AND)
bool isTimeValid = (isOnYYEmpty && isOnMMEmpty && isOffYYEmpty && isOffMMEmpty) || (!isOnYYEmpty && !isOnMMEmpty && !isOffYYEmpty && !isOffMMEmpty);
bool isTimeValid = (isOnYYEmpty && isOnMMEmpty && isOnSSEmpty && isOffYYEmpty && isOffMMEmpty && isOffSSEmpty) ||
(!isOnYYEmpty && !isOnMMEmpty && !isOnSSEmpty && !isOffYYEmpty && !isOffMMEmpty && !isOffSSEmpty);
// 저장 버튼 활성화
btnUpdate.Enabled = isTimeValid;
if (isTimeValid)
{
btnUpdate.BackColor = Color.FromArgb(52, 152, 219); // 활성화 스카이블루
btnUpdate.ForeColor = Color.White;
}
else
{
btnUpdate.BackColor = Color.FromArgb(180, 210, 235); // 비활성화 흐린 블루
btnUpdate.ForeColor = Color.White;
}
}
private void btnCancel_MouseClick(object sender, MouseEventArgs e)
@@ -50,8 +226,53 @@ namespace ControlServer
private void btnUpdate_MouseClick(object sender, MouseEventArgs e)
{
// 수정
// 수정 시 DB 저장
string displayTime = txtBoxDisplay.Text;
string onTime = txtBoxOnYY.Text + ":" + txtBoxOnMM.Text + ":" + txtBoxOnSS.Text;
string offTime = txtBoxOffYY.Text + ":" + txtBoxOffMM.Text + ":" + txtBoxOffSS.Text;
_mainForm.SaveProgramTimesToGrid(_targetIP, displayTime, onTime, offTime);
string protocol = $"SET_TIME|{displayTime}\n";
_mainForm.SendDataToSingleAgent(_targetIP, protocol);
MessageBox.Show("수정되었습니다.", "알림", MessageBoxButtons.OK, MessageBoxIcon.Information);
this.Close();
}
private void LoadAndParseFile()
{
if (!File.Exists(_filePath)) return;
string fileContent = File.ReadAllText(_filePath);
if (string.IsNullOrWhiteSpace(fileContent)) return;
ParseAndBindServerData(fileContent);
}
private void ParseAndBindServerData(string rawData)
{
try
{
var doc = System.Xml.Linq.XDocument.Parse(rawData);
grdDataList.Rows.Clear();
foreach (var item in doc.Descendants("AuctionTable"))
{
grdDataList.Rows.Add(
item.Element("aucDate")?.Value,
item.Element("itemName")?.Value,
item.Element("origin")?.Value,
item.Element("totalQty")?.Value,
item.Element("fixPriceQty")?.Value,
item.Element("totalAmt")?.Value,
item.Element("fixPriceAmt")?.Value
);
}
}
catch (Exception ex)
{
MessageBox.Show("XML 파싱 에러: " + ex.Message, "오류", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
}