133 lines
4.8 KiB
C#
133 lines
4.8 KiB
C#
using System.IO;
|
|
using System.Text;
|
|
using System.Windows;
|
|
using AxCopilot.SDK;
|
|
using AxCopilot.Services;
|
|
using AxCopilot.Themes;
|
|
|
|
namespace AxCopilot.Handlers;
|
|
|
|
/// <summary>
|
|
/// 업무 일지 자동 생성 핸들러. "journal" 프리픽스로 사용합니다.
|
|
/// UsageStatisticsService 데이터를 기반으로 오늘/지정일의 업무 요약을 자동 생성합니다.
|
|
/// 예: journal → 오늘의 업무 일지 생성
|
|
/// journal 2026-03-25 → 해당 날짜 일지
|
|
/// Enter → 마크다운 형식으로 클립보드에 복사.
|
|
/// </summary>
|
|
public class JournalHandler : IActionHandler
|
|
{
|
|
public string? Prefix => "journal";
|
|
|
|
public PluginMetadata Metadata => new(
|
|
"Journal",
|
|
"업무 일지 자동 생성 — journal",
|
|
"1.0",
|
|
"AX");
|
|
|
|
public Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
|
|
{
|
|
var q = query.Trim();
|
|
DateTime targetDate;
|
|
|
|
if (string.IsNullOrWhiteSpace(q))
|
|
targetDate = DateTime.Today;
|
|
else if (DateTime.TryParse(q, out var parsed))
|
|
targetDate = parsed.Date;
|
|
else
|
|
{
|
|
return Task.FromResult<IEnumerable<LauncherItem>>(
|
|
[
|
|
new LauncherItem("날짜 형식 오류", "예: journal 2026-03-25 또는 journal (오늘)",
|
|
null, null, Symbol: Symbols.Warning)
|
|
]);
|
|
}
|
|
|
|
// 날짜 범위 계산 (오늘~targetDate 간 차이)
|
|
var daysAgo = (DateTime.Today - targetDate).Days;
|
|
var allStats = UsageStatisticsService.GetStats(Math.Max(daysAgo + 1, 1));
|
|
var stats = allStats.FirstOrDefault(s => s.Date == targetDate.ToString("yyyy-MM-dd"));
|
|
var items = new List<LauncherItem>();
|
|
|
|
if (stats == null)
|
|
{
|
|
items.Add(new LauncherItem(
|
|
$"{targetDate:yyyy-MM-dd} — 기록 없음",
|
|
"해당 날짜의 사용 기록이 없습니다",
|
|
null, null, Symbol: Symbols.Info));
|
|
return Task.FromResult<IEnumerable<LauncherItem>>(items);
|
|
}
|
|
|
|
// 요약 생성
|
|
var activeHours = stats.ActiveSeconds / 3600.0;
|
|
var sb = new StringBuilder();
|
|
sb.AppendLine($"## 업무 일지 — {targetDate:yyyy-MM-dd} ({targetDate:dddd})");
|
|
sb.AppendLine();
|
|
sb.AppendLine($"- **PC 활성 시간**: {activeHours:F1}시간");
|
|
sb.AppendLine($"- **런처 호출**: {stats.LauncherOpens}회");
|
|
|
|
if (stats.CommandUsage.Count > 0)
|
|
{
|
|
sb.AppendLine();
|
|
sb.AppendLine("### 사용한 명령어");
|
|
foreach (var kv in stats.CommandUsage.OrderByDescending(x => x.Value).Take(10))
|
|
sb.AppendLine($"- `{kv.Key}` — {kv.Value}회");
|
|
}
|
|
|
|
sb.AppendLine();
|
|
sb.AppendLine("---");
|
|
sb.AppendLine($"*AX Copilot 자동 생성 · {DateTime.Now:HH:mm}*");
|
|
|
|
var journal = sb.ToString();
|
|
|
|
// 요약 카드
|
|
var topCmds = stats.CommandUsage.OrderByDescending(x => x.Value).Take(3)
|
|
.Select(x => x.Key);
|
|
var cmdPreview = stats.CommandUsage.Count > 0
|
|
? $"주요 명령: {string.Join(", ", topCmds)}"
|
|
: "명령어 사용 기록 없음";
|
|
|
|
items.Add(new LauncherItem(
|
|
$"{targetDate:yyyy-MM-dd} 업무 일지 — 클립보드로 복사",
|
|
$"활성 {activeHours:F1}h · 런처 {stats.LauncherOpens}회 · {cmdPreview}",
|
|
null, journal,
|
|
Symbol: Symbols.Note));
|
|
|
|
items.Add(new LauncherItem(
|
|
$"PC 활성 시간: {activeHours:F1}시간",
|
|
"잠금 해제 시간 기준 누적",
|
|
null, $"PC 활성 시간: {activeHours:F1}시간",
|
|
Symbol: Symbols.Clock));
|
|
|
|
items.Add(new LauncherItem(
|
|
$"런처 호출: {stats.LauncherOpens}회",
|
|
"Alt+Space 또는 트레이 클릭",
|
|
null, $"런처 호출: {stats.LauncherOpens}회",
|
|
Symbol: Symbols.Search));
|
|
|
|
if (stats.CommandUsage.Count > 0)
|
|
{
|
|
foreach (var kv in stats.CommandUsage.OrderByDescending(x => x.Value).Take(5))
|
|
{
|
|
items.Add(new LauncherItem(
|
|
$"{kv.Key} — {kv.Value}회",
|
|
"Enter로 복사",
|
|
null, $"{kv.Key}: {kv.Value}회",
|
|
Symbol: Symbols.Terminal));
|
|
}
|
|
}
|
|
|
|
return Task.FromResult<IEnumerable<LauncherItem>>(items);
|
|
}
|
|
|
|
public Task ExecuteAsync(LauncherItem item, CancellationToken ct)
|
|
{
|
|
if (item.Data is string text && !string.IsNullOrWhiteSpace(text))
|
|
{
|
|
try { Application.Current?.Dispatcher.Invoke(() => Clipboard.SetText(text)); }
|
|
catch { }
|
|
NotificationService.Notify("업무 일지", "클립보드에 복사되었습니다");
|
|
}
|
|
return Task.CompletedTask;
|
|
}
|
|
}
|