From 86424023c8c0c774de66f0a7a416e558caa25f92 Mon Sep 17 00:00:00 2001 From: sungro815 Date: Mon, 19 Jan 2026 10:19:09 +0900 Subject: [PATCH] =?UTF-8?q?=ED=9A=8C=EC=9B=90=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EB=AA=A8=EB=8D=B8=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Member/Concerns/HasNoTimestamps.php | 8 ++ app/Models/Member/MemAddress.php | 24 ++++ app/Models/Member/MemAuth.php | 38 ++++++ app/Models/Member/MemAuthInfo.php | 28 +++++ app/Models/Member/MemAuthLog.php | 32 +++++ app/Models/Member/MemInfo.php | 87 ++++++++++++++ app/Models/Member/MemJoinFilter.php | 22 ++++ app/Models/Member/MemJoinLog.php | 24 ++++ app/Models/Member/MemLoginRecent.php | 24 ++++ app/Models/Member/MemLoginYear.php | 27 +++++ app/Models/Member/MemModLog.php | 18 +++ app/Models/Member/MemPasswdModify.php | 22 ++++ app/Models/Member/MemStRing.php | 24 ++++ .../Member/MemberAuthRepository.php | 110 ++++++++++++++++++ 14 files changed, 488 insertions(+) create mode 100644 app/Models/Member/Concerns/HasNoTimestamps.php create mode 100644 app/Models/Member/MemAddress.php create mode 100644 app/Models/Member/MemAuth.php create mode 100644 app/Models/Member/MemAuthInfo.php create mode 100644 app/Models/Member/MemAuthLog.php create mode 100644 app/Models/Member/MemInfo.php create mode 100644 app/Models/Member/MemJoinFilter.php create mode 100644 app/Models/Member/MemJoinLog.php create mode 100644 app/Models/Member/MemLoginRecent.php create mode 100644 app/Models/Member/MemLoginYear.php create mode 100644 app/Models/Member/MemModLog.php create mode 100644 app/Models/Member/MemPasswdModify.php create mode 100644 app/Models/Member/MemStRing.php create mode 100644 app/Repositories/Member/MemberAuthRepository.php diff --git a/app/Models/Member/Concerns/HasNoTimestamps.php b/app/Models/Member/Concerns/HasNoTimestamps.php new file mode 100644 index 0000000..0a0bb12 --- /dev/null +++ b/app/Models/Member/Concerns/HasNoTimestamps.php @@ -0,0 +1,8 @@ +belongsTo(MemInfo::class, 'mem_no', 'mem_no'); + } +} diff --git a/app/Models/Member/MemAuth.php b/app/Models/Member/MemAuth.php new file mode 100644 index 0000000..1db2e0d --- /dev/null +++ b/app/Models/Member/MemAuth.php @@ -0,0 +1,38 @@ +belongsTo(MemInfo::class, 'mem_no', 'mem_no'); + } +} diff --git a/app/Models/Member/MemAuthInfo.php b/app/Models/Member/MemAuthInfo.php new file mode 100644 index 0000000..acd8db9 --- /dev/null +++ b/app/Models/Member/MemAuthInfo.php @@ -0,0 +1,28 @@ + 'array', + ]; + + public function member(): BelongsTo + { + return $this->belongsTo(MemInfo::class, 'mem_no', 'mem_no'); + } +} diff --git a/app/Models/Member/MemAuthLog.php b/app/Models/Member/MemAuthLog.php new file mode 100644 index 0000000..bd452d9 --- /dev/null +++ b/app/Models/Member/MemAuthLog.php @@ -0,0 +1,32 @@ + 'array', + ]; + + public const STATE_S = 'S'; // success + public const STATE_F = 'F'; // fail + public const STATE_P = 'P'; // pass/processing + + public function member(): BelongsTo + { + return $this->belongsTo(MemInfo::class, 'mem_no', 'mem_no'); + } +} diff --git a/app/Models/Member/MemInfo.php b/app/Models/Member/MemInfo.php new file mode 100644 index 0000000..6979e9f --- /dev/null +++ b/app/Models/Member/MemInfo.php @@ -0,0 +1,87 @@ + 'array', + 'modify_log' => 'array', + ]; + + /* ===================== + * Relationships + * ===================== */ + + public function authInfo(): HasOne + { + return $this->hasOne(MemAuthInfo::class, 'mem_no', 'mem_no'); + } + + public function authRows(): HasMany + { + // mem_auth 복합키 테이블이지만 조회 관계는 문제 없음 + return $this->hasMany(MemAuth::class, 'mem_no', 'mem_no'); + } + + public function authLogs(): HasMany + { + return $this->hasMany(MemAuthLog::class, 'mem_no', 'mem_no'); + } + + public function addresses(): HasMany + { + return $this->hasMany(MemAddress::class, 'mem_no', 'mem_no'); + } + + public function joinLogs(): HasMany + { + return $this->hasMany(MemJoinLog::class, 'mem_no', 'mem_no'); + } + + public function stRing(): HasOne + { + return $this->hasOne(MemStRing::class, 'mem_no', 'mem_no'); + } + + public function loginRecents(): HasMany + { + return $this->hasMany(MemLoginRecent::class, 'mem_no', 'mem_no'); + } + + public function modLogs(): HasMany + { + return $this->hasMany(MemModLog::class, 'mem_no', 'mem_no'); + } + + /* ===================== + * Helpers (optional) + * ===================== */ + + public function isWithdrawn(): bool + { + // legacy: dt_out 기본값이 0000-00-00... 이므로 문자열 비교로 처리 + return isset($this->attributes['dt_out']) && $this->attributes['dt_out'] !== '0000-00-00 00:00:00'; + } + + public function hasEmail(): bool + { + return !empty($this->attributes['email']); + } +} diff --git a/app/Models/Member/MemJoinFilter.php b/app/Models/Member/MemJoinFilter.php new file mode 100644 index 0000000..52d5d94 --- /dev/null +++ b/app/Models/Member/MemJoinFilter.php @@ -0,0 +1,22 @@ + 'array', + ]; +} diff --git a/app/Models/Member/MemJoinLog.php b/app/Models/Member/MemJoinLog.php new file mode 100644 index 0000000..8f342a7 --- /dev/null +++ b/app/Models/Member/MemJoinLog.php @@ -0,0 +1,24 @@ +belongsTo(MemInfo::class, 'mem_no', 'mem_no'); + } +} diff --git a/app/Models/Member/MemLoginRecent.php b/app/Models/Member/MemLoginRecent.php new file mode 100644 index 0000000..7424c90 --- /dev/null +++ b/app/Models/Member/MemLoginRecent.php @@ -0,0 +1,24 @@ +belongsTo(MemInfo::class, 'mem_no', 'mem_no'); + } +} diff --git a/app/Models/Member/MemLoginYear.php b/app/Models/Member/MemLoginYear.php new file mode 100644 index 0000000..58be580 --- /dev/null +++ b/app/Models/Member/MemLoginYear.php @@ -0,0 +1,27 @@ +forYear(2026)->create([...]) + */ +class MemLoginYear extends Model +{ + use HasNoTimestamps; + + protected $primaryKey = 'seq'; + public $incrementing = true; + protected $keyType = 'int'; + + protected $guarded = []; + + public function forYear(int $year): self + { + $this->setTable('mem_login_' . $year); + return $this; + } +} diff --git a/app/Models/Member/MemModLog.php b/app/Models/Member/MemModLog.php new file mode 100644 index 0000000..8789310 --- /dev/null +++ b/app/Models/Member/MemModLog.php @@ -0,0 +1,18 @@ + 'array', + ]; +} diff --git a/app/Models/Member/MemStRing.php b/app/Models/Member/MemStRing.php new file mode 100644 index 0000000..29563d0 --- /dev/null +++ b/app/Models/Member/MemStRing.php @@ -0,0 +1,24 @@ +belongsTo(MemInfo::class, 'mem_no', 'mem_no'); + } +} diff --git a/app/Repositories/Member/MemberAuthRepository.php b/app/Repositories/Member/MemberAuthRepository.php new file mode 100644 index 0000000..dd334e4 --- /dev/null +++ b/app/Repositories/Member/MemberAuthRepository.php @@ -0,0 +1,110 @@ +toDateString(); + + DB::table('mem_auth')->updateOrInsert( + ['mem_no' => $memNo, 'auth_type' => $authType], + ['auth_state' => $authState, 'auth_date' => $authDate] + ); + } + + public function markRequested(int $memNo, string $authType, array $logInfo = []): void + { + $this->setStateWithLog($memNo, $authType, MemAuth::STATE_R, MemAuthLog::STATE_P, $logInfo); + } + + public function markProcessing(int $memNo, string $authType, array $logInfo = []): void + { + $this->setStateWithLog($memNo, $authType, MemAuth::STATE_P, MemAuthLog::STATE_P, $logInfo); + } + + public function markSuccess(int $memNo, string $authType, array $logInfo = []): void + { + $this->setStateWithLog($memNo, $authType, MemAuth::STATE_Y, MemAuthLog::STATE_S, $logInfo); + } + + public function markFail(int $memNo, string $authType, array $logInfo = []): void + { + $this->setStateWithLog($memNo, $authType, MemAuth::STATE_N, MemAuthLog::STATE_F, $logInfo); + } + + /** + * mem_auth_info.auth_info JSON에 타입별로 병합 저장 + * - 예: ["email" => [...], "cell" => [...]] + */ + public function mergeAuthInfo(int $memNo, string $authType, array $payload): void + { + DB::transaction(function () use ($memNo, $authType, $payload) { + /** @var MemAuthInfo $row */ + $row = MemAuthInfo::query()->find($memNo); + + if (!$row) { + $row = new MemAuthInfo(); + $row->mem_no = $memNo; + $row->auth_info = []; + } + + $data = $row->auth_info ?: []; + $data[$authType] = array_merge($data[$authType] ?? [], $payload); + + $row->auth_info = $data; + $row->save(); + }); + } + + /** + * mem_auth 상태 변경 + mem_auth_log 기록을 한 트랜잭션으로 + */ + private function setStateWithLog( + int $memNo, + string $authType, + string $authState, + string $logState, + array $logInfo + ): void { + DB::transaction(function () use ($memNo, $authType, $authState, $logState, $logInfo) { + $this->upsertState($memNo, $authType, $authState); + + MemAuthLog::query()->create([ + 'mem_no' => $memNo, + 'type' => $authType, + 'state' => $logState, + 'info' => $logInfo, + 'rgdate' => Carbon::now()->toDateTimeString(), + ]); + }); + } + + public function getState(int $memNo, string $authType): ?string + { + return DB::table('mem_auth') + ->where('mem_no', $memNo) + ->where('auth_type', $authType) + ->value('auth_state'); + } + + public function isVerified(int $memNo, string $authType): bool + { + return $this->getState($memNo, $authType) === MemAuth::STATE_Y; + } +}