초기 커밋: SheetMe 서식생성기 (P0~P5 완료 상태)

레거시 서식생성기(VB.NET WinForms) 대체용 C#/.NET 10 WPF 디자이너.
기준선: 실DB 활성 디자인 1,271건 왕복 의미론 diff 0 / 예외 0, 단위 테스트 49/49.

이 커밋에 함께 포함된 자격증명 분리:
- appsettings.json 을 __HOST__/__PASSWORD__ 플레이스홀더로 전환
- 실접속 정보는 appsettings.Development.json 으로 분리(.gitignore 제외,
  csproj Debug 조건부 복사라 Release 산출물에 실리지 않음)
- ConfigLoader 를 환경변수 > Development > appsettings 순 레이어링으로 변경,
  미치환 플레이스홀더는 '미설정'으로 간주

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Msystech
2026-08-11 17:20:22 +09:00
co-authored by Claude Fable 5
commit 16c07f48dc
102 changed files with 14210 additions and 0 deletions
@@ -0,0 +1,82 @@
using System.Windows;
using System.Windows.Controls;
namespace SheetMe.Designer.Views;
/// <summary>
/// 데이터소스(MDataTable) 쿼리 전용 편집기 — 큰 SQL 편집 영역 + 치환 변수 삽입.
/// 치환 규칙 원본: [014]EMRLoader bzDesignSheetLoader.ConvertQuery — &lt;&lt;PatientInfo/SheetInfo/WorkInfo.속성&gt;&gt; 리플렉션 치환.
/// 변수 목록 출처: [021]SheetLoadOperatingInfo 의 bzPatientInfo/bzSheetInfo/bzWorkInfo 공개 속성(스칼라만 큐레이션, 2026-07-16).
/// </summary>
public partial class QueryEditorWindow : Window
{
#region Member Fields
/// <summary>치환 변수 목록 — 작성 시점 실제 값으로 치환됨</summary>
private static readonly string[] Variables =
{
"<<PatientInfo.ChtNum>>",
"<<PatientInfo.ComNum>>",
"<<PatientInfo.PatTyp>>",
"<<PatientInfo.OdrNum>>",
"<<PatientInfo.OdrSeq>>",
"<<SheetInfo.ShtCod>>",
"<<SheetInfo.ShtNam>>",
"<<SheetInfo.EmrKey>>",
"<<SheetInfo.EmrGbn>>",
"<<SheetInfo.AdpDtm>>",
"<<SheetInfo.PatTyp>>",
"<<SheetInfo.OdrNum>>",
"<<SheetInfo.OdrSeq>>",
"<<SheetInfo.TemKey>>",
"<<WorkInfo.WrkUid>>",
"<<WorkInfo.WrkNam>>",
"<<WorkInfo.WrkDte>>",
"<<WorkInfo.WrkDtm>>",
"<<WorkInfo.AdpDep>>",
"<<WorkInfo.AdpDtm>>",
};
#endregion
#region Properties
/// <summary>편집 결과 SQL — 확인 시 채워짐</summary>
public string QueryText { get; private set; } = string.Empty;
#endregion
#region Constructors
public QueryEditorWindow(string ownerLabel, string initialQuery)
{
InitializeComponent();
Title = $"쿼리 편집 — {ownerLabel}";
SqlBox.Text = initialQuery;
VariableList.ItemsSource = Variables;
Loaded += (_, _) =>
{
SqlBox.Focus();
SqlBox.CaretIndex = SqlBox.Text.Length;
};
}
#endregion
#region Methods
private void OnSqlChanged(object sender, TextChangedEventArgs e)
=> LengthText.Text = $"{SqlBox.Text.Length:N0}자";
private void OnInsertVariable(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (VariableList.SelectedItem is not string variable)
{
return;
}
var caret = SqlBox.CaretIndex;
SqlBox.Text = SqlBox.Text.Insert(caret, variable);
SqlBox.CaretIndex = caret + variable.Length;
SqlBox.Focus();
}
private void OnConfirm(object sender, RoutedEventArgs e)
{
QueryText = SqlBox.Text;
DialogResult = true;
}
#endregion
}