refactor: 섹션 관리를 entity_relationships 참조 방식으로 전환
- SectionTemplateService: 독립 섹션 생성, page_id 있으면 링크 연결 - ItemMasterService: init API가 linkedSections 기반으로 조회 - SectionTemplateStoreRequest: page_id nullable로 변경 - Swagger: 스키마 업데이트 (sectionTemplates → sections)
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace App\Services\ItemMaster;
|
||||
|
||||
use App\Models\ItemMaster\EntityRelationship;
|
||||
use App\Models\ItemMaster\ItemPage;
|
||||
use App\Models\ItemMaster\ItemSection;
|
||||
use App\Services\Service;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
@@ -10,104 +12,145 @@
|
||||
/**
|
||||
* SectionTemplateService
|
||||
*
|
||||
* 섹션 템플릿 관리 서비스
|
||||
* 내부적으로 ItemSection (is_template=true) 사용
|
||||
* 섹션 관리 서비스 (참조 방식)
|
||||
* - 섹션은 독립 엔티티로 생성
|
||||
* - 페이지와는 entity_relationships로 링크 연결
|
||||
*/
|
||||
class SectionTemplateService extends Service
|
||||
{
|
||||
/**
|
||||
* 섹션 템플릿 목록
|
||||
* 섹션 목록 (독립 섹션 전체)
|
||||
*/
|
||||
public function index(): Collection
|
||||
{
|
||||
$tenantId = $this->tenantId();
|
||||
|
||||
return ItemSection::templates()
|
||||
->where('tenant_id', $tenantId)
|
||||
return ItemSection::where('tenant_id', $tenantId)
|
||||
->with(['fields', 'bomItems'])
|
||||
->orderBy('created_at', 'desc')
|
||||
->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* 섹션 템플릿 생성
|
||||
* 독립 섹션 생성 (page_id가 있으면 링크도 연결)
|
||||
*
|
||||
* @param array $data ['page_id'(optional), 'title', 'type', 'description', 'is_default']
|
||||
*/
|
||||
public function store(array $data): ItemSection
|
||||
{
|
||||
$tenantId = $this->tenantId();
|
||||
$userId = $this->apiUserId();
|
||||
$pageId = $data['page_id'] ?? null;
|
||||
|
||||
$template = ItemSection::create([
|
||||
// page_id가 있으면 페이지 존재 확인
|
||||
if ($pageId) {
|
||||
$page = ItemPage::where('tenant_id', $tenantId)->find($pageId);
|
||||
if (! $page) {
|
||||
throw new NotFoundHttpException(__('error.page_not_found'));
|
||||
}
|
||||
}
|
||||
|
||||
// 1. 독립 섹션 생성 (page_id=null)
|
||||
$section = ItemSection::create([
|
||||
'tenant_id' => $tenantId,
|
||||
'group_id' => 1,
|
||||
'page_id' => null,
|
||||
'title' => $data['title'],
|
||||
'type' => $data['type'],
|
||||
'order_no' => 0,
|
||||
'is_template' => true,
|
||||
'is_template' => false,
|
||||
'is_default' => $data['is_default'] ?? false,
|
||||
'description' => $data['description'] ?? null,
|
||||
'created_by' => $userId,
|
||||
]);
|
||||
|
||||
return $template->load(['fields', 'bomItems']);
|
||||
// 2. page_id가 있으면 링크 연결
|
||||
if ($pageId) {
|
||||
$maxOrderNo = EntityRelationship::where('tenant_id', $tenantId)
|
||||
->where('parent_type', EntityRelationship::TYPE_PAGE)
|
||||
->where('parent_id', $pageId)
|
||||
->where('child_type', EntityRelationship::TYPE_SECTION)
|
||||
->max('order_no') ?? -1;
|
||||
|
||||
EntityRelationship::link(
|
||||
$tenantId,
|
||||
EntityRelationship::TYPE_PAGE,
|
||||
$pageId,
|
||||
EntityRelationship::TYPE_SECTION,
|
||||
$section->id,
|
||||
$maxOrderNo + 1
|
||||
);
|
||||
}
|
||||
|
||||
return $section->load(['fields', 'bomItems']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 섹션 템플릿 수정
|
||||
* 섹션 수정
|
||||
*/
|
||||
public function update(int $id, array $data): ItemSection
|
||||
{
|
||||
$tenantId = $this->tenantId();
|
||||
$userId = $this->apiUserId();
|
||||
|
||||
$template = ItemSection::templates()
|
||||
->where('tenant_id', $tenantId)
|
||||
$section = ItemSection::where('tenant_id', $tenantId)
|
||||
->where('id', $id)
|
||||
->first();
|
||||
|
||||
if (! $template) {
|
||||
if (! $section) {
|
||||
throw new NotFoundHttpException(__('error.section_not_found'));
|
||||
}
|
||||
|
||||
$template->update([
|
||||
'title' => $data['title'] ?? $template->title,
|
||||
'type' => $data['type'] ?? $template->type,
|
||||
'description' => $data['description'] ?? $template->description,
|
||||
'is_default' => $data['is_default'] ?? $template->is_default,
|
||||
$section->update([
|
||||
'title' => $data['title'] ?? $section->title,
|
||||
'type' => $data['type'] ?? $section->type,
|
||||
'description' => $data['description'] ?? $section->description,
|
||||
'is_default' => $data['is_default'] ?? $section->is_default,
|
||||
'updated_by' => $userId,
|
||||
]);
|
||||
|
||||
return $template->fresh()->load(['fields', 'bomItems']);
|
||||
return $section->fresh()->load(['fields', 'bomItems']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 섹션 템플릿 삭제
|
||||
* 섹션 삭제 (Soft Delete) + 링크 해제
|
||||
*/
|
||||
public function destroy(int $id): void
|
||||
{
|
||||
$tenantId = $this->tenantId();
|
||||
$userId = $this->apiUserId();
|
||||
|
||||
$template = ItemSection::templates()
|
||||
->where('tenant_id', $tenantId)
|
||||
$section = ItemSection::where('tenant_id', $tenantId)
|
||||
->where('id', $id)
|
||||
->first();
|
||||
|
||||
if (! $template) {
|
||||
if (! $section) {
|
||||
throw new NotFoundHttpException(__('error.section_not_found'));
|
||||
}
|
||||
|
||||
$template->update(['deleted_by' => $userId]);
|
||||
$template->delete();
|
||||
// 1. 모든 부모 링크 해제 (페이지-섹션 관계)
|
||||
EntityRelationship::where('tenant_id', $tenantId)
|
||||
->where('child_type', EntityRelationship::TYPE_SECTION)
|
||||
->where('child_id', $id)
|
||||
->delete();
|
||||
|
||||
// 하위 필드/BOM도 Soft Delete
|
||||
foreach ($template->fields as $field) {
|
||||
// 2. 모든 자식 링크 해제 (섹션-필드, 섹션-BOM 관계)
|
||||
EntityRelationship::where('tenant_id', $tenantId)
|
||||
->where('parent_type', EntityRelationship::TYPE_SECTION)
|
||||
->where('parent_id', $id)
|
||||
->delete();
|
||||
|
||||
// 3. 섹션 Soft Delete
|
||||
$section->update(['deleted_by' => $userId]);
|
||||
$section->delete();
|
||||
|
||||
// 4. 하위 필드/BOM도 Soft Delete
|
||||
foreach ($section->fields as $field) {
|
||||
$field->update(['deleted_by' => $userId]);
|
||||
$field->delete();
|
||||
}
|
||||
|
||||
foreach ($template->bomItems as $bomItem) {
|
||||
foreach ($section->bomItems as $bomItem) {
|
||||
$bomItem->update(['deleted_by' => $userId]);
|
||||
$bomItem->delete();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user