256 lines
10 KiB
C#
256 lines
10 KiB
C#
using Microsoft.UI;
|
|
using Microsoft.UI.Xaml.Controls;
|
|
using Microsoft.UI.Xaml;
|
|
using Microsoft.UI.Xaml.Media;
|
|
using System.Collections.ObjectModel;
|
|
using TornadoAce_CJOnStyle.Services;
|
|
using Windows.UI;
|
|
|
|
namespace TornadoAce_CJOnStyle.ViewModels
|
|
{
|
|
public partial class MainViewModel : BaseViewModel
|
|
{
|
|
private readonly AutomationWorkspace workspace;
|
|
|
|
public MainViewModel()
|
|
{
|
|
Title = "CG 제작 자동화";
|
|
workspace = AutomationWorkspace.CreateDemo();
|
|
|
|
BuildPhase = "INITIAL BUILD";
|
|
OperatorMessage = "큐시트 플랫폼, Tornado Scene 템플릿, 자동 검수 결과를 한 화면에서 확인하는 운영 콘솔 초안입니다.";
|
|
LastCueSheetSyncText = "목 데이터 기준 13:25";
|
|
ActiveTemplateName = workspace.ActiveTemplate.TemplateName;
|
|
InspectionSummary = "1차 diff 실패 2건 / LLM 검토 대기 1건";
|
|
SceneSnapshotLabel = $"{workspace.ActiveScene.SceneName} / visible text objects";
|
|
SceneSnapshotText = workspace.ActiveScene.ToPreviewJson();
|
|
LoginOperatorName = "producer";
|
|
LaunchMessage = "TornadoAce";
|
|
LlmPolicyText = "사내 LLM 우선, 외부 서비스는 정책 승인 후";
|
|
LlmPolicyDetail = "1차 Text Diffing 실패 건만 2차 LLM 판정으로 이동하고, 가격·구성·방송시간 변경은 높은 중요도로 표시합니다.";
|
|
|
|
LoadStatusCards();
|
|
LoadPipelineSteps();
|
|
LoadFieldMappings();
|
|
LoadEndpoints();
|
|
LoadInspectionQueue();
|
|
}
|
|
|
|
private string buildPhase = string.Empty;
|
|
private string operatorMessage = string.Empty;
|
|
private string lastCueSheetSyncText = string.Empty;
|
|
private string activeTemplateName = string.Empty;
|
|
private string inspectionSummary = string.Empty;
|
|
private string sceneSnapshotLabel = string.Empty;
|
|
private string sceneSnapshotText = string.Empty;
|
|
private string llmPolicyText = string.Empty;
|
|
private string llmPolicyDetail = string.Empty;
|
|
private string loginOperatorName = string.Empty;
|
|
private string launchMessage = string.Empty;
|
|
private Visibility loginScreenVisibility = Visibility.Visible;
|
|
private Visibility launchScreenVisibility = Visibility.Collapsed;
|
|
private Visibility mainShellVisibility = Visibility.Collapsed;
|
|
|
|
public string BuildPhase
|
|
{
|
|
get => buildPhase;
|
|
set => SetProperty(ref buildPhase, value);
|
|
}
|
|
|
|
public string OperatorMessage
|
|
{
|
|
get => operatorMessage;
|
|
set => SetProperty(ref operatorMessage, value);
|
|
}
|
|
|
|
public string LastCueSheetSyncText
|
|
{
|
|
get => lastCueSheetSyncText;
|
|
set => SetProperty(ref lastCueSheetSyncText, value);
|
|
}
|
|
|
|
public string ActiveTemplateName
|
|
{
|
|
get => activeTemplateName;
|
|
set => SetProperty(ref activeTemplateName, value);
|
|
}
|
|
|
|
public string InspectionSummary
|
|
{
|
|
get => inspectionSummary;
|
|
set => SetProperty(ref inspectionSummary, value);
|
|
}
|
|
|
|
public string SceneSnapshotLabel
|
|
{
|
|
get => sceneSnapshotLabel;
|
|
set => SetProperty(ref sceneSnapshotLabel, value);
|
|
}
|
|
|
|
public string SceneSnapshotText
|
|
{
|
|
get => sceneSnapshotText;
|
|
set => SetProperty(ref sceneSnapshotText, value);
|
|
}
|
|
|
|
public string LlmPolicyText
|
|
{
|
|
get => llmPolicyText;
|
|
set => SetProperty(ref llmPolicyText, value);
|
|
}
|
|
|
|
public string LlmPolicyDetail
|
|
{
|
|
get => llmPolicyDetail;
|
|
set => SetProperty(ref llmPolicyDetail, value);
|
|
}
|
|
|
|
public ObservableCollection<StatusCardViewModel> StatusCards { get; } = [];
|
|
|
|
public ObservableCollection<PipelineStepViewModel> PipelineSteps { get; } = [];
|
|
|
|
public ObservableCollection<FieldMappingViewModel> FieldMappings { get; } = [];
|
|
|
|
public ObservableCollection<IntegrationEndpointViewModel> Endpoints { get; } = [];
|
|
|
|
public ObservableCollection<InspectionQueueItemViewModel> InspectionQueue { get; } = [];
|
|
|
|
public string LoginOperatorName
|
|
{
|
|
get => loginOperatorName;
|
|
set => SetProperty(ref loginOperatorName, value);
|
|
}
|
|
|
|
public string LaunchMessage
|
|
{
|
|
get => launchMessage;
|
|
set => SetProperty(ref launchMessage, value);
|
|
}
|
|
|
|
public Visibility LoginScreenVisibility
|
|
{
|
|
get => loginScreenVisibility;
|
|
set => SetProperty(ref loginScreenVisibility, value);
|
|
}
|
|
|
|
public Visibility LaunchScreenVisibility
|
|
{
|
|
get => launchScreenVisibility;
|
|
set => SetProperty(ref launchScreenVisibility, value);
|
|
}
|
|
|
|
public Visibility MainShellVisibility
|
|
{
|
|
get => mainShellVisibility;
|
|
set => SetProperty(ref mainShellVisibility, value);
|
|
}
|
|
|
|
public void BeginLogin(string operatorName, string accessCode)
|
|
{
|
|
LoginOperatorName = string.IsNullOrWhiteSpace(operatorName) ? "producer" : operatorName.Trim();
|
|
LaunchMessage = "TornadoAce";
|
|
LoginScreenVisibility = Visibility.Collapsed;
|
|
LaunchScreenVisibility = Visibility.Visible;
|
|
}
|
|
|
|
public void CompleteLogin()
|
|
{
|
|
LaunchScreenVisibility = Visibility.Collapsed;
|
|
MainShellVisibility = Visibility.Visible;
|
|
OperatorMessage = $"{LoginOperatorName} 제작자가 접속했습니다. 큐시트와 Scene 매핑 상태를 확인하세요.";
|
|
}
|
|
|
|
[RelayCommand]
|
|
private void RefreshCueSheet()
|
|
{
|
|
LastCueSheetSyncText = $"목 데이터 동기화 {DateTime.Now:HH:mm:ss}";
|
|
OperatorMessage = "큐시트 목 데이터를 다시 읽었습니다. 실제 API 연결 전까지 이 버튼은 화면 흐름 확인용으로 동작합니다.";
|
|
StatusCards[0].Metric = "12";
|
|
StatusCards[0].Detail = "동기화 완료";
|
|
}
|
|
|
|
[RelayCommand]
|
|
private void GenerateScene()
|
|
{
|
|
OperatorMessage = "선택된 큐시트 레코드를 Tornado Scene 템플릿에 매핑하는 흐름을 확인했습니다.";
|
|
StatusCards[1].Metric = "7";
|
|
StatusCards[1].Detail = "생성 후보";
|
|
}
|
|
|
|
[RelayCommand]
|
|
private void RunInspection()
|
|
{
|
|
OperatorMessage = "Scene 데이터와 큐시트 데이터를 비교하는 1차 검수 흐름을 확인했습니다.";
|
|
InspectionSummary = "1차 diff 실패 2건 / LLM 검토 대기 1건 / 통과 5건";
|
|
StatusCards[2].Metric = "99.2%";
|
|
StatusCards[2].Detail = "평균 일치율";
|
|
}
|
|
|
|
private void LoadStatusCards()
|
|
{
|
|
StatusCards.Add(new StatusCardViewModel("큐시트 API", "12", "수신 대기", Symbol.Sync, Brush(0xFF45D6D1)));
|
|
StatusCards.Add(new StatusCardViewModel("Scene 매핑", "5", "템플릿 정의", Symbol.Map, Brush(0xFFB48CFF)));
|
|
StatusCards.Add(new StatusCardViewModel("자동 검수", "98.7%", "목표 99%+", Symbol.Accept, Brush(0xFFFFB547)));
|
|
StatusCards.Add(new StatusCardViewModel("Tornado", "Mock", "SDK 어댑터 자리", Symbol.Repair, Brush(0xFF37D67A)));
|
|
}
|
|
|
|
private void LoadPipelineSteps()
|
|
{
|
|
PipelineSteps.Add(new PipelineStepViewModel("01", "큐시트 데이터 수신", "AI ON Studio / 자막 큐시트 API", "설계", 35, Brush(0xFF45D6D1)));
|
|
PipelineSteps.Add(new PipelineStepViewModel("02", "Data Field Mapping", "큐시트 필드 -> Tornado Scene 객체", "초안", 45, Brush(0xFFB48CFF)));
|
|
PipelineSteps.Add(new PipelineStepViewModel("03", "Scene 생성/갱신", "Tornado2 우선, Tornado3 어댑터 준비", "대기", 25, Brush(0xFF37D67A)));
|
|
PipelineSteps.Add(new PipelineStepViewModel("04", "Scene Data API 추출", "Text/Image visible object snapshot", "초안", 30, Brush(0xFFFFB547)));
|
|
PipelineSteps.Add(new PipelineStepViewModel("05", "자동 검수 피드백", "Text Diffing + LLM 중요도 판정", "초안", 40, Brush(0xFFFF5B61)));
|
|
}
|
|
|
|
private void LoadFieldMappings()
|
|
{
|
|
foreach (var mapping in workspace.ActiveTemplate.Mappings)
|
|
{
|
|
FieldMappings.Add(new FieldMappingViewModel(mapping.CueSheetField, mapping.SceneObjectName, mapping.Rule, mapping.Attribute));
|
|
}
|
|
}
|
|
|
|
private void LoadEndpoints()
|
|
{
|
|
Endpoints.Add(new IntegrationEndpointViewModel("큐시트 플랫폼", "GET /api/cuesheets/{broadcastDate}", "AI ON Studio", "Mock", Brush(0xFF45D6D1)));
|
|
Endpoints.Add(new IntegrationEndpointViewModel("ERP 편성", "GET /api/schedules/{programCode}", "CJ OnStyle ERP", "대기", Brush(0xFFFFB547)));
|
|
Endpoints.Add(new IntegrationEndpointViewModel("Tornado Scene API", "POST /api/scenes/extract", "Tornado Adapter", "설계", Brush(0xFF37D67A)));
|
|
Endpoints.Add(new IntegrationEndpointViewModel("LLM 검수", "POST /api/inspection/llm", "Internal LLM", "정책 확인", Brush(0xFFB48CFF)));
|
|
}
|
|
|
|
private void LoadInspectionQueue()
|
|
{
|
|
foreach (var item in workspace.InspectionResults)
|
|
{
|
|
InspectionQueue.Add(new InspectionQueueItemViewModel(
|
|
item.ProgramTitle,
|
|
item.SceneName,
|
|
$"{item.MatchRate:0.0}%",
|
|
item.Severity,
|
|
item.Decision,
|
|
SeverityBrush(item.Severity)));
|
|
}
|
|
}
|
|
|
|
private static SolidColorBrush SeverityBrush(string severity)
|
|
{
|
|
return severity switch
|
|
{
|
|
"High" => Brush(0xFFFF5B61),
|
|
"Medium" => Brush(0xFFFFB547),
|
|
_ => Brush(0xFF37D67A)
|
|
};
|
|
}
|
|
|
|
private static SolidColorBrush Brush(uint argb)
|
|
{
|
|
return new SolidColorBrush(Color.FromArgb(
|
|
(byte)(argb >> 24),
|
|
(byte)(argb >> 16),
|
|
(byte)(argb >> 8),
|
|
(byte)argb));
|
|
}
|
|
}
|
|
}
|