feat: [bending] 절곡품 전용 테이블 분리 API

- bending_items 전용 테이블 생성 (items.options → 정규 컬럼 승격)
- bending_models 전용 테이블 생성 (가이드레일/케이스/하단마감재 통합)
- bending_data JSON 통합 (별도 테이블 → bending_items.bending_data 컬럼)
- bending_item_mappings 테이블 DROP (bending_items.code에 흡수)
- BendingItemService/BendingCodeService → BendingItem 모델 전환
- GuiderailModelService component 이미지 자동 복사
- ItemsFileController bending_items/bending_models 폴백 지원
- Swagger 스키마 업데이트
This commit is contained in:
강영보
2026-03-19 19:54:23 +09:00
parent 623298dd82
commit c29090a0b8
32 changed files with 3114 additions and 490 deletions

View File

@@ -12,61 +12,61 @@ public function toArray(Request $request): array
return [
'id' => $this->id,
'code' => $this->code,
'name' => $this->name,
'item_type' => $this->item_type,
'item_category' => $this->item_category,
'unit' => $this->unit,
'is_active' => $this->is_active,
// options → 최상위로 노출
'item_name' => $this->getOption('item_name'),
'item_sep' => $this->getOption('item_sep'),
'item_bending' => $this->getOption('item_bending'),
'item_spec' => $this->getOption('item_spec'),
'material' => $this->getOption('material'),
'model_name' => $this->getOption('model_name'),
'model_UA' => $this->getOption('model_UA'),
'legacy_code' => $this->legacy_code,
// 정규 컬럼 직접 참조
'item_name' => $this->item_name,
'item_sep' => $this->item_sep,
'item_bending' => $this->item_bending,
'item_spec' => $this->item_spec,
'material' => $this->material,
'model_name' => $this->model_name,
'model_UA' => $this->model_UA,
'rail_width' => $this->rail_width ? (int) $this->rail_width : null,
// 케이스 전용
'exit_direction' => $this->exit_direction,
'front_bottom' => $this->front_bottom ? (int) $this->front_bottom : null,
'box_width' => $this->box_width ? (int) $this->box_width : null,
'box_height' => $this->box_height ? (int) $this->box_height : null,
'inspection_door' => $this->inspection_door,
// 원자재 길이
'length_code' => $this->length_code,
'length_mm' => $this->length_mm,
// 전개도 (JSON 컬럼)
'bendingData' => $this->bending_data,
// 비정형 속성 (options)
'search_keyword' => $this->getOption('search_keyword'),
'rail_width' => $this->getOption('rail_width'),
'registration_date' => $this->getOption('registration_date'),
'author' => $this->getOption('author'),
'memo' => $this->getOption('memo'),
// 케이스 전용
'exit_direction' => $this->getOption('exit_direction'),
'front_bottom_width' => $this->getOption('front_bottom_width'),
'box_width' => $this->getOption('box_width'),
'box_height' => $this->getOption('box_height'),
// 전개도
'bendingData' => $this->getOption('bendingData'),
// PREFIX 관련
'prefix' => $this->getOption('prefix'),
'length_code' => $this->getOption('length_code'),
'length_mm' => $this->getOption('length_mm'),
'registration_date' => $this->getOption('registration_date'),
// 이미지
'image_file_id' => $this->getImageFileId(),
// 추적
'legacy_bending_num' => $this->getOption('legacy_bending_num'),
'legacy_bending_id' => $this->legacy_bending_id,
'legacy_bending_num' => $this->legacy_bending_id, // MNG2 호환
'modified_by' => $this->getOption('modified_by'),
// MNG2 호환 (items 기반 필드명)
'name' => $this->item_name,
'front_bottom_width' => $this->front_bottom ? (int) $this->front_bottom : null,
'item_type' => 'PT',
'item_category' => 'BENDING',
'unit' => 'EA',
// 계산값
'width_sum' => $this->getWidthSum(),
'bend_count' => $this->getBendCount(),
'width_sum' => $this->width_sum,
'bend_count' => $this->bend_count,
// 메타
'is_active' => $this->is_active,
'created_at' => $this->created_at?->format('Y-m-d H:i:s'),
'updated_at' => $this->updated_at?->format('Y-m-d H:i:s'),
];
}
private function getWidthSum(): ?int
private function getImageFileId(): ?int
{
$data = $this->getOption('bendingData', []);
if (empty($data)) {
return null;
}
$last = end($data);
$file = $this->files()
->where('field_key', 'bending_diagram')
->orderByDesc('id')
->first();
return isset($last['sum']) ? (int) $last['sum'] : null;
}
private function getBendCount(): int
{
$data = $this->getOption('bendingData', []);
return count(array_filter($data, fn ($d) => ($d['rate'] ?? '') !== ''));
return $file?->id;
}
}