diff --git a/app/Models/Member.php b/app/Models/Member.php index ca596a6..a81e678 100644 --- a/app/Models/Member.php +++ b/app/Models/Member.php @@ -30,6 +30,10 @@ class Member extends Model const DISABILITY_STATUS_APPROVED = 'approved'; const DISABILITY_STATUS_REJECTED = 'rejected'; + // Identity type constants (病友/家長) + const IDENTITY_PATIENT = 'patient'; // 病友 + const IDENTITY_PARENT = 'parent'; // 家長/父母 + protected $fillable = [ 'user_id', 'full_name', @@ -47,6 +51,8 @@ class Member extends Model 'membership_expires_at', 'membership_status', 'membership_type', + 'identity_type', + 'guardian_member_id', 'disability_certificate_path', 'disability_certificate_status', 'disability_verified_by', @@ -72,6 +78,50 @@ class Member extends Model return $this->hasMany(MembershipPayment::class); } + /** + * 監護人(父母) + */ + public function guardian() + { + return $this->belongsTo(Member::class, 'guardian_member_id'); + } + + /** + * 被監護人(子女) + */ + public function dependents() + { + return $this->hasMany(Member::class, 'guardian_member_id'); + } + + /** + * 是否為病友 + */ + public function isPatient(): bool + { + return $this->identity_type === self::IDENTITY_PATIENT; + } + + /** + * 是否為家長/父母 + */ + public function isParent(): bool + { + return $this->identity_type === self::IDENTITY_PARENT; + } + + /** + * 取得身份類型標籤 + */ + public function getIdentityTypeLabelAttribute(): string + { + return match ($this->identity_type) { + self::IDENTITY_PATIENT => '病友', + self::IDENTITY_PARENT => '家長/父母', + default => '未設定', + }; + } + /** * 關聯的收入記錄 */ diff --git a/database/migrations/2026_01_25_043205_add_identity_and_guardian_to_members_table.php b/database/migrations/2026_01_25_043205_add_identity_and_guardian_to_members_table.php new file mode 100644 index 0000000..8bd44a2 --- /dev/null +++ b/database/migrations/2026_01_25_043205_add_identity_and_guardian_to_members_table.php @@ -0,0 +1,36 @@ +string('identity_type')->nullable()->after('membership_type'); + + // 監護人關係(未成年人指向其父母的 member_id) + $table->foreignId('guardian_member_id')->nullable()->after('identity_type') + ->constrained('members')->nullOnDelete(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('members', function (Blueprint $table) { + $table->dropForeign(['guardian_member_id']); + $table->dropColumn(['identity_type', 'guardian_member_id']); + }); + } +};