From ef42602c7c2324c9984dad45282b5e81e99f3dc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=96=8C?= <259278618@qq.com> Date: Fri, 31 Jul 2026 13:47:11 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=B9=BF=E5=91=8A=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E6=8A=BD=E8=B1=A1=EF=BC=88Mock=20=E6=BF=80=E5=8A=B1=E8=A7=86?= =?UTF-8?q?=E9=A2=91=EF=BC=89+=20url=5Flauncher=20=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/core/ads/ads_service.dart | 24 +++++++++ lib/features/member/member_provider.dart | 25 +++++++++ pubspec.lock | 64 ++++++++++++++++++++++++ pubspec.yaml | 1 + test/features/member/benefits_test.dart | 24 +++++++++ 5 files changed, 138 insertions(+) create mode 100644 lib/core/ads/ads_service.dart create mode 100644 lib/features/member/member_provider.dart create mode 100644 test/features/member/benefits_test.dart diff --git a/lib/core/ads/ads_service.dart b/lib/core/ads/ads_service.dart new file mode 100644 index 0000000..5e6a968 --- /dev/null +++ b/lib/core/ads/ads_service.dart @@ -0,0 +1,24 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +/// 广告服务抽象:P0 用 Mock(保证业务链路可开发可测),P1 换穿山甲 SDK +abstract class AdsService { + bool get enabled; + Future showRewarded(); +} + +/// 本地模拟激励视频(约 1 秒"播放"后返回完整观看) +class MockAdsService implements AdsService { + @override + bool get enabled => true; + + @override + Future showRewarded() async { + await Future.delayed(const Duration(milliseconds: 900)); + return true; + } +} + +final adsServiceProvider = Provider((ref) { + // P1:AppConfig.pangleAppId 非空时替换为 PangleAdsService(穿山甲 SDK 实现) + return MockAdsService(); +}); diff --git a/lib/features/member/member_provider.dart b/lib/features/member/member_provider.dart new file mode 100644 index 0000000..27ec83c --- /dev/null +++ b/lib/features/member/member_provider.dart @@ -0,0 +1,25 @@ +/// 会员 provider:Task 1 仅含权益文案纯函数(Task 2 将补全状态/套餐/下单/轮询/领奖) +class MemberInfo { + final bool isVip; + final String expireAt; + final String planName; + final List benefits; + + const MemberInfo({ + required this.isVip, + required this.expireAt, + required this.planName, + required this.benefits, + }); +} + +/// 权益 key → 文案 +const benefitLabels = { + 'effect_unlimited': '无限效果图', + 'ai_priority': '优先 AI 方案', + 'cps_commission_x15': '返现加成 1.5x', + 'store_discount': '门店折扣', +}; + +List benefitTexts(MemberInfo m) => + m.benefits.map((b) => benefitLabels[b] ?? b).toList(); diff --git a/pubspec.lock b/pubspec.lock index ee95cb4..ff5d852 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -717,6 +717,70 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.0" + url_launcher: + dependency: "direct main" + description: + name: url_launcher + sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8 + url: "https://pub.dev" + source: hosted + version: "6.3.2" + url_launcher_android: + dependency: transitive + description: + name: url_launcher_android + sha256: b413d49b73867ac08dd2f9890efd3cc11f2a0e577618d50843440a1fb3776c32 + url: "https://pub.dev" + source: hosted + version: "6.3.32" + url_launcher_ios: + dependency: transitive + description: + name: url_launcher_ios + sha256: "580fe5dfb51671ae38191d316e027f6b76272b026370708c2d898799750a02b0" + url: "https://pub.dev" + source: hosted + version: "6.4.1" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + sha256: d5e14138b3bc193a0f63c10a53c94b91d399df0512b1f29b94a043db7482384a + url: "https://pub.dev" + source: hosted + version: "3.2.2" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18" + url: "https://pub.dev" + source: hosted + version: "3.2.5" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + sha256: "85c81589622fbc87c1c683aaea164d3604a7777495a79d91e39ffcdec39ddb34" + url: "https://pub.dev" + source: hosted + version: "2.4.3" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + sha256: "712c70ab1b99744ff066053cbe3e80c73332b38d46e5e945c98689b2e66fc15f" + url: "https://pub.dev" + source: hosted + version: "3.1.5" uuid: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 686a027..e05ebb9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -40,6 +40,7 @@ dependencies: image_picker: ^1.2.3 shared_preferences: ^2.5.5 fluttertoast: ^9.1.0 + url_launcher: ^6.3.0 # v2 3D 渲染接入时引入:three_dart ^0.0.16 + three_dart_jsm ^0.0.10 + flutter_gl ^0.0.20 # (flutter_gl 0.0.21 在 Flutter 3.44 下无法编译:platformViewRegistry 已移除) diff --git a/test/features/member/benefits_test.dart b/test/features/member/benefits_test.dart new file mode 100644 index 0000000..4a10a15 --- /dev/null +++ b/test/features/member/benefits_test.dart @@ -0,0 +1,24 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:slogan_app/features/member/member_provider.dart'; + +void main() { + test('benefitTexts 映射已知权益文案,未知 key 原样保留', () { + final info = MemberInfo( + isVip: true, + expireAt: '2026-08-30 12:00:00', + planName: '月卡', + benefits: const ['effect_unlimited', 'unknown_key'], + ); + expect(benefitTexts(info), ['无限效果图', 'unknown_key']); + }); + + test('benefitTexts 空权益返回空列表', () { + final info = MemberInfo( + isVip: false, + expireAt: '', + planName: '', + benefits: const [], + ); + expect(benefitTexts(info), isEmpty); + }); +}