Files
Gnuboard7/modules/_bundled/sirsoft-ecommerce/database/seeders/UserAddressSeeder.php
T
2026-04-01 10:30:52 +09:00

182 lines
5.2 KiB
PHP

<?php
namespace Modules\Sirsoft\Ecommerce\Database\Seeders;
use App\Models\User;
use App\Traits\HasSeederCounts;
use Illuminate\Database\Seeder;
use Modules\Sirsoft\Ecommerce\Models\UserAddress;
/**
* 사용자 배송지 더미 데이터 시더
*
* 모듈 설치 시 자동 실행되지 않습니다 (DatabaseSeeder에 미등록).
* 수동 실행: php artisan module:seed sirsoft-ecommerce --class=UserAddressSeeder
*/
class UserAddressSeeder extends Seeder
{
use HasSeederCounts;
/**
* 배송지를 생성할 기본 사용자 수
*/
private const USER_COUNT = 10;
/**
* 사용자당 배송지 최소 수
*/
private const MIN_ADDRESSES_PER_USER = 1;
/**
* 사용자당 배송지 최대 수
*/
private const MAX_ADDRESSES_PER_USER = 5;
/**
* 사용자당 해외 배송지 생성 확률 (%)
*/
private const INTERNATIONAL_ADDRESS_CHANCE = 30;
/**
* 국내 배송지명 목록
*/
private const DOMESTIC_NAMES = [
'집',
'회사',
'본가',
'학교',
'사무실',
'친구집',
'아파트',
'오피스텔',
'별장',
'기숙사',
];
/**
* 해외 배송지명 목록
*/
private const INTERNATIONAL_NAMES = [
'US 사무실',
'도쿄 집',
'상하이 사무실',
'런던 플랫',
'LA 하우스',
'NYC 아파트',
'오사카 스튜디오',
'베를린 사무실',
];
/**
* 시더 실행
*/
public function run(): void
{
$this->command->info('사용자 배송지 더미 데이터 생성을 시작합니다.');
$this->deleteExistingAddresses();
$this->createAddresses();
$count = UserAddress::count();
$this->command->info("사용자 배송지 더미 데이터 {$count}건이 성공적으로 생성되었습니다.");
}
/**
* 기존 배송지 삭제
*/
private function deleteExistingAddresses(): void
{
$deletedCount = UserAddress::count();
if ($deletedCount > 0) {
UserAddress::query()->delete();
$this->command->warn("기존 배송지 데이터 {$deletedCount}건을 삭제했습니다.");
}
}
/**
* 사용자별 배송지 생성
*/
private function createAddresses(): void
{
$userCount = $this->getSeederCount('address_users', self::USER_COUNT);
$users = User::take($userCount)->get();
if ($users->isEmpty()) {
$this->command->error('사용자가 없습니다. 먼저 사용자를 생성해주세요.');
return;
}
$this->command->line(" - 사용자 {$users->count()}명의 배송지 생성 중...");
$domesticCount = 0;
$internationalCount = 0;
foreach ($users as $user) {
$addressCount = rand(self::MIN_ADDRESSES_PER_USER, self::MAX_ADDRESSES_PER_USER);
$usedDomesticIndices = [];
$usedInternationalIndices = [];
for ($i = 0; $i < $addressCount; $i++) {
$isInternational = $i > 0 && rand(1, 100) <= self::INTERNATIONAL_ADDRESS_CHANCE;
if ($isInternational) {
[$index, $name] = $this->pickUniqueName($usedInternationalIndices, self::INTERNATIONAL_NAMES);
$usedInternationalIndices[] = $index;
UserAddress::factory()
->forUser($user)
->international()
->state([
'name' => $name,
'is_default' => false,
])
->create();
$internationalCount++;
} else {
[$index, $name] = $this->pickUniqueName($usedDomesticIndices, self::DOMESTIC_NAMES);
$usedDomesticIndices[] = $index;
UserAddress::factory()
->forUser($user)
->state([
'name' => $name,
'is_default' => $i === 0,
])
->create();
$domesticCount++;
}
}
}
$total = $domesticCount + $internationalCount;
$this->command->line(" - 배송지 {$total}건 생성 완료 (국내 {$domesticCount}건, 해외 {$internationalCount}건)");
}
/**
* 중복되지 않는 배송지명을 선택합니다.
*
* @param array $usedIndices 이미 사용된 배송지명 인덱스 목록
* @param array $namePool 배송지명 후보 목록
* @return array [인덱스, 배송지명]
*/
private function pickUniqueName(array $usedIndices, array $namePool): array
{
$availableIndices = array_values(array_diff(array_keys($namePool), $usedIndices));
if (empty($availableIndices)) {
$index = array_rand($namePool);
$suffix = ' '.rand(2, 9);
return [-1, $namePool[$index].$suffix];
}
$index = $availableIndices[array_rand($availableIndices)];
return [$index, $namePool[$index]];
}
}