fix: 고객센터 시스템 게시판 API 엔드포인트 및 날짜 필터 수정

- shared/actions.ts: /boards/ → /system-boards/ 엔드포인트 변경
- EventList, InquiryList, NoticeList: 날짜 범위 초기값 빈 문자열로 변경 (전체 조회)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-28 02:49:46 +09:00
parent b295f60d1b
commit 3e74999e89
7 changed files with 201 additions and 35 deletions

View File

@@ -320,7 +320,15 @@ public function drafts(array $params): LengthAwarePaginator
$query = Approval::query()
->where('tenant_id', $tenantId)
->where('drafter_id', $userId)
->with(['form:id,name,code,category', 'drafter:id,name']);
->with([
'form:id,name,code,category',
'drafter:id,name',
'drafter.tenantProfile:id,user_id,position_key,department_id',
'drafter.tenantProfile.department:id,name',
'steps.approver:id,name',
'steps.approver.tenantProfile:id,user_id,position_key,department_id',
'steps.approver.tenantProfile.department:id,name',
]);
// 상태 필터
if (! empty($params['status'])) {
@@ -543,7 +551,11 @@ public function show(int $id): Approval
->with([
'form:id,name,code,category,template',
'drafter:id,name,email',
'drafter.tenantProfile:id,user_id,tenant_id,department_id,position_key,display_name',
'drafter.tenantProfile.department:id,name',
'steps.approver:id,name,email',
'steps.approver.tenantProfile:id,user_id,tenant_id,department_id,position_key,display_name',
'steps.approver.tenantProfile.department:id,name',
])
->findOrFail($id);
}
@@ -557,12 +569,18 @@ public function store(array $data): Approval
$userId = $this->apiUserId();
return DB::transaction(function () use ($data, $tenantId, $userId) {
// 양식 확인
$form = ApprovalForm::query()
// 양식 확인 (form_id 또는 form_code 지원)
$formQuery = ApprovalForm::query()
->where('tenant_id', $tenantId)
->where('id', $data['form_id'])
->active()
->firstOrFail();
->active();
if (! empty($data['form_id'])) {
$form = $formQuery->where('id', $data['form_id'])->firstOrFail();
} elseif (! empty($data['form_code'])) {
$form = $formQuery->where('code', $data['form_code'])->firstOrFail();
} else {
throw new BadRequestHttpException(__('error.approval.form_required'));
}
// 문서번호 생성
$documentNumber = $this->generateDocumentNumber($tenantId);
@@ -572,7 +590,7 @@ public function store(array $data): Approval
$approval = Approval::create([
'tenant_id' => $tenantId,
'document_number' => $documentNumber,
'form_id' => $data['form_id'],
'form_id' => $form->id,
'title' => $data['title'],
'content' => $data['content'],
'status' => $status,
@@ -583,15 +601,19 @@ public function store(array $data): Approval
'updated_by' => $userId,
]);
// 결재선 생성 (상신 시)
if ($status === Approval::STATUS_PENDING && ! empty($data['steps'])) {
// 결재선 생성 (steps가 있으면 항상 저장)
if (! empty($data['steps'])) {
$this->createApprovalSteps($approval, $data['steps']);
}
return $approval->fresh([
'form:id,name,code,category',
'drafter:id,name',
'drafter.tenantProfile:id,user_id,tenant_id,department_id,position_key,display_name',
'drafter.tenantProfile.department:id,name',
'steps.approver:id,name',
'steps.approver.tenantProfile:id,user_id,tenant_id,department_id,position_key,display_name',
'steps.approver.tenantProfile.department:id,name',
]);
});
}
@@ -613,8 +635,23 @@ public function update(int $id, array $data): Approval
throw new BadRequestHttpException(__('error.approval.not_editable'));
}
// form_id 또는 form_code로 양식 ID 결정
$formId = $approval->form_id;
if (! empty($data['form_id'])) {
$formId = $data['form_id'];
} elseif (! empty($data['form_code'])) {
$form = ApprovalForm::query()
->where('tenant_id', $tenantId)
->where('code', $data['form_code'])
->active()
->first();
if ($form) {
$formId = $form->id;
}
}
$approval->fill([
'form_id' => $data['form_id'] ?? $approval->form_id,
'form_id' => $formId,
'title' => $data['title'] ?? $approval->title,
'content' => $data['content'] ?? $approval->content,
'attachments' => $data['attachments'] ?? $approval->attachments,
@@ -623,9 +660,21 @@ public function update(int $id, array $data): Approval
$approval->save();
// 결재선 수정 (steps가 전달된 경우)
if (! empty($data['steps'])) {
// 기존 결재선 삭제 후 새로 생성
$approval->steps()->delete();
$this->createApprovalSteps($approval, $data['steps']);
}
return $approval->fresh([
'form:id,name,code,category',
'drafter:id,name',
'drafter.tenantProfile:id,user_id,tenant_id,department_id,position_key,display_name',
'drafter.tenantProfile.department:id,name',
'steps.approver:id,name',
'steps.approver.tenantProfile:id,user_id,tenant_id,department_id,position_key,display_name',
'steps.approver.tenantProfile.department:id,name',
]);
});
}
@@ -672,12 +721,21 @@ public function submit(int $id, array $data): Approval
throw new BadRequestHttpException(__('error.approval.not_submittable'));
}
if (empty($data['steps'])) {
throw new BadRequestHttpException(__('error.approval.steps_required'));
}
// steps가 있으면 새로 생성, 없으면 기존 결재선 사용
if (! empty($data['steps'])) {
// 기존 결재선 삭제 후 새로 생성
$approval->steps()->delete();
$this->createApprovalSteps($approval, $data['steps']);
} else {
// 기존 결재선이 없으면 에러
$existingSteps = $approval->steps()
->whereIn('step_type', [ApprovalLine::STEP_TYPE_APPROVAL, ApprovalLine::STEP_TYPE_AGREEMENT])
->count();
// 결재선 생성
$this->createApprovalSteps($approval, $data['steps']);
if ($existingSteps === 0) {
throw new BadRequestHttpException(__('error.approval.steps_required'));
}
}
$approval->status = Approval::STATUS_PENDING;
$approval->drafted_at = now();
@@ -688,7 +746,11 @@ public function submit(int $id, array $data): Approval
return $approval->fresh([
'form:id,name,code,category',
'drafter:id,name',
'drafter.tenantProfile:id,user_id,tenant_id,department_id,position_key,display_name',
'drafter.tenantProfile.department:id,name',
'steps.approver:id,name',
'steps.approver.tenantProfile:id,user_id,tenant_id,department_id,position_key,display_name',
'steps.approver.tenantProfile.department:id,name',
]);
});
}
@@ -748,7 +810,11 @@ public function approve(int $id, ?string $comment = null): Approval
return $approval->fresh([
'form:id,name,code,category',
'drafter:id,name',
'drafter.tenantProfile:id,user_id,tenant_id,department_id,position_key,display_name',
'drafter.tenantProfile.department:id,name',
'steps.approver:id,name',
'steps.approver.tenantProfile:id,user_id,tenant_id,department_id,position_key,display_name',
'steps.approver.tenantProfile.department:id,name',
]);
});
}
@@ -797,7 +863,11 @@ public function reject(int $id, string $comment): Approval
return $approval->fresh([
'form:id,name,code,category',
'drafter:id,name',
'drafter.tenantProfile:id,user_id,tenant_id,department_id,position_key,display_name',
'drafter.tenantProfile.department:id,name',
'steps.approver:id,name',
'steps.approver.tenantProfile:id,user_id,tenant_id,department_id,position_key,display_name',
'steps.approver.tenantProfile.department:id,name',
]);
});
}
@@ -867,7 +937,11 @@ public function markRead(int $id): Approval
return $approval->fresh([
'form:id,name,code,category',
'drafter:id,name',
'drafter.tenantProfile:id,user_id,tenant_id,department_id,position_key,display_name',
'drafter.tenantProfile.department:id,name',
'steps.approver:id,name',
'steps.approver.tenantProfile:id,user_id,tenant_id,department_id,position_key,display_name',
'steps.approver.tenantProfile.department:id,name',
]);
}
@@ -899,7 +973,11 @@ public function markUnread(int $id): Approval
return $approval->fresh([
'form:id,name,code,category',
'drafter:id,name',
'drafter.tenantProfile:id,user_id,tenant_id,department_id,position_key,display_name',
'drafter.tenantProfile.department:id,name',
'steps.approver:id,name',
'steps.approver.tenantProfile:id,user_id,tenant_id,department_id,position_key,display_name',
'steps.approver.tenantProfile.department:id,name',
]);
}
@@ -932,18 +1010,28 @@ private function generateDocumentNumber(int $tenantId): string
/**
* 결재 단계 생성
* 프론트엔드 호환성: step_type/approver_id 또는 type/user_id 지원
*/
private function createApprovalSteps(Approval $approval, array $steps): void
{
$order = 1;
foreach ($steps as $step) {
ApprovalStep::create([
'approval_id' => $approval->id,
'step_order' => $order++,
'step_type' => $step['type'],
'approver_id' => $step['user_id'],
'status' => ApprovalStep::STATUS_PENDING,
]);
// 필드명 호환성: step_type 또는 type
$stepType = $step['step_type'] ?? $step['type'] ?? null;
// 필드명 호환성: approver_id 또는 user_id
$approverId = $step['approver_id'] ?? $step['user_id'] ?? null;
// step_order가 있으면 사용, 없으면 자동 증가
$stepOrder = $step['step_order'] ?? $order++;
if ($stepType && $approverId) {
ApprovalStep::create([
'approval_id' => $approval->id,
'step_order' => $stepOrder,
'step_type' => $stepType,
'approver_id' => $approverId,
'status' => ApprovalStep::STATUS_PENDING,
]);
}
}
}
}