初始化
This commit is contained in:
@@ -0,0 +1,286 @@
|
||||
import 'package:get/get.dart';
|
||||
import 'package:hgdj/hj_model/video_model.dart';
|
||||
import 'package:hgdj/hj_page/pre_sale/pre_sale_page.dart';
|
||||
import 'package:hgdj/hj_page/pre_sale/pre_sale_provider.dart';
|
||||
import 'package:hgdj/hj_page/user_center_page/user_center_page.dart';
|
||||
import 'package:hgdj/hj_page/video/video_page.dart';
|
||||
import 'package:hgdj/tools_base/debug_log.dart';
|
||||
import 'package:hgdj/tools_base/event_bus/events.dart';
|
||||
import 'package:hgdj/tools_base/headphone_monitor.dart';
|
||||
import 'package:hgdj/tools_base/loading/loading_helper.dart';
|
||||
import 'package:hgdj/tools_base/toast.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
import '../config/address.dart';
|
||||
import '../config/config.dart';
|
||||
import '../hj_model/cartoon_media_info.dart';
|
||||
import '../hj_page/cartoon/cartoon_detail_page.dart';
|
||||
import '../hj_page/cartoon/novel_detail_page.dart';
|
||||
import '../hj_page/community/post_detail_page/post_detail_page.dart';
|
||||
import '../hj_page/community/publish_page/publish_page.dart';
|
||||
import '../hj_page/find/acg_game_detail_page.dart';
|
||||
import '../hj_page/find/rank_module/rank_main_page.dart';
|
||||
import '../hj_page/mine/mine_setting/bing_phone_page.dart';
|
||||
import '../hj_page/mine/mine_share/mine_share_page.dart';
|
||||
import '../hj_page/mine/mine_vip/mine_charge_coin_page.dart';
|
||||
import '../hj_page/mine/mine_vip/mine_charge_vip_page.dart';
|
||||
import '../hj_page/mine/mine_vip/pay_order_source.dart';
|
||||
import '../hj_page/mine/welfare/welfare_home_page.dart';
|
||||
import '../hj_page/short_video/short_video_page.dart';
|
||||
import '../hj_page/web_page/h5_page.dart';
|
||||
import '../hj_utils/api_service/mine_service.dart';
|
||||
import '../hj_utils/api_service/vid_service.dart';
|
||||
import '../tools_base/event_bus/event_bus_util.dart';
|
||||
import '../tools_base/loading/loading_alert_widget.dart';
|
||||
|
||||
/// 跳转视频/动漫/短视频详情页
|
||||
/// - [isCartoon] 优先级最高 → 长视频页(标记动漫)
|
||||
/// - newsType == SEED_LINK → ACG 游戏详情页
|
||||
/// - playTime < 300 且非 0 → 短视频
|
||||
/// - 其余 → 长视频
|
||||
/// - [videoModel] / [videoId] 必传其一
|
||||
Future? pushToVideoPage({
|
||||
String? videoId,
|
||||
VideoModel? videoModel,
|
||||
bool isCartoon = false,
|
||||
String? videoCover,
|
||||
List<VideoModel>? videoArr,
|
||||
}) {
|
||||
// 1. 动漫优先:跳长视频
|
||||
if (isCartoon) {
|
||||
return Get.to(
|
||||
() => VideoPage(
|
||||
id: videoModel?.id ?? videoId,
|
||||
isCartoon: true,
|
||||
videoCover: videoCover ?? videoModel?.cover,
|
||||
),
|
||||
preventDuplicates: false,
|
||||
);
|
||||
}
|
||||
|
||||
// 2. SEED_LINK:跳 ACG 游戏详情
|
||||
if (videoModel?.newsType == 'SEED_LINK') {
|
||||
return Get.to(() => AcgGameDetailPage(id: videoModel?.id ?? ''),
|
||||
preventDuplicates: false);
|
||||
}
|
||||
|
||||
// 3. 短视频:playTime < 300 且非 0(此分支 videoModel 必非 null,playTime 取自它)
|
||||
final playTime = videoModel?.playTime ?? 1000;
|
||||
if (playTime < 300 && playTime != 0) {
|
||||
final list = videoArr?.isNotEmpty == true ? videoArr! : [videoModel!];
|
||||
final idx = list.indexWhere((e) => e.id == videoModel?.id);
|
||||
return Get.to(
|
||||
() => ShortVideoPage(
|
||||
type: VideoListType.SECOND,
|
||||
videoList: list,
|
||||
pageIndex: idx < 0 ? 0 : idx,
|
||||
),
|
||||
preventDuplicates: false,
|
||||
);
|
||||
}
|
||||
|
||||
// 4. 默认:长视频
|
||||
return Get.to(() => VideoPage(
|
||||
id: videoId ?? videoModel?.id,
|
||||
videoCover: videoCover ?? videoModel?.cover,
|
||||
model: videoModel,
|
||||
));
|
||||
}
|
||||
|
||||
/// 跳转卡通详情:按 mediaType 分发
|
||||
void pushToCartoonPage(CartoonMediaInfo? info) {
|
||||
switch (info?.mediaType) {
|
||||
case 'image':
|
||||
Get.to(
|
||||
CartoonDetailPage(id: info?.id ?? '', heroTag: info?.heroTag),
|
||||
preventDuplicates: false,
|
||||
);
|
||||
return;
|
||||
case 'text':
|
||||
Get.to(NovelDetailPage(info?.id), preventDuplicates: false);
|
||||
return;
|
||||
case 'video':
|
||||
pushToVideoPage(
|
||||
videoId: info?.id ?? '', isCartoon: true, videoCover: info?.coverV);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// 解析 deeplink/h5 链接并执行跳转
|
||||
/// [sourcePage] 链接落到会员/金币页时的下单来源(如首页浮窗),不传走 pushToWalletPage 的默认
|
||||
Future? pushToPageByLink(String? url,
|
||||
{Map<String, dynamic>? arguments, PaySourcePage? sourcePage}) async {
|
||||
if (url?.isNotEmpty != true) return null;
|
||||
|
||||
Uri? uri;
|
||||
try {
|
||||
uri = Uri.parse(url!);
|
||||
} catch (e) {
|
||||
debugLog("go func", e.toString());
|
||||
}
|
||||
if (uri == null) return null;
|
||||
|
||||
arguments ??= {};
|
||||
arguments.addAll(uri.queryParameters);
|
||||
|
||||
final host = uri.host.toLowerCase().removeAllWhitespace;
|
||||
|
||||
if (uri.scheme == "yinseinner") {
|
||||
return _handleYinseInnerLink(host, arguments, sourcePage);
|
||||
}
|
||||
// http(s):默认走外部浏览器;带 inner=1 走内部 H5
|
||||
if (uri.scheme.startsWith("http")) {
|
||||
if (uri.queryParameters["inner"] == "1") {
|
||||
// InAppWebView 是 PlatformView,创建时会重建渲染 Surface;视频在播放(Texture持续产帧)会导致部分机型画面放大/闪烁,先暂停所有播放
|
||||
HeadphoneMonitor.instance.pauseAll();
|
||||
return Get.to(H5Page(url: url!, showTitle: false, showClose: true),
|
||||
popGesture: true);
|
||||
}
|
||||
return launchUrlToWeb(url!);
|
||||
}
|
||||
showToast("未知链接");
|
||||
return null;
|
||||
}
|
||||
|
||||
/// 处理 yinseinner:// 内部 scheme 跳转
|
||||
Future? _handleYinseInnerLink(String host, Map<String, dynamic> arguments,
|
||||
[PaySourcePage? sourcePage]) async {
|
||||
switch (host) {
|
||||
case "submodule": // 亚模块分类
|
||||
eventBus.emit(YinseinnerModel(routeName: "module", id: arguments["id"]));
|
||||
return null;
|
||||
case "navigation_bar": // 导航栏 亚模块菜单弹出
|
||||
eventBus.emit(YinseinnerModel(routeName: "navigation_bar"));
|
||||
return null;
|
||||
case "community_module": // 社区
|
||||
eventBus.emit(
|
||||
YinseinnerModel(routeName: "community_module", id: arguments["id"]));
|
||||
return null;
|
||||
case "vip_page": // 会员中心
|
||||
return pushToWalletPage(vipId: arguments['id'], sourcePage: sourcePage);
|
||||
case "wallet_page": // 金币购买
|
||||
return pushToWalletPage(tabPosition: 1, sourcePage: sourcePage);
|
||||
case "universal_agent": // 分享推广
|
||||
return Get.to(() => MineSharePage(), preventDuplicates: false);
|
||||
case "lottery": // 抽奖
|
||||
presaleProvider.openLuckyDraw();
|
||||
return null;
|
||||
case "rankinglist": // 排行榜
|
||||
return Get.to(RankMainPage(), preventDuplicates: false);
|
||||
case "postdetail": // 帖子详情
|
||||
return Get.to(() => PostDetailPage(
|
||||
argument: PostDetailPageArgument(id: arguments["id"])));
|
||||
case "video_page": // 长视频播放页
|
||||
return Get.to(() => VideoPage(id: arguments["id"]),
|
||||
preventDuplicates: false);
|
||||
case "taskhall": // 福利任务
|
||||
return Get.to(() => const WelfareHomePage(index: 1),
|
||||
preventDuplicates: false);
|
||||
case "advancepage": // 预售
|
||||
return Get.to(() => const PreSalePage());
|
||||
case "live_streaming": // 直播
|
||||
eventBus.emit(YinseinnerModel(routeName: "live_streaming"));
|
||||
return null;
|
||||
case "shop_page": // 原味商店
|
||||
if (!Config.isStoreOpen) return null;
|
||||
try {
|
||||
LoadingHelper.showLoading();
|
||||
final result = await VidService.getShopAddress();
|
||||
LoadingHelper.dismissLoading();
|
||||
if (result is String && result.isEmpty) {
|
||||
showToast("获取商店地址失败~");
|
||||
return null;
|
||||
}
|
||||
HeadphoneMonitor.instance.pauseAll();
|
||||
return Get.to(H5Page(url: result), popGesture: true);
|
||||
} catch (e) {
|
||||
LoadingHelper.dismissLoading();
|
||||
debugLog(e);
|
||||
return null;
|
||||
}
|
||||
case "kefu": // 在线客服
|
||||
pushToCustomService();
|
||||
return null;
|
||||
case "userhomepage": // 跳转博主
|
||||
final uid = arguments["uid"] ?? 0;
|
||||
if (uid == 0) return null;
|
||||
return pushToPersonCenter(uid);
|
||||
case "publish_page": // 发布
|
||||
return Get.to(() => const PublishPage(type: PublishType.homeImgText));
|
||||
case "binding_page": // 绑定手机
|
||||
return Get.to(() => const BindPhonePage(pageType: PhonePageType.bind));
|
||||
case "science": // AI
|
||||
eventBus.emit(YinseinnerModel(routeName: "ai"));
|
||||
return null;
|
||||
default:
|
||||
showToast("未处理链接");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// 浏览器跳转(先 externalApplication,再 platformDefault 兜底)
|
||||
Future launchUrlToWeb(String url, {String? tip}) async {
|
||||
final uri = Uri.tryParse(url);
|
||||
if (uri == null) {
|
||||
debugLog('launchUrlToWeb invalid url: $url');
|
||||
return;
|
||||
}
|
||||
|
||||
const launchModes = <LaunchMode>[
|
||||
LaunchMode.externalApplication,
|
||||
LaunchMode.platformDefault,
|
||||
];
|
||||
|
||||
try {
|
||||
for (final mode in launchModes) {
|
||||
final launched = await launchUrl(uri, mode: mode);
|
||||
if (launched) {
|
||||
if (tip?.isNotEmpty == true) showToast(tip!);
|
||||
return;
|
||||
}
|
||||
}
|
||||
debugLog('launchUrlToWeb failed: $url');
|
||||
} catch (e) {
|
||||
debugLog(e);
|
||||
}
|
||||
}
|
||||
|
||||
/// 跳转个人中心
|
||||
/// [type]==1 历史业务(ActressMainPage)已下线
|
||||
/// [id] 深链传进来可能是字符串,统一收敛成 int
|
||||
Future? pushToPersonCenter(dynamic id, {int? type}) {
|
||||
if (type == 1) return null;
|
||||
final uid = id is int ? id : int.tryParse('$id') ?? 0;
|
||||
return Get.to(() => UserCenterPage(uid: uid), preventDuplicates: false);
|
||||
}
|
||||
|
||||
/// 跳转到充值/会员页(tabPosition==1 → 金币,否则 → 会员)
|
||||
/// [sourcePage] 落地页下单时的来源。不传时各分支用各自的默认:会员页记会员中心
|
||||
/// (绝大多数入口都是「跳进会员页再下单」),金币页记 UNKNOWN(没有专属枚举,别拿会员的顶上);
|
||||
/// 有独立来源的(H5 活动等)自己传
|
||||
Future pushToWalletPage(
|
||||
{int? tabPosition, String? vipId, PaySourcePage? sourcePage}) async {
|
||||
if (tabPosition == 1) {
|
||||
return Get.to(
|
||||
MineChargeCoinPage(sourcePage: sourcePage ?? PaySourcePage.unknown),
|
||||
preventDuplicates: false);
|
||||
}
|
||||
return Get.to(
|
||||
MineChargeVipPage(
|
||||
vipID: vipId?.isNotEmpty == true ? vipId : null,
|
||||
sourcePage: sourcePage ?? PaySourcePage.vipCenter,
|
||||
),
|
||||
preventDuplicates: false,
|
||||
);
|
||||
}
|
||||
|
||||
/// 跳转客服系统
|
||||
void pushToCustomService() async {
|
||||
LoadingAlertWidget.show();
|
||||
final url = await MineService.fetchCustomService();
|
||||
LoadingAlertWidget.cancel();
|
||||
if (url?.isNotEmpty == true) {
|
||||
final h5Url = '${Address.baseHost}/api$url';
|
||||
Get.to(H5Page(url: h5Url, title: '在线客服'), opaque: false);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user