대시보드와 주간보고 기능 업데이트
This commit is contained in:
@@ -64,9 +64,11 @@
|
||||
<div
|
||||
class="upload-zone p-5 text-center border rounded"
|
||||
:class="{ 'border-primary bg-light': isDragging }"
|
||||
tabindex="0"
|
||||
@dragover.prevent="isDragging = true"
|
||||
@dragleave.prevent="isDragging = false"
|
||||
@drop.prevent="handleDrop"
|
||||
@paste="handlePaste"
|
||||
@click="($refs.fileInput as HTMLInputElement).click()"
|
||||
>
|
||||
<input
|
||||
@@ -80,7 +82,7 @@
|
||||
<i class="bi bi-cloud-arrow-up display-4 text-muted"></i>
|
||||
<p class="mt-2 mb-0 text-muted">
|
||||
이미지를 드래그하거나 클릭해서 업로드<br>
|
||||
<small>(최대 10장, PNG/JPG)</small>
|
||||
<small>또는 <strong>Ctrl+V</strong>로 붙여넣기 (최대 10장)</small>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -358,6 +360,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
const { fetchCurrentUser } = useAuth()
|
||||
const { getWeekInfo, getWeekDates, getLastWeekInfo, getActualCurrentWeekInfo, changeWeek: calcChangeWeek } = useWeekCalc()
|
||||
const router = useRouter()
|
||||
|
||||
const step = ref(1)
|
||||
@@ -400,12 +403,6 @@ onMounted(async () => {
|
||||
router.push('/login')
|
||||
return
|
||||
}
|
||||
|
||||
if (user.employeeEmail !== 'coziny@gmail.com') {
|
||||
alert('관리자만 접근할 수 있습니다.')
|
||||
router.push('/')
|
||||
return
|
||||
}
|
||||
})
|
||||
|
||||
function getHeaderClass(report: any) {
|
||||
@@ -449,14 +446,36 @@ function handleDrop(e: DragEvent) {
|
||||
if (files) processFiles(files)
|
||||
}
|
||||
|
||||
function handlePaste(e: ClipboardEvent) {
|
||||
const items = e.clipboardData?.items
|
||||
if (!items) return
|
||||
|
||||
const imageFiles: File[] = []
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
if (items[i].type.startsWith('image/')) {
|
||||
const file = items[i].getAsFile()
|
||||
if (file) imageFiles.push(file)
|
||||
}
|
||||
}
|
||||
|
||||
if (imageFiles.length > 0) {
|
||||
e.preventDefault()
|
||||
processImageFiles(imageFiles)
|
||||
}
|
||||
}
|
||||
|
||||
function handleFileSelect(e: Event) {
|
||||
const input = e.target as HTMLInputElement
|
||||
if (input.files) processFiles(input.files)
|
||||
}
|
||||
|
||||
function processFiles(files: FileList) {
|
||||
processImageFiles(Array.from(files))
|
||||
}
|
||||
|
||||
function processImageFiles(files: File[]) {
|
||||
const maxFiles = 10 - uploadedImages.value.length
|
||||
const toProcess = Array.from(files).slice(0, maxFiles)
|
||||
const toProcess = files.slice(0, maxFiles)
|
||||
|
||||
toProcess.forEach(file => {
|
||||
if (!file.type.startsWith('image/')) return
|
||||
@@ -491,67 +510,34 @@ function removeParsedTask(taskArray: any[], idx: number) {
|
||||
}
|
||||
}
|
||||
|
||||
// 주차 계산 함수들
|
||||
function getMonday(date: Date): Date {
|
||||
const d = new Date(date)
|
||||
const day = d.getDay()
|
||||
const diff = d.getDate() - day + (day === 0 ? -6 : 1)
|
||||
d.setDate(diff)
|
||||
return d
|
||||
}
|
||||
|
||||
function getSunday(monday: Date): Date {
|
||||
const d = new Date(monday)
|
||||
d.setDate(d.getDate() + 6)
|
||||
return d
|
||||
}
|
||||
|
||||
function formatDate(date: Date): string {
|
||||
return date.toISOString().split('T')[0]
|
||||
}
|
||||
|
||||
function getWeekNumber(date: Date): { year: number; week: number } {
|
||||
const d = new Date(date)
|
||||
d.setHours(0, 0, 0, 0)
|
||||
d.setDate(d.getDate() + 3 - (d.getDay() + 6) % 7)
|
||||
const week1 = new Date(d.getFullYear(), 0, 4)
|
||||
const weekNum = 1 + Math.round(((d.getTime() - week1.getTime()) / 86400000 - 3 + (week1.getDay() + 6) % 7) / 7)
|
||||
return { year: d.getFullYear(), week: weekNum }
|
||||
}
|
||||
|
||||
function setWeekDates(monday: Date) {
|
||||
const sunday = getSunday(monday)
|
||||
const weekInfo = getWeekNumber(monday)
|
||||
|
||||
parsedData.value.weekStartDate = formatDate(monday)
|
||||
parsedData.value.weekEndDate = formatDate(sunday)
|
||||
parsedData.value.reportYear = weekInfo.year
|
||||
parsedData.value.reportWeek = weekInfo.week
|
||||
// 주차 관련 함수들 (useWeekCalc 사용)
|
||||
function setWeekFromInfo(info: { year: number; week: number; startDateStr: string; endDateStr: string }) {
|
||||
parsedData.value.reportYear = info.year
|
||||
parsedData.value.reportWeek = info.week
|
||||
parsedData.value.weekStartDate = info.startDateStr
|
||||
parsedData.value.weekEndDate = info.endDateStr
|
||||
}
|
||||
|
||||
function changeWeek(delta: number) {
|
||||
const currentMonday = new Date(parsedData.value.weekStartDate)
|
||||
currentMonday.setDate(currentMonday.getDate() + (delta * 7))
|
||||
setWeekDates(currentMonday)
|
||||
const { year, week } = calcChangeWeek(parsedData.value.reportYear, parsedData.value.reportWeek, delta)
|
||||
const weekInfo = getWeekDates(year, week)
|
||||
setWeekFromInfo(weekInfo)
|
||||
}
|
||||
|
||||
function setLastWeek() {
|
||||
const today = new Date()
|
||||
const lastWeekMonday = getMonday(today)
|
||||
lastWeekMonday.setDate(lastWeekMonday.getDate() - 7)
|
||||
setWeekDates(lastWeekMonday)
|
||||
const lastWeek = getLastWeekInfo()
|
||||
setWeekFromInfo(lastWeek)
|
||||
}
|
||||
|
||||
function setThisWeek() {
|
||||
const today = new Date()
|
||||
const thisWeekMonday = getMonday(today)
|
||||
setWeekDates(thisWeekMonday)
|
||||
const thisWeek = getActualCurrentWeekInfo()
|
||||
setWeekFromInfo(thisWeek)
|
||||
}
|
||||
|
||||
function updateWeekFromDate() {
|
||||
const startDate = new Date(parsedData.value.weekStartDate)
|
||||
const monday = getMonday(startDate)
|
||||
setWeekDates(monday)
|
||||
const weekInfo = getWeekInfo(startDate)
|
||||
setWeekFromInfo(weekInfo)
|
||||
}
|
||||
|
||||
// 분석 결과 처리
|
||||
@@ -568,6 +554,11 @@ function handleParseResult(res: any) {
|
||||
}))
|
||||
p.planTasks = p.planTasks || []
|
||||
})
|
||||
// 내용 없는 프로젝트 제외
|
||||
r.projects = r.projects.filter((p: any) =>
|
||||
(p.workTasks && p.workTasks.some((t: any) => t.description?.trim())) ||
|
||||
(p.planTasks && p.planTasks.some((t: any) => t.description?.trim()))
|
||||
)
|
||||
})
|
||||
employees.value = res.employees
|
||||
projects.value = res.projects
|
||||
@@ -616,12 +607,14 @@ async function bulkRegister() {
|
||||
employeeId: r.createNewEmployee ? null : r.matchedEmployeeId,
|
||||
employeeName: r.employeeName,
|
||||
employeeEmail: r.employeeEmail,
|
||||
projects: r.projects.map((p: any) => ({
|
||||
projectId: p.matchedProjectId,
|
||||
projectName: p.projectName,
|
||||
workTasks: (p.workTasks || []).filter((t: any) => t.description?.trim()),
|
||||
planTasks: (p.planTasks || []).filter((t: any) => t.description?.trim())
|
||||
})),
|
||||
projects: r.projects
|
||||
.map((p: any) => ({
|
||||
projectId: p.matchedProjectId,
|
||||
projectName: p.projectName,
|
||||
workTasks: (p.workTasks || []).filter((t: any) => t.description?.trim()),
|
||||
planTasks: (p.planTasks || []).filter((t: any) => t.description?.trim())
|
||||
}))
|
||||
.filter((p: any) => p.workTasks.length > 0 || p.planTasks.length > 0), // 내용 없는 프로젝트 제외
|
||||
issueDescription: r.issueDescription,
|
||||
vacationDescription: r.vacationDescription,
|
||||
remarkDescription: r.remarkDescription
|
||||
|
||||
Reference in New Issue
Block a user