추가
This commit is contained in:
190
frontend/report/weekly/[id].vue
Normal file
190
frontend/report/weekly/[id].vue
Normal file
@@ -0,0 +1,190 @@
|
||||
<template>
|
||||
<div>
|
||||
<AppHeader />
|
||||
|
||||
<div class="container-fluid py-4">
|
||||
<div class="mb-4">
|
||||
<NuxtLink to="/report/weekly" class="text-decoration-none">
|
||||
<i class="bi bi-arrow-left me-1"></i> 목록으로
|
||||
</NuxtLink>
|
||||
</div>
|
||||
|
||||
<div class="card" v-if="report">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="mb-0">
|
||||
<i class="bi bi-journal-text me-2"></i>
|
||||
{{ report.projectName }} - {{ report.reportYear }}-W{{ String(report.reportWeek).padStart(2, '0') }}
|
||||
</h5>
|
||||
<span :class="getStatusBadgeClass(report.reportStatus)">
|
||||
{{ getStatusText(report.reportStatus) }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<!-- 기본 정보 -->
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label text-muted">작성자</label>
|
||||
<p class="mb-0">{{ report.authorName }}</p>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label text-muted">기간</label>
|
||||
<p class="mb-0">{{ formatDate(report.weekStartDate) }} ~ {{ formatDate(report.weekEndDate) }}</p>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label text-muted">투입시간</label>
|
||||
<p class="mb-0">{{ report.workHours ? report.workHours + '시간' : '-' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 금주 실적 -->
|
||||
<div class="mb-4">
|
||||
<label class="form-label text-muted">
|
||||
<i class="bi bi-check-circle me-1"></i>금주 실적
|
||||
</label>
|
||||
<div class="p-3 bg-light rounded">
|
||||
<pre class="mb-0" style="white-space: pre-wrap;">{{ report.workDescription || '-' }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 차주 계획 -->
|
||||
<div class="mb-4">
|
||||
<label class="form-label text-muted">
|
||||
<i class="bi bi-calendar-event me-1"></i>차주 계획
|
||||
</label>
|
||||
<div class="p-3 bg-light rounded">
|
||||
<pre class="mb-0" style="white-space: pre-wrap;">{{ report.planDescription || '-' }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 이슈사항 -->
|
||||
<div class="mb-4" v-if="report.issueDescription">
|
||||
<label class="form-label text-muted">
|
||||
<i class="bi bi-exclamation-triangle me-1"></i>이슈/리스크
|
||||
</label>
|
||||
<div class="p-3 bg-warning bg-opacity-10 rounded">
|
||||
<pre class="mb-0" style="white-space: pre-wrap;">{{ report.issueDescription }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 비고 -->
|
||||
<div class="mb-4" v-if="report.remarkDescription">
|
||||
<label class="form-label text-muted">
|
||||
<i class="bi bi-chat-text me-1"></i>비고
|
||||
</label>
|
||||
<div class="p-3 bg-light rounded">
|
||||
<pre class="mb-0" style="white-space: pre-wrap;">{{ report.remarkDescription }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 작업 버튼 -->
|
||||
<div class="d-flex gap-2 mt-4 pt-3 border-top">
|
||||
<NuxtLink
|
||||
v-if="report.reportStatus === 'DRAFT'"
|
||||
:to="`/report/weekly/write?id=${report.reportId}`"
|
||||
class="btn btn-primary"
|
||||
>
|
||||
<i class="bi bi-pencil me-1"></i> 수정
|
||||
</NuxtLink>
|
||||
<button
|
||||
v-if="report.reportStatus === 'DRAFT'"
|
||||
class="btn btn-success"
|
||||
@click="submitReport"
|
||||
>
|
||||
<i class="bi bi-send me-1"></i> 제출
|
||||
</button>
|
||||
<button
|
||||
v-if="report.reportStatus === 'DRAFT'"
|
||||
class="btn btn-outline-danger"
|
||||
@click="deleteReport"
|
||||
>
|
||||
<i class="bi bi-trash me-1"></i> 삭제
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="text-center py-5" v-else-if="isLoading">
|
||||
<div class="spinner-border text-primary"></div>
|
||||
<p class="mt-2 text-muted">로딩중...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const { fetchCurrentUser } = useAuth()
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
|
||||
const report = ref<any>(null)
|
||||
const isLoading = ref(true)
|
||||
|
||||
onMounted(async () => {
|
||||
const user = await fetchCurrentUser()
|
||||
if (!user) {
|
||||
router.push('/login')
|
||||
return
|
||||
}
|
||||
|
||||
await loadReport()
|
||||
})
|
||||
|
||||
async function loadReport() {
|
||||
isLoading.value = true
|
||||
try {
|
||||
const res = await $fetch<{ report: any }>(`/api/report/weekly/${route.params.id}/detail`)
|
||||
report.value = res.report
|
||||
} catch (e: any) {
|
||||
alert('보고서를 불러오는데 실패했습니다.')
|
||||
router.push('/report/weekly')
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function submitReport() {
|
||||
if (!confirm('보고서를 제출하시겠습니까?\n제출 후에는 수정이 제한됩니다.')) return
|
||||
|
||||
try {
|
||||
await $fetch(`/api/report/weekly/${route.params.id}/submit`, { method: 'POST' })
|
||||
await loadReport()
|
||||
} catch (e: any) {
|
||||
alert(e.data?.message || e.message || '제출에 실패했습니다.')
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteReport() {
|
||||
if (!confirm('보고서를 삭제하시겠습니까?')) return
|
||||
|
||||
try {
|
||||
await $fetch(`/api/report/weekly/${route.params.id}/detail`, { method: 'DELETE' })
|
||||
router.push('/report/weekly')
|
||||
} catch (e: any) {
|
||||
alert(e.data?.message || e.message || '삭제에 실패했습니다.')
|
||||
}
|
||||
}
|
||||
|
||||
function getStatusBadgeClass(status: string) {
|
||||
const classes: Record<string, string> = {
|
||||
'DRAFT': 'badge bg-secondary',
|
||||
'SUBMITTED': 'badge bg-success',
|
||||
'AGGREGATED': 'badge bg-info'
|
||||
}
|
||||
return classes[status] || 'badge bg-secondary'
|
||||
}
|
||||
|
||||
function getStatusText(status: string) {
|
||||
const texts: Record<string, string> = {
|
||||
'DRAFT': '작성중',
|
||||
'SUBMITTED': '제출완료',
|
||||
'AGGREGATED': '취합완료'
|
||||
}
|
||||
return texts[status] || status
|
||||
}
|
||||
|
||||
function formatDate(dateStr: string) {
|
||||
const d = new Date(dateStr)
|
||||
return `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}`
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user