import 'package:get/get.dart'; import 'package:hgdj/hj_model/splash/domain_source_model.dart'; import '../../hj_page/main_page/provider/msg_provider.dart'; import 'guide_config.dart'; /// 付费引导开关(全站唯一数据源) /// /// 配置随 /ping/domain 及 /ping/domain/refresh?keys=paymentGuide 下发后缓存在内存, /// 首页/播放页/会员中心触发时直接读,不再临时请求接口。 /// /// 弹不弹只认后端下发的 enabled && show:本地不去重、不改这两个值、也不上报曝光, /// 触发几次弹几次,要收敛得由后端把 show 改成 false;没下发配置则一律不弹。 /// (VIP_CONTENT_UPDATE 不归这里管,它走独立接口 + 曝光回执,见 GuidePushBanner) class GuideManager { static final GuideManager _instance = GuideManager._(); factory GuideManager() => _instance; GuideManager._(); GuideConfig? _config; /// ping / ping refresh 下发时写入。字段缺失(后端未下发)时保留上一次配置,不清空 void update(dynamic json) { if (json is! Map) return; _config = GuideConfig.fromJson(Map.from(json)); } /// 场景配置:全局开关关掉、场景没配或没启用都返回 null GuideSceneConfig? configOf(GuideScene scene) { final all = _config; if (all == null || !all.enabled) return null; final config = all.scenes[scene]; return config?.enabled == true ? config : null; } /// 能不能弹:全局开关 + 场景启用([configOf])之外,还要后端本次放行 bool canShow(GuideScene scene) => configOf(scene)?.show == true; /// 首页新/老用户二选一:**按本地分层选**,newUnpay 走新用户场景,其余走老用户; /// 选中的那个不可展示就不弹,不回退到另一个——分层不匹配的文案给错人比不弹更糟。 /// (以前只按 show 挑,后端两个都下发 true 时老用户会命中新人场景) /// /// ⚠️ 分层为 null 时必须退回按 show 挑,不能当成老用户:payTier 由 MainLogic.onInit 的 /// refreshPayPopup 异步拉,而本 getter 在首帧后的弹窗链里就被读了——首页没别的弹窗时 /// 请求还没回来,硬判成老用户会让新用户永远错过新人引导,且 _adShown 保证不会再有第二次 GuideScene? get homeScene { final tier = MineMsgProvider().payTier?.status; if (tier == null) return [GuideScene.homeNewUser, GuideScene.homeOldUser] .firstWhereOrNull(canShow); final scene = tier == PayTier.newUnpay ? GuideScene.homeNewUser : GuideScene.homeOldUser; return canShow(scene) ? scene : null; } }