회원목록
This commit is contained in:
@@ -0,0 +1,265 @@
|
||||
|
||||
/// 사용자 역할 정의
|
||||
enum UserRole {
|
||||
member, // 일반 회원
|
||||
manager, // 매니저 (일부 관리 권한)
|
||||
admin, // 관리자 (대부분의 관리 권한)
|
||||
owner // 소유자 (모든 권한)
|
||||
}
|
||||
|
||||
/// 관리 권한 정의
|
||||
class AdminPermission {
|
||||
final bool canManageMembers; // 회원 관리 권한
|
||||
final bool canManageEvents; // 이벤트 관리 권한
|
||||
final bool canManageScores; // 점수 관리 권한
|
||||
final bool canManageSettings; // 설정 관리 권한
|
||||
final bool canManageSubscription; // 구독 관리 권한
|
||||
final bool canManageRoles; // 역할 관리 권한
|
||||
final bool canViewFinancials; // 재정 정보 조회 권한
|
||||
final bool canExportData; // 데이터 내보내기 권한
|
||||
|
||||
const AdminPermission({
|
||||
this.canManageMembers = false,
|
||||
this.canManageEvents = false,
|
||||
this.canManageScores = false,
|
||||
this.canManageSettings = false,
|
||||
this.canManageSubscription = false,
|
||||
this.canManageRoles = false,
|
||||
this.canViewFinancials = false,
|
||||
this.canExportData = false,
|
||||
});
|
||||
|
||||
/// 역할에 따른 기본 권한 생성
|
||||
factory AdminPermission.fromRole(UserRole role) {
|
||||
switch (role) {
|
||||
case UserRole.member:
|
||||
return const AdminPermission();
|
||||
case UserRole.manager:
|
||||
return const AdminPermission(
|
||||
canManageMembers: true,
|
||||
canManageEvents: true,
|
||||
canManageScores: true,
|
||||
canExportData: true,
|
||||
);
|
||||
case UserRole.admin:
|
||||
return const AdminPermission(
|
||||
canManageMembers: true,
|
||||
canManageEvents: true,
|
||||
canManageScores: true,
|
||||
canManageSettings: true,
|
||||
canViewFinancials: true,
|
||||
canExportData: true,
|
||||
);
|
||||
case UserRole.owner:
|
||||
return const AdminPermission(
|
||||
canManageMembers: true,
|
||||
canManageEvents: true,
|
||||
canManageScores: true,
|
||||
canManageSettings: true,
|
||||
canManageSubscription: true,
|
||||
canManageRoles: true,
|
||||
canViewFinancials: true,
|
||||
canExportData: true,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// JSON에서 권한 객체 생성
|
||||
factory AdminPermission.fromJson(Map<String, dynamic> json) {
|
||||
return AdminPermission(
|
||||
canManageMembers: json['canManageMembers'] ?? false,
|
||||
canManageEvents: json['canManageEvents'] ?? false,
|
||||
canManageScores: json['canManageScores'] ?? false,
|
||||
canManageSettings: json['canManageSettings'] ?? false,
|
||||
canManageSubscription: json['canManageSubscription'] ?? false,
|
||||
canManageRoles: json['canManageRoles'] ?? false,
|
||||
canViewFinancials: json['canViewFinancials'] ?? false,
|
||||
canExportData: json['canExportData'] ?? false,
|
||||
);
|
||||
}
|
||||
|
||||
/// 권한 객체를 JSON으로 변환
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'canManageMembers': canManageMembers,
|
||||
'canManageEvents': canManageEvents,
|
||||
'canManageScores': canManageScores,
|
||||
'canManageSettings': canManageSettings,
|
||||
'canManageSubscription': canManageSubscription,
|
||||
'canManageRoles': canManageRoles,
|
||||
'canViewFinancials': canViewFinancials,
|
||||
'canExportData': canExportData,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// 클럽 회원 역할 정보
|
||||
class MemberRole {
|
||||
final String userId;
|
||||
final String memberId;
|
||||
final String clubId;
|
||||
final UserRole role;
|
||||
final AdminPermission permissions;
|
||||
final DateTime assignedAt;
|
||||
final String? assignedBy;
|
||||
|
||||
MemberRole({
|
||||
required this.userId,
|
||||
required this.memberId,
|
||||
required this.clubId,
|
||||
required this.role,
|
||||
required this.permissions,
|
||||
required this.assignedAt,
|
||||
this.assignedBy,
|
||||
});
|
||||
|
||||
/// JSON에서 회원 역할 객체 생성
|
||||
factory MemberRole.fromJson(Map<String, dynamic> json) {
|
||||
return MemberRole(
|
||||
userId: json['userId'],
|
||||
memberId: json['memberId'],
|
||||
clubId: json['clubId'],
|
||||
role: UserRole.values.firstWhere(
|
||||
(e) => e.toString().split('.').last == json['role'],
|
||||
orElse: () => UserRole.member,
|
||||
),
|
||||
permissions: AdminPermission.fromJson(json['permissions'] ?? {}),
|
||||
assignedAt: DateTime.parse(json['assignedAt']),
|
||||
assignedBy: json['assignedBy'],
|
||||
);
|
||||
}
|
||||
|
||||
/// 회원 역할 객체를 JSON으로 변환
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'userId': userId,
|
||||
'memberId': memberId,
|
||||
'clubId': clubId,
|
||||
'role': role.toString().split('.').last,
|
||||
'permissions': permissions.toJson(),
|
||||
'assignedAt': assignedAt.toIso8601String(),
|
||||
'assignedBy': assignedBy,
|
||||
};
|
||||
}
|
||||
|
||||
/// 역할 이름 (한글)
|
||||
String get roleName {
|
||||
switch (role) {
|
||||
case UserRole.member:
|
||||
return '일반 회원';
|
||||
case UserRole.manager:
|
||||
return '매니저';
|
||||
case UserRole.admin:
|
||||
return '관리자';
|
||||
case UserRole.owner:
|
||||
return '소유자';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 클럽 설정 모델
|
||||
class ClubSettings {
|
||||
final String clubId;
|
||||
final String clubName;
|
||||
final String? logoUrl;
|
||||
final String? bannerUrl;
|
||||
final String? description;
|
||||
final String? contactEmail;
|
||||
final String? contactPhone;
|
||||
final String? address;
|
||||
final String? website;
|
||||
final Map<String, dynamic>? customFields;
|
||||
final Map<String, dynamic>? notificationSettings;
|
||||
final Map<String, dynamic>? privacySettings;
|
||||
final DateTime createdAt;
|
||||
final DateTime updatedAt;
|
||||
|
||||
ClubSettings({
|
||||
required this.clubId,
|
||||
required this.clubName,
|
||||
this.logoUrl,
|
||||
this.bannerUrl,
|
||||
this.description,
|
||||
this.contactEmail,
|
||||
this.contactPhone,
|
||||
this.address,
|
||||
this.website,
|
||||
this.customFields,
|
||||
this.notificationSettings,
|
||||
this.privacySettings,
|
||||
required this.createdAt,
|
||||
required this.updatedAt,
|
||||
});
|
||||
|
||||
/// JSON에서 클럽 설정 객체 생성
|
||||
factory ClubSettings.fromJson(Map<String, dynamic> json) {
|
||||
return ClubSettings(
|
||||
clubId: json['clubId'],
|
||||
clubName: json['clubName'],
|
||||
logoUrl: json['logoUrl'],
|
||||
bannerUrl: json['bannerUrl'],
|
||||
description: json['description'],
|
||||
contactEmail: json['contactEmail'],
|
||||
contactPhone: json['contactPhone'],
|
||||
address: json['address'],
|
||||
website: json['website'],
|
||||
customFields: json['customFields'],
|
||||
notificationSettings: json['notificationSettings'],
|
||||
privacySettings: json['privacySettings'],
|
||||
createdAt: DateTime.parse(json['createdAt']),
|
||||
updatedAt: DateTime.parse(json['updatedAt']),
|
||||
);
|
||||
}
|
||||
|
||||
/// 클럽 설정 객체를 JSON으로 변환
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'clubId': clubId,
|
||||
'clubName': clubName,
|
||||
'logoUrl': logoUrl,
|
||||
'bannerUrl': bannerUrl,
|
||||
'description': description,
|
||||
'contactEmail': contactEmail,
|
||||
'contactPhone': contactPhone,
|
||||
'address': address,
|
||||
'website': website,
|
||||
'customFields': customFields,
|
||||
'notificationSettings': notificationSettings,
|
||||
'privacySettings': privacySettings,
|
||||
'createdAt': createdAt.toIso8601String(),
|
||||
'updatedAt': updatedAt.toIso8601String(),
|
||||
};
|
||||
}
|
||||
|
||||
/// 복사본 생성 (일부 필드 업데이트)
|
||||
ClubSettings copyWith({
|
||||
String? clubName,
|
||||
String? logoUrl,
|
||||
String? bannerUrl,
|
||||
String? description,
|
||||
String? contactEmail,
|
||||
String? contactPhone,
|
||||
String? address,
|
||||
String? website,
|
||||
Map<String, dynamic>? customFields,
|
||||
Map<String, dynamic>? notificationSettings,
|
||||
Map<String, dynamic>? privacySettings,
|
||||
}) {
|
||||
return ClubSettings(
|
||||
clubId: clubId,
|
||||
clubName: clubName ?? this.clubName,
|
||||
logoUrl: logoUrl ?? this.logoUrl,
|
||||
bannerUrl: bannerUrl ?? this.bannerUrl,
|
||||
description: description ?? this.description,
|
||||
contactEmail: contactEmail ?? this.contactEmail,
|
||||
contactPhone: contactPhone ?? this.contactPhone,
|
||||
address: address ?? this.address,
|
||||
website: website ?? this.website,
|
||||
customFields: customFields ?? this.customFields,
|
||||
notificationSettings: notificationSettings ?? this.notificationSettings,
|
||||
privacySettings: privacySettings ?? this.privacySettings,
|
||||
createdAt: createdAt,
|
||||
updatedAt: DateTime.now(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
class Club {
|
||||
final String id;
|
||||
final String name;
|
||||
final String? description;
|
||||
final String? logo;
|
||||
final String? address;
|
||||
final String? location;
|
||||
final String? phone;
|
||||
final String? email;
|
||||
final String? website;
|
||||
final int? memberCount;
|
||||
final String? ownerId;
|
||||
final int? femaleHandicap;
|
||||
final String? averageCalculationPeriod;
|
||||
final DateTime? createdAt;
|
||||
final DateTime? updatedAt;
|
||||
|
||||
Club({
|
||||
required this.id,
|
||||
required this.name,
|
||||
this.description,
|
||||
this.logo,
|
||||
this.address,
|
||||
this.location,
|
||||
this.phone,
|
||||
this.email,
|
||||
this.website,
|
||||
this.memberCount,
|
||||
this.ownerId,
|
||||
this.femaleHandicap,
|
||||
this.averageCalculationPeriod,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
});
|
||||
|
||||
// JSON 데이터로부터 Club 객체 생성
|
||||
factory Club.fromJson(Map<String, dynamic> json) {
|
||||
return Club(
|
||||
id: json['id'] != null ? json['id'].toString() : '',
|
||||
name: json['name'] ?? '',
|
||||
description: json['description'],
|
||||
logo: json['logo'],
|
||||
address: json['address'],
|
||||
location: json['location'],
|
||||
phone: json['phone'] ?? json['contact'], // contact 필드도 확인
|
||||
email: json['email'],
|
||||
website: json['website'],
|
||||
memberCount: json['memberCount'],
|
||||
ownerId: json['ownerId']?.toString(),
|
||||
femaleHandicap: json['femaleHandicap'] != null ? int.tryParse(json['femaleHandicap'].toString()) : null,
|
||||
averageCalculationPeriod: json['averageCalculationPeriod'],
|
||||
createdAt: json['createdAt'] != null ? DateTime.parse(json['createdAt']) : null,
|
||||
updatedAt: json['updatedAt'] != null ? DateTime.parse(json['updatedAt']) : null,
|
||||
);
|
||||
}
|
||||
|
||||
// Club 객체를 JSON으로 변환
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'id': id,
|
||||
'name': name,
|
||||
'description': description,
|
||||
'logo': logo,
|
||||
'address': address,
|
||||
'location': location,
|
||||
'phone': phone,
|
||||
'email': email,
|
||||
'website': website,
|
||||
'memberCount': memberCount,
|
||||
'ownerId': ownerId,
|
||||
'femaleHandicap': femaleHandicap,
|
||||
'averageCalculationPeriod': averageCalculationPeriod,
|
||||
'createdAt': createdAt?.toIso8601String(),
|
||||
'updatedAt': updatedAt?.toIso8601String(),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
class Event {
|
||||
final String id;
|
||||
final String clubId;
|
||||
final String title;
|
||||
final String? description;
|
||||
final DateTime startDate;
|
||||
final DateTime? endDate;
|
||||
final String? location;
|
||||
final String? type;
|
||||
final int? maxParticipants;
|
||||
final int? currentParticipants;
|
||||
final bool isActive;
|
||||
final String? createdBy;
|
||||
final DateTime? createdAt;
|
||||
final DateTime? updatedAt;
|
||||
|
||||
Event({
|
||||
required this.id,
|
||||
required this.clubId,
|
||||
required this.title,
|
||||
this.description,
|
||||
required this.startDate,
|
||||
this.endDate,
|
||||
this.location,
|
||||
this.type,
|
||||
this.maxParticipants,
|
||||
this.currentParticipants,
|
||||
required this.isActive,
|
||||
this.createdBy,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
});
|
||||
|
||||
// JSON 데이터로부터 Event 객체 생성
|
||||
factory Event.fromJson(Map<String, dynamic> json) {
|
||||
return Event(
|
||||
id: json['id']?.toString() ?? '',
|
||||
clubId: json['clubId']?.toString() ?? '',
|
||||
title: json['title'] ?? '',
|
||||
description: json['description']?.toString(),
|
||||
startDate: json['startDate'] != null ? DateTime.parse(json['startDate'].toString()) : DateTime.now(),
|
||||
endDate: json['endDate'] != null ? DateTime.parse(json['endDate'].toString()) : null,
|
||||
location: json['location']?.toString(),
|
||||
type: json['type']?.toString(),
|
||||
maxParticipants: json['maxParticipants'],
|
||||
currentParticipants: json['currentParticipants'],
|
||||
isActive: json['isActive'] ?? true,
|
||||
createdBy: json['createdBy']?.toString(),
|
||||
createdAt: json['createdAt'] != null ? DateTime.parse(json['createdAt'].toString()) : null,
|
||||
updatedAt: json['updatedAt'] != null ? DateTime.parse(json['updatedAt'].toString()) : null,
|
||||
);
|
||||
}
|
||||
|
||||
// Event 객체를 JSON으로 변환
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'id': id,
|
||||
'clubId': clubId,
|
||||
'title': title,
|
||||
'description': description,
|
||||
'startDate': startDate.toIso8601String(),
|
||||
'endDate': endDate?.toIso8601String(),
|
||||
'location': location,
|
||||
'type': type,
|
||||
'maxParticipants': maxParticipants,
|
||||
'currentParticipants': currentParticipants,
|
||||
'isActive': isActive,
|
||||
'createdBy': createdBy,
|
||||
'createdAt': createdAt?.toIso8601String(),
|
||||
'updatedAt': updatedAt?.toIso8601String(),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
class Member {
|
||||
final String id;
|
||||
final String userId;
|
||||
final String clubId;
|
||||
final String name;
|
||||
final String email;
|
||||
final String? role;
|
||||
final String? profileImage;
|
||||
final String? phone;
|
||||
final String? address;
|
||||
final DateTime? joinDate;
|
||||
final bool isActive;
|
||||
final String? gender;
|
||||
final String? memberType;
|
||||
final int? handicap;
|
||||
final String? status;
|
||||
final DateTime? createdAt;
|
||||
final DateTime? updatedAt;
|
||||
|
||||
Member({
|
||||
required this.id,
|
||||
required this.userId,
|
||||
required this.clubId,
|
||||
required this.name,
|
||||
required this.email,
|
||||
this.role,
|
||||
this.profileImage,
|
||||
this.phone,
|
||||
this.address,
|
||||
this.joinDate,
|
||||
required this.isActive,
|
||||
this.gender,
|
||||
this.memberType,
|
||||
this.handicap,
|
||||
this.status,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
});
|
||||
|
||||
// JSON 데이터로부터 Member 객체 생성
|
||||
factory Member.fromJson(Map<String, dynamic> json) {
|
||||
return Member(
|
||||
id: json['id']?.toString() ?? '',
|
||||
userId: json['userId']?.toString() ?? '',
|
||||
clubId: json['clubId']?.toString() ?? '',
|
||||
name: json['name'] ?? '',
|
||||
email: json['email'] ?? '',
|
||||
role: json['role']?.toString(),
|
||||
profileImage: json['profileImage']?.toString(),
|
||||
phone: json['phone']?.toString(),
|
||||
address: json['address']?.toString(),
|
||||
joinDate: json['joinDate'] != null ? DateTime.parse(json['joinDate'].toString()) : null,
|
||||
isActive: json['isActive'] ?? true,
|
||||
gender: json['gender']?.toString(),
|
||||
memberType: json['memberType']?.toString(),
|
||||
handicap: json['handicap'] != null ? int.tryParse(json['handicap'].toString()) : null,
|
||||
status: json['status']?.toString(),
|
||||
createdAt: json['createdAt'] != null ? DateTime.parse(json['createdAt'].toString()) : null,
|
||||
updatedAt: json['updatedAt'] != null ? DateTime.parse(json['updatedAt'].toString()) : null,
|
||||
);
|
||||
}
|
||||
|
||||
// Member 객체를 JSON으로 변환
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'id': id,
|
||||
'userId': userId,
|
||||
'clubId': clubId,
|
||||
'name': name,
|
||||
'email': email,
|
||||
'role': role,
|
||||
'profileImage': profileImage,
|
||||
'phone': phone,
|
||||
'address': address,
|
||||
'joinDate': joinDate?.toIso8601String(),
|
||||
'isActive': isActive,
|
||||
'gender': gender,
|
||||
'memberType': memberType,
|
||||
'handicap': handicap,
|
||||
'status': status,
|
||||
'createdAt': createdAt?.toIso8601String(),
|
||||
'updatedAt': updatedAt?.toIso8601String(),
|
||||
};
|
||||
}
|
||||
|
||||
// 객체 복사 및 특정 필드 업데이트를 위한 copyWith 메서드
|
||||
Member copyWith({
|
||||
String? id,
|
||||
String? userId,
|
||||
String? clubId,
|
||||
String? name,
|
||||
String? email,
|
||||
String? role,
|
||||
String? profileImage,
|
||||
String? phone,
|
||||
String? address,
|
||||
DateTime? joinDate,
|
||||
bool? isActive,
|
||||
String? gender,
|
||||
String? memberType,
|
||||
int? handicap,
|
||||
String? status,
|
||||
DateTime? createdAt,
|
||||
DateTime? updatedAt,
|
||||
}) {
|
||||
return Member(
|
||||
id: id ?? this.id,
|
||||
userId: userId ?? this.userId,
|
||||
clubId: clubId ?? this.clubId,
|
||||
name: name ?? this.name,
|
||||
email: email ?? this.email,
|
||||
role: role ?? this.role,
|
||||
profileImage: profileImage ?? this.profileImage,
|
||||
phone: phone ?? this.phone,
|
||||
address: address ?? this.address,
|
||||
joinDate: joinDate ?? this.joinDate,
|
||||
isActive: isActive ?? this.isActive,
|
||||
gender: gender ?? this.gender,
|
||||
memberType: memberType ?? this.memberType,
|
||||
handicap: handicap ?? this.handicap,
|
||||
status: status ?? this.status,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
updatedAt: updatedAt ?? this.updatedAt,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
class Score {
|
||||
final String id;
|
||||
final String memberId;
|
||||
final String eventId;
|
||||
final String clubId;
|
||||
final List<int> frames;
|
||||
final int totalScore;
|
||||
final DateTime date;
|
||||
final String? notes;
|
||||
|
||||
Score({
|
||||
required this.id,
|
||||
required this.memberId,
|
||||
required this.eventId,
|
||||
required this.clubId,
|
||||
required this.frames,
|
||||
required this.totalScore,
|
||||
required this.date,
|
||||
this.notes,
|
||||
});
|
||||
|
||||
factory Score.fromJson(Map<String, dynamic> json) {
|
||||
return Score(
|
||||
id: json['id']?.toString() ?? '',
|
||||
memberId: json['memberId']?.toString() ?? '',
|
||||
eventId: json['eventId']?.toString() ?? '',
|
||||
clubId: json['clubId']?.toString() ?? '',
|
||||
frames: json['frames'] != null ? List<int>.from(json['frames']) : [],
|
||||
totalScore: json['totalScore'] ?? 0,
|
||||
date: json['date'] != null ? DateTime.parse(json['date'].toString()) : DateTime.now(),
|
||||
notes: json['notes']?.toString(),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'id': id,
|
||||
'memberId': memberId,
|
||||
'eventId': eventId,
|
||||
'clubId': clubId,
|
||||
'frames': frames,
|
||||
'totalScore': totalScore,
|
||||
'date': date.toIso8601String(),
|
||||
'notes': notes,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class ScoreStatistics {
|
||||
final double average;
|
||||
final int highScore;
|
||||
final int lowScore;
|
||||
final int gamesPlayed;
|
||||
final Map<String, dynamic>? additionalStats;
|
||||
|
||||
ScoreStatistics({
|
||||
required this.average,
|
||||
required this.highScore,
|
||||
required this.lowScore,
|
||||
required this.gamesPlayed,
|
||||
this.additionalStats,
|
||||
});
|
||||
|
||||
factory ScoreStatistics.fromJson(Map<String, dynamic> json) {
|
||||
return ScoreStatistics(
|
||||
average: json['average'] != null ? (json['average'] is int ? (json['average'] as int).toDouble() : json['average'].toDouble()) : 0.0,
|
||||
highScore: json['highScore'] ?? 0,
|
||||
lowScore: json['lowScore'] ?? 0,
|
||||
gamesPlayed: json['gamesPlayed'] ?? 0,
|
||||
additionalStats: json['additionalStats'],
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'average': average,
|
||||
'highScore': highScore,
|
||||
'lowScore': lowScore,
|
||||
'gamesPlayed': gamesPlayed,
|
||||
'additionalStats': additionalStats,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
|
||||
/// 구독 플랜 타입
|
||||
enum SubscriptionPlanType {
|
||||
free, // 무료 플랜
|
||||
basic, // 기본 유료 플랜
|
||||
premium, // 프리미엄 플랜
|
||||
enterprise // 기업용 플랜
|
||||
}
|
||||
|
||||
/// 구독 상태
|
||||
enum SubscriptionStatus {
|
||||
active, // 활성화 상태
|
||||
canceled, // 취소됨 (아직 만료 안됨)
|
||||
expired, // 만료됨
|
||||
pending, // 결제 대기 중
|
||||
failed // 결제 실패
|
||||
}
|
||||
|
||||
/// 구독 모델
|
||||
class Subscription {
|
||||
final String id;
|
||||
final String userId;
|
||||
final String? clubId;
|
||||
final SubscriptionPlanType planType;
|
||||
final SubscriptionStatus status;
|
||||
final DateTime startDate;
|
||||
final DateTime endDate;
|
||||
final double price;
|
||||
final String currency;
|
||||
final bool autoRenew;
|
||||
final Map<String, dynamic>? features;
|
||||
final String? paymentMethod;
|
||||
final String? transactionId;
|
||||
final DateTime createdAt;
|
||||
final DateTime updatedAt;
|
||||
|
||||
Subscription({
|
||||
required this.id,
|
||||
required this.userId,
|
||||
this.clubId,
|
||||
required this.planType,
|
||||
required this.status,
|
||||
required this.startDate,
|
||||
required this.endDate,
|
||||
required this.price,
|
||||
required this.currency,
|
||||
required this.autoRenew,
|
||||
this.features,
|
||||
this.paymentMethod,
|
||||
this.transactionId,
|
||||
required this.createdAt,
|
||||
required this.updatedAt,
|
||||
});
|
||||
|
||||
/// JSON에서 구독 객체 생성
|
||||
factory Subscription.fromJson(Map<String, dynamic> json) {
|
||||
return Subscription(
|
||||
id: json['id'],
|
||||
userId: json['userId'],
|
||||
clubId: json['clubId'],
|
||||
planType: SubscriptionPlanType.values.firstWhere(
|
||||
(e) => e.toString().split('.').last == json['planType'],
|
||||
orElse: () => SubscriptionPlanType.free,
|
||||
),
|
||||
status: SubscriptionStatus.values.firstWhere(
|
||||
(e) => e.toString().split('.').last == json['status'],
|
||||
orElse: () => SubscriptionStatus.expired,
|
||||
),
|
||||
startDate: DateTime.parse(json['startDate']),
|
||||
endDate: DateTime.parse(json['endDate']),
|
||||
price: json['price'].toDouble(),
|
||||
currency: json['currency'],
|
||||
autoRenew: json['autoRenew'] ?? false,
|
||||
features: json['features'],
|
||||
paymentMethod: json['paymentMethod'],
|
||||
transactionId: json['transactionId'],
|
||||
createdAt: DateTime.parse(json['createdAt']),
|
||||
updatedAt: DateTime.parse(json['updatedAt']),
|
||||
);
|
||||
}
|
||||
|
||||
/// 구독 객체를 JSON으로 변환
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'id': id,
|
||||
'userId': userId,
|
||||
'clubId': clubId,
|
||||
'planType': planType.toString().split('.').last,
|
||||
'status': status.toString().split('.').last,
|
||||
'startDate': startDate.toIso8601String(),
|
||||
'endDate': endDate.toIso8601String(),
|
||||
'price': price,
|
||||
'currency': currency,
|
||||
'autoRenew': autoRenew,
|
||||
'features': features,
|
||||
'paymentMethod': paymentMethod,
|
||||
'transactionId': transactionId,
|
||||
'createdAt': createdAt.toIso8601String(),
|
||||
'updatedAt': updatedAt.toIso8601String(),
|
||||
};
|
||||
}
|
||||
|
||||
/// 구독이 활성 상태인지 확인
|
||||
bool get isActive => status == SubscriptionStatus.active;
|
||||
|
||||
/// 구독이 만료되었는지 확인
|
||||
bool get isExpired => status == SubscriptionStatus.expired ||
|
||||
DateTime.now().isAfter(endDate);
|
||||
|
||||
/// 구독 남은 일수 계산
|
||||
int get daysLeft {
|
||||
if (isExpired) return 0;
|
||||
return endDate.difference(DateTime.now()).inDays;
|
||||
}
|
||||
|
||||
/// 구독 플랜 이름 (한글)
|
||||
String get planName {
|
||||
switch (planType) {
|
||||
case SubscriptionPlanType.free:
|
||||
return '무료';
|
||||
case SubscriptionPlanType.basic:
|
||||
return '기본';
|
||||
case SubscriptionPlanType.premium:
|
||||
return '프리미엄';
|
||||
case SubscriptionPlanType.enterprise:
|
||||
return '기업용';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 구독 플랜 정보 모델
|
||||
class SubscriptionPlan {
|
||||
final SubscriptionPlanType type;
|
||||
final String name;
|
||||
final String description;
|
||||
final double monthlyPrice;
|
||||
final double yearlyPrice;
|
||||
final String currency;
|
||||
final List<String> features;
|
||||
final int maxMembers;
|
||||
final int maxEvents;
|
||||
final bool hasAdvancedStats;
|
||||
final bool hasCustomization;
|
||||
final bool hasPriority;
|
||||
|
||||
SubscriptionPlan({
|
||||
required this.type,
|
||||
required this.name,
|
||||
required this.description,
|
||||
required this.monthlyPrice,
|
||||
required this.yearlyPrice,
|
||||
required this.currency,
|
||||
required this.features,
|
||||
required this.maxMembers,
|
||||
required this.maxEvents,
|
||||
required this.hasAdvancedStats,
|
||||
required this.hasCustomization,
|
||||
required this.hasPriority,
|
||||
});
|
||||
|
||||
/// 기본 구독 플랜 목록 반환
|
||||
static List<SubscriptionPlan> getDefaultPlans() {
|
||||
return [
|
||||
SubscriptionPlan(
|
||||
type: SubscriptionPlanType.free,
|
||||
name: '무료',
|
||||
description: '소규모 클럽을 위한 기본 기능',
|
||||
monthlyPrice: 0,
|
||||
yearlyPrice: 0,
|
||||
currency: 'KRW',
|
||||
features: [
|
||||
'최대 10명 회원 관리',
|
||||
'기본 점수 기록',
|
||||
'간단한 통계',
|
||||
],
|
||||
maxMembers: 10,
|
||||
maxEvents: 5,
|
||||
hasAdvancedStats: false,
|
||||
hasCustomization: false,
|
||||
hasPriority: false,
|
||||
),
|
||||
SubscriptionPlan(
|
||||
type: SubscriptionPlanType.basic,
|
||||
name: '기본',
|
||||
description: '중소규모 클럽을 위한 확장 기능',
|
||||
monthlyPrice: 9900,
|
||||
yearlyPrice: 99000,
|
||||
currency: 'KRW',
|
||||
features: [
|
||||
'최대 30명 회원 관리',
|
||||
'상세 점수 분석',
|
||||
'이벤트 관리',
|
||||
'회원 통계',
|
||||
],
|
||||
maxMembers: 30,
|
||||
maxEvents: 20,
|
||||
hasAdvancedStats: true,
|
||||
hasCustomization: false,
|
||||
hasPriority: false,
|
||||
),
|
||||
SubscriptionPlan(
|
||||
type: SubscriptionPlanType.premium,
|
||||
name: '프리미엄',
|
||||
description: '대규모 클럽을 위한 고급 기능',
|
||||
monthlyPrice: 19900,
|
||||
yearlyPrice: 199000,
|
||||
currency: 'KRW',
|
||||
features: [
|
||||
'무제한 회원 관리',
|
||||
'고급 통계 및 분석',
|
||||
'무제한 이벤트',
|
||||
'맞춤형 보고서',
|
||||
'우선 지원',
|
||||
],
|
||||
maxMembers: 100,
|
||||
maxEvents: 100,
|
||||
hasAdvancedStats: true,
|
||||
hasCustomization: true,
|
||||
hasPriority: true,
|
||||
),
|
||||
SubscriptionPlan(
|
||||
type: SubscriptionPlanType.enterprise,
|
||||
name: '기업용',
|
||||
description: '프로 클럽 및 단체를 위한 맞춤형 솔루션',
|
||||
monthlyPrice: 49900,
|
||||
yearlyPrice: 499000,
|
||||
currency: 'KRW',
|
||||
features: [
|
||||
'무제한 회원 및 이벤트',
|
||||
'전문가 수준 분석',
|
||||
'맞춤형 기능',
|
||||
'전담 지원',
|
||||
'API 액세스',
|
||||
],
|
||||
maxMembers: 1000,
|
||||
maxEvents: 1000,
|
||||
hasAdvancedStats: true,
|
||||
hasCustomization: true,
|
||||
hasPriority: true,
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
class User {
|
||||
final String id;
|
||||
final String email;
|
||||
final String name;
|
||||
final String role;
|
||||
final String? profileImage;
|
||||
final String? clubId;
|
||||
final String? clubRole;
|
||||
|
||||
User({
|
||||
required this.id,
|
||||
required this.email,
|
||||
required this.name,
|
||||
required this.role,
|
||||
this.profileImage,
|
||||
this.clubId,
|
||||
this.clubRole,
|
||||
});
|
||||
|
||||
// JSON 데이터로부터 User 객체 생성
|
||||
factory User.fromJson(Map<String, dynamic> json) {
|
||||
return User(
|
||||
id: json['id'] != null ? json['id'].toString() : '',
|
||||
email: json['email'] ?? '',
|
||||
name: json['name'] ?? '',
|
||||
role: json['role'] ?? 'user',
|
||||
profileImage: json['profileImage'],
|
||||
clubId: json['clubId']?.toString(),
|
||||
clubRole: json['clubRole'],
|
||||
);
|
||||
}
|
||||
|
||||
// User 객체를 JSON으로 변환
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'id': id,
|
||||
'email': email,
|
||||
'name': name,
|
||||
'role': role,
|
||||
'profileImage': profileImage,
|
||||
'clubId': clubId,
|
||||
'clubRole': clubRole,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user