244 lines
6.7 KiB
Dart
244 lines
6.7 KiB
Dart
|
|
/// 구독 플랜 타입
|
|
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,
|
|
),
|
|
];
|
|
}
|
|
}
|