작업계획서대로 진행
This commit is contained in:
172
frontend/maintenance/write.vue
Normal file
172
frontend/maintenance/write.vue
Normal file
@@ -0,0 +1,172 @@
|
||||
<template>
|
||||
<div>
|
||||
<AppHeader />
|
||||
|
||||
<div class="container-fluid py-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h4 class="mb-0">
|
||||
<i class="bi bi-tools me-2"></i>유지보수 업무 등록
|
||||
</h4>
|
||||
<NuxtLink to="/maintenance" class="btn btn-outline-secondary">
|
||||
<i class="bi bi-arrow-left me-1"></i>목록
|
||||
</NuxtLink>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">프로젝트</label>
|
||||
<select class="form-select" v-model="form.projectId">
|
||||
<option value="">선택 안함</option>
|
||||
<option v-for="p in projects" :key="p.projectId" :value="p.projectId">
|
||||
{{ p.projectName }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">요청일 <span class="text-danger">*</span></label>
|
||||
<input type="date" class="form-control" v-model="form.requestDate" />
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">담당자</label>
|
||||
<select class="form-select" v-model="form.assigneeId">
|
||||
<option value="">미배정</option>
|
||||
<option v-for="e in employees" :key="e.employeeId" :value="e.employeeId">
|
||||
{{ e.employeeName }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<label class="form-label">제목 <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control" v-model="form.requestTitle" placeholder="업무 제목" />
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">우선순위</label>
|
||||
<select class="form-select" v-model="form.priority">
|
||||
<option value="HIGH">높음</option>
|
||||
<option value="MEDIUM">보통</option>
|
||||
<option value="LOW">낮음</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">업무유형</label>
|
||||
<select class="form-select" v-model="form.taskType">
|
||||
<option value="GENERAL">일반</option>
|
||||
<option value="BUG">버그수정</option>
|
||||
<option value="ENHANCEMENT">기능개선</option>
|
||||
<option value="DATA">데이터</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">요청자명</label>
|
||||
<input type="text" class="form-control" v-model="form.requesterName" placeholder="요청자 이름" />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">요청자 연락처</label>
|
||||
<input type="text" class="form-control" v-model="form.requesterContact" placeholder="전화번호 또는 이메일" />
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label">내용</label>
|
||||
<textarea class="form-control" v-model="form.requestContent" rows="6" placeholder="업무 내용을 입력하세요"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer text-end">
|
||||
<button class="btn btn-primary" @click="save" :disabled="isSaving">
|
||||
<span v-if="isSaving">
|
||||
<span class="spinner-border spinner-border-sm me-1"></span>등록 중...
|
||||
</span>
|
||||
<span v-else><i class="bi bi-check-lg me-1"></i>등록</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const { fetchCurrentUser } = useAuth()
|
||||
const router = useRouter()
|
||||
|
||||
interface Project { projectId: number; projectName: string }
|
||||
interface Employee { employeeId: number; employeeName: string }
|
||||
|
||||
const projects = ref<Project[]>([])
|
||||
const employees = ref<Employee[]>([])
|
||||
const isSaving = ref(false)
|
||||
|
||||
const form = ref({
|
||||
projectId: '',
|
||||
requestDate: new Date().toISOString().split('T')[0],
|
||||
requestTitle: '',
|
||||
requestContent: '',
|
||||
requesterName: '',
|
||||
requesterContact: '',
|
||||
taskType: 'GENERAL',
|
||||
priority: 'MEDIUM',
|
||||
assigneeId: ''
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
const user = await fetchCurrentUser()
|
||||
if (!user) {
|
||||
router.push('/login')
|
||||
return
|
||||
}
|
||||
await loadProjects()
|
||||
await loadEmployees()
|
||||
})
|
||||
|
||||
async function loadProjects() {
|
||||
try {
|
||||
const res = await $fetch<{ projects: Project[] }>('/api/project/list')
|
||||
projects.value = res.projects || []
|
||||
} catch (e) {
|
||||
console.error('Load projects error:', e)
|
||||
}
|
||||
}
|
||||
|
||||
async function loadEmployees() {
|
||||
try {
|
||||
const res = await $fetch<{ employees: Employee[] }>('/api/employee/list')
|
||||
employees.value = res.employees || []
|
||||
} catch (e) {
|
||||
console.error('Load employees error:', e)
|
||||
}
|
||||
}
|
||||
|
||||
async function save() {
|
||||
if (!form.value.requestTitle) {
|
||||
alert('제목을 입력하세요.')
|
||||
return
|
||||
}
|
||||
if (!form.value.requestDate) {
|
||||
alert('요청일을 선택하세요.')
|
||||
return
|
||||
}
|
||||
|
||||
isSaving.value = true
|
||||
try {
|
||||
const res = await $fetch<{ taskId: number }>('/api/maintenance/create', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
projectId: form.value.projectId ? Number(form.value.projectId) : null,
|
||||
requestDate: form.value.requestDate,
|
||||
requestTitle: form.value.requestTitle,
|
||||
requestContent: form.value.requestContent,
|
||||
requesterName: form.value.requesterName,
|
||||
requesterContact: form.value.requesterContact,
|
||||
taskType: form.value.taskType,
|
||||
priority: form.value.priority,
|
||||
assigneeId: form.value.assigneeId ? Number(form.value.assigneeId) : null
|
||||
}
|
||||
})
|
||||
router.push(`/maintenance/${res.taskId}`)
|
||||
} catch (e: any) {
|
||||
alert(e.data?.message || e.message || '등록에 실패했습니다.')
|
||||
} finally {
|
||||
isSaving.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user