2000, // 완제품 'PT' => 3000, // 부품 'SM' => 2000, // 부자재 'RM' => 2000, // 원자재 'CS' => 1000, // 소모품 ]; /** * 타입별 코드 접두사 */ private const TYPE_PREFIXES = [ 'FG' => 'FG', 'PT' => 'PT', 'SM' => 'SM', 'RM' => 'RM', 'CS' => 'CS', ]; /** * 타입별 품목명 패턴 */ private const TYPE_NAMES = [ 'FG' => ['스크린', '블라인드', '커튼', '차양막', '롤스크린', '버티칼', '우드블라인드', '허니콤', '듀오롤', '콤비블라인드'], 'PT' => ['모터', '브라켓', '가이드레일', '샤프트', '베어링', '기어박스', '풀리', '벨트', '스프링', '힌지'], 'SM' => ['나사', '볼트', '너트', '와셔', '리벳', '클립', '고정핀', '스토퍼', '캡', '부싱'], 'RM' => ['알루미늄', '스틸', 'PVC', '폴리에스터', '면', '폴리카보네이트', 'ABS', '나일론', '실리콘', '고무'], 'CS' => ['포장재', '라벨', '테이프', '박스', '비닐', '완충재', '스티커', '인쇄물', '매뉴얼', '보증서'], ]; /** * 단위 목록 */ private const UNITS = ['EA', 'SET', 'M', 'MM', 'KG', 'G', 'L', 'ML', 'BOX', 'ROLL']; /** * 색상 목록 */ private const COLORS = ['화이트', '아이보리', '베이지', '그레이', '블랙', '브라운', '네이비', '카키', '버건디', '실버']; /** * 규격 목록 */ private const SPECS = ['소형', '중형', '대형', '특대형', 'A타입', 'B타입', 'C타입', '표준', '고급', '프리미엄']; public function run(): void { $tenantId = DummyDataSeeder::TENANT_ID; $userId = DummyDataSeeder::USER_ID; // 기존 데이터 확인 $existing = Item::where('tenant_id', $tenantId)->count(); if ($existing >= 10000) { $this->command->info(' ⚠ items: 이미 '.$existing.'개 존재 (스킵)'); return; } $this->command->info(' 🔄 items: 10,000개 생성 중...'); $totalCount = 0; $now = now(); foreach (self::TYPE_COUNTS as $type => $count) { $prefix = self::TYPE_PREFIXES[$type]; $names = self::TYPE_NAMES[$type]; $items = []; for ($i = 1; $i <= $count; $i++) { $code = sprintf('%s-%06d', $prefix, $i); $baseName = $names[array_rand($names)]; $color = self::COLORS[array_rand(self::COLORS)]; $spec = self::SPECS[array_rand(self::SPECS)]; $name = "{$baseName} {$color} {$spec}"; $items[] = [ 'tenant_id' => $tenantId, 'item_type' => $type, 'code' => $code, 'name' => $name, 'unit' => self::UNITS[array_rand(self::UNITS)], 'category_id' => null, 'bom' => null, 'attributes' => json_encode($this->generateAttributes($type)), 'attributes_archive' => null, 'options' => json_encode(['color' => $color, 'spec' => $spec]), 'description' => "{$type} 타입 품목 - {$name}", 'is_active' => rand(1, 100) <= 95, // 95% 활성 'created_by' => $userId, 'updated_by' => $userId, 'created_at' => $now, 'updated_at' => $now, ]; // 1000개씩 배치 삽입 if (count($items) >= 1000) { DB::table('items')->insert($items); $totalCount += count($items); $items = []; $this->command->info(" → {$totalCount}개 완료..."); } } // 남은 데이터 삽입 if (! empty($items)) { DB::table('items')->insert($items); $totalCount += count($items); } } $this->command->info(' ✓ items: '.$totalCount.'건 생성 완료'); } /** * 타입별 속성 생성 */ private function generateAttributes(string $type): array { $base = [ 'weight' => rand(10, 10000) / 100, // 0.1 ~ 100 kg 'width' => rand(10, 3000), // 10 ~ 3000 mm 'height' => rand(10, 3000), // 10 ~ 3000 mm ]; return match ($type) { 'FG' => array_merge($base, [ 'warranty_months' => rand(6, 36), 'lead_time_days' => rand(3, 30), ]), 'PT' => array_merge($base, [ 'material' => ['알루미늄', '스틸', 'ABS', 'PVC'][array_rand(['알루미늄', '스틸', 'ABS', 'PVC'])], 'tolerance' => '±'.rand(1, 10) / 10 .'mm', ]), 'SM', 'RM' => array_merge($base, [ 'min_order_qty' => rand(1, 100) * 10, 'supplier' => ['국내', '중국', '베트남', '일본'][array_rand(['국내', '중국', '베트남', '일본'])], ]), 'CS' => [ 'expiry_months' => rand(6, 24), 'storage' => ['상온', '냉장', '냉동'][array_rand(['상온', '냉장', '냉동'])], ], default => $base, }; } }