1ㅊㅏ완료
This commit is contained in:
@@ -43,6 +43,19 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- AI 요약 -->
|
||||
<div class="card mb-4" v-if="summary.aiSummary">
|
||||
<div class="card-header bg-primary bg-opacity-10">
|
||||
<i class="bi bi-robot me-2"></i><strong>AI 요약</strong>
|
||||
<small class="text-muted ms-2" v-if="summary.aiSummaryAt">
|
||||
({{ formatDateTime(summary.aiSummaryAt) }})
|
||||
</small>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="ai-summary" v-html="renderMarkdown(summary.aiSummary)"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PM 검토 영역 -->
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
@@ -121,17 +134,29 @@
|
||||
<i class="bi bi-check-circle me-1"></i>금주 실적
|
||||
</label>
|
||||
<div class="p-2 bg-light rounded">
|
||||
<pre class="mb-0 small" style="white-space: pre-wrap;">{{ report.workDescription || '-' }}</pre>
|
||||
<div v-if="report.workTasks && report.workTasks.length > 0">
|
||||
<div v-for="(task, idx) in report.workTasks" :key="idx" class="mb-1">
|
||||
<span class="badge me-1" :class="task.isCompleted ? 'bg-success' : 'bg-warning'">
|
||||
{{ task.isCompleted ? '완료' : '진행' }}
|
||||
</span>
|
||||
<span class="small" style="white-space: pre-wrap;">{{ task.description }}</span>
|
||||
<span class="text-muted small ms-1">({{ task.hours }}h)</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="small text-muted">-</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 차주 계획 -->
|
||||
<div class="mb-3" v-if="report.planDescription">
|
||||
<div class="mb-3" v-if="report.planTasks && report.planTasks.length > 0">
|
||||
<label class="form-label text-muted small">
|
||||
<i class="bi bi-calendar-event me-1"></i>차주 계획
|
||||
</label>
|
||||
<div class="p-2 bg-light rounded">
|
||||
<pre class="mb-0 small" style="white-space: pre-wrap;">{{ report.planDescription }}</pre>
|
||||
<div v-for="(task, idx) in report.planTasks" :key="idx" class="mb-1">
|
||||
<span class="small" style="white-space: pre-wrap;">{{ task.description }}</span>
|
||||
<span class="text-muted small ms-1">({{ task.hours }}h)</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -237,4 +262,38 @@ function formatDateTime(dateStr: string) {
|
||||
const d = new Date(dateStr)
|
||||
return d.toLocaleString('ko-KR')
|
||||
}
|
||||
|
||||
// 간단한 마크다운 렌더링
|
||||
function renderMarkdown(text: string): string {
|
||||
if (!text) return ''
|
||||
return text
|
||||
// 헤더
|
||||
.replace(/^### (.+)$/gm, '<h5 class="mt-3 mb-2">$1</h5>')
|
||||
.replace(/^## (.+)$/gm, '<h4 class="mt-3 mb-2">$1</h4>')
|
||||
.replace(/^# (.+)$/gm, '<h3 class="mt-3 mb-2">$1</h3>')
|
||||
// 볼드
|
||||
.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
|
||||
// 이탤릭
|
||||
.replace(/\*(.+?)\*/g, '<em>$1</em>')
|
||||
// 리스트
|
||||
.replace(/^- (.+)$/gm, '<li>$1</li>')
|
||||
.replace(/(<li>.*<\/li>\n?)+/g, '<ul class="mb-2">$&</ul>')
|
||||
// 줄바꿈
|
||||
.replace(/\n/g, '<br>')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ai-summary {
|
||||
line-height: 1.7;
|
||||
}
|
||||
.ai-summary h3, .ai-summary h4, .ai-summary h5 {
|
||||
color: #333;
|
||||
}
|
||||
.ai-summary ul {
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
.ai-summary li {
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user