logo和名称替换
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:hgmj/hj_utils/screen.dart';
|
||||
import 'package:hgmj/tools_base/widget/net_image_widget.dart';
|
||||
import 'package:hgmj/tools_base/widget/sheet_handle_bar.dart';
|
||||
import 'package:wydj/hj_utils/screen.dart';
|
||||
import 'package:wydj/tools_base/widget/net_image_widget.dart';
|
||||
import 'package:wydj/tools_base/widget/sheet_handle_bar.dart';
|
||||
|
||||
import '../../hj_page/mine/mine_vip/pay_order_source.dart';
|
||||
import '../../hj_page/mine/mine_vip/vip_support_model.dart';
|
||||
@@ -66,14 +66,21 @@ class GuideBottomSheet extends StatelessWidget {
|
||||
return show(
|
||||
scene: GuideScene.videoPreviewEnd,
|
||||
title: Text(
|
||||
config?.title?.isNotEmpty == true ? config!.title! : '该视频为VIP内容\n只能观看试看内容哦~',
|
||||
config?.title?.isNotEmpty == true
|
||||
? config!.title!
|
||||
: '该视频为VIP内容\n只能观看试看内容哦~',
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(color: Colors.white, fontSize: 17, fontWeight: FontWeight.w600),
|
||||
style: const TextStyle(
|
||||
color: Colors.white, fontSize: 17, fontWeight: FontWeight.w600),
|
||||
),
|
||||
subtitle: GradientText(
|
||||
config?.description?.isNotEmpty == true ? config!.description! : '想要查看完整内容,需要开通会员',
|
||||
gradient: const LinearGradient(colors: [Colors.white, Color(0xffEFD394)]),
|
||||
style: const TextStyle(color: Colors.white, fontSize: 15, fontWeight: FontWeight.w500),
|
||||
config?.description?.isNotEmpty == true
|
||||
? config!.description!
|
||||
: '想要查看完整内容,需要开通会员',
|
||||
gradient:
|
||||
const LinearGradient(colors: [Colors.white, Color(0xffEFD394)]),
|
||||
style: const TextStyle(
|
||||
color: Colors.white, fontSize: 15, fontWeight: FontWeight.w500),
|
||||
),
|
||||
buttonText: buttonText,
|
||||
);
|
||||
@@ -87,8 +94,13 @@ class GuideBottomSheet extends StatelessWidget {
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.fromLTRB(16, 18, 16, 18 + screen.paddingBottom),
|
||||
decoration: const BoxDecoration(
|
||||
gradient: LinearGradient(begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [Color(0xff0F0F0F), Colors.black]),
|
||||
border: Border(top: BorderSide(color: Color(0x4DE4BB6D))), // rgba(228,187,109,0.3)
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [Color(0xff0F0F0F), Colors.black]),
|
||||
border: Border(
|
||||
top: BorderSide(
|
||||
color: Color(0x4DE4BB6D))), // rgba(228,187,109,0.3)
|
||||
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
|
||||
),
|
||||
child: Column(
|
||||
@@ -103,7 +115,8 @@ class GuideBottomSheet extends StatelessWidget {
|
||||
SizedBox(
|
||||
width: 270,
|
||||
height: 122,
|
||||
child: NetworkImageLoader(imageUrl: cover, fit: BoxFit.fill, borderRadius: 8),
|
||||
child: NetworkImageLoader(
|
||||
imageUrl: cover, fit: BoxFit.fill, borderRadius: 8),
|
||||
),
|
||||
18.sizeBoxH,
|
||||
subtitle,
|
||||
@@ -116,11 +129,21 @@ class GuideBottomSheet extends StatelessWidget {
|
||||
height: 52,
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
gradient: const LinearGradient(colors: [Color(0xffFFB03F), Color(0xffF2680C)]),
|
||||
gradient: const LinearGradient(
|
||||
colors: [Color(0xffFFB03F), Color(0xffF2680C)]),
|
||||
borderRadius: BorderRadius.circular(26),
|
||||
boxShadow: [BoxShadow(color: const Color(0x73F2680C), blurRadius: 18, offset: const Offset(0, 6))], // rgba(242,104,12,0.45)
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: const Color(0x73F2680C),
|
||||
blurRadius: 18,
|
||||
offset: const Offset(0, 6))
|
||||
], // rgba(242,104,12,0.45)
|
||||
),
|
||||
child: Text(buttonText, style: const TextStyle(color: Colors.white, fontSize: 17, fontWeight: FontWeight.w700)),
|
||||
child: Text(buttonText,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 17,
|
||||
fontWeight: FontWeight.w700)),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:get/get.dart';
|
||||
import 'package:hgmj/hj_model/splash/domain_source_model.dart';
|
||||
import 'package:hgmj/tools_base/global_store/store.dart';
|
||||
import 'package:wydj/hj_model/splash/domain_source_model.dart';
|
||||
import 'package:wydj/tools_base/global_store/store.dart';
|
||||
|
||||
import '../../hj_page/main_page/provider/msg_provider.dart';
|
||||
import '../../hj_page/mine/mine_vip/mine_charge_vip_page.dart';
|
||||
@@ -19,13 +19,18 @@ import 'guide_manager.dart';
|
||||
Future<VipProductModel?> loadGuideCard(GuideScene scene) async {
|
||||
final config = GuideManager().configOf(scene);
|
||||
if (config == null) return null; // 开关关着
|
||||
if (config.productId?.isNotEmpty != true || config.cover?.isNotEmpty != true) {
|
||||
if (config.productId?.isNotEmpty != true ||
|
||||
config.cover?.isNotEmpty != true) {
|
||||
debugLog('paymentGuide', '${scene.value} 缺 productId 或 cover,配置有误不弹');
|
||||
return null;
|
||||
}
|
||||
if (vipProductManager.vipCards.isEmpty) await vipProductManager.loadVipCards();
|
||||
final card = vipProductManager.vipCards.firstWhereOrNull((e) => e.productID == config.productId);
|
||||
if (card == null) debugLog('paymentGuide', '${scene.value} 配置的会员卡不在列表里,不弹: ${config.productId}');
|
||||
if (vipProductManager.vipCards.isEmpty)
|
||||
await vipProductManager.loadVipCards();
|
||||
final card = vipProductManager.vipCards
|
||||
.firstWhereOrNull((e) => e.productID == config.productId);
|
||||
if (card == null)
|
||||
debugLog(
|
||||
'paymentGuide', '${scene.value} 配置的会员卡不在列表里,不弹: ${config.productId}');
|
||||
return card;
|
||||
}
|
||||
|
||||
@@ -38,7 +43,9 @@ bool isUnpayGuideUser() {
|
||||
|
||||
/// 场景 → 下单来源页(透传 /mine/topay 的 sourcePage)
|
||||
PaySourcePage guideSourcePage(GuideScene scene) => switch (scene) {
|
||||
GuideScene.homeNewUser || GuideScene.homeOldUser || GuideScene.homeNewUserFreeTrial =>
|
||||
GuideScene.homeNewUser ||
|
||||
GuideScene.homeOldUser ||
|
||||
GuideScene.homeNewUserFreeTrial =>
|
||||
PaySourcePage.homeUserSegment,
|
||||
GuideScene.vipCenter => PaySourcePage.vipCenter,
|
||||
_ => PaySourcePage.videoBottomSheet, //播放页起播引导 / 返回挽留
|
||||
@@ -47,5 +54,6 @@ PaySourcePage guideSourcePage(GuideScene scene) => switch (scene) {
|
||||
/// 开通 → 关弹窗 + 进会员页并选中该卡(落地页 VIP_CENTER 开着还会再弹一次,不去重)
|
||||
void goVipDetail(VipProductModel card, {required PaySourcePage sourcePage}) {
|
||||
Get.back(result: true); // 带回"去开通了",调用方据此不恢复播放
|
||||
Get.to(() => MineChargeVipPage(vipID: card.productID, sourcePage: sourcePage));
|
||||
Get.to(
|
||||
() => MineChargeVipPage(vipID: card.productID, sourcePage: sourcePage));
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:hgmj/hj_utils/screen.dart';
|
||||
import 'package:hgmj/tools_base/widget/net_image_widget.dart';
|
||||
import 'package:wydj/hj_utils/screen.dart';
|
||||
import 'package:wydj/tools_base/widget/net_image_widget.dart';
|
||||
|
||||
import '../../assets_tool/images.dart';
|
||||
import '../../hj_page/mine/mine_vip/pay_order_source.dart';
|
||||
@@ -34,7 +34,8 @@ class PromoCountdown {
|
||||
/// 长视频返回挽留 / 进会员页时触发
|
||||
class GuideCountdownDialog extends StatelessWidget {
|
||||
final VipProductModel card;
|
||||
final ValueChanged<VipProductModel>? onConfirm; // 默认跳会员页选卡;已在会员页的场景自己处理(关弹窗+就地选中该卡)
|
||||
final ValueChanged<VipProductModel>?
|
||||
onConfirm; // 默认跳会员页选卡;已在会员页的场景自己处理(关弹窗+就地选中该卡)
|
||||
final PaySourcePage sourcePage;
|
||||
final String cover; // 场景下发的主图,相对路径由 ImageCacheManager 拼域名
|
||||
const GuideCountdownDialog({
|
||||
@@ -47,7 +48,9 @@ class GuideCountdownDialog extends StatelessWidget {
|
||||
|
||||
/// [scene] 决定主图/卡/下单来源,调用方须先用开关判过能弹
|
||||
/// 返回 true = 点了「立即开通」(点X/点蒙层/没弹成都是 false),返回挽留场景据此决定要不要放行返回
|
||||
static Future<bool> show({required GuideScene scene, ValueChanged<VipProductModel>? onConfirm}) async {
|
||||
static Future<bool> show(
|
||||
{required GuideScene scene,
|
||||
ValueChanged<VipProductModel>? onConfirm}) async {
|
||||
final card = await loadGuideCard(scene);
|
||||
if (card == null) return false; // 配置有误不弹
|
||||
final confirmed = await Get.dialog<bool>(
|
||||
@@ -92,15 +95,29 @@ class GuideCountdownDialog extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.baseline,
|
||||
textBaseline: TextBaseline.alphabetic,
|
||||
children: [
|
||||
const Text('现在下单获得', style: TextStyle(color: Colors.white, fontSize: 19, fontWeight: FontWeight.w800)),
|
||||
const Text('现在下单获得',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 19,
|
||||
fontWeight: FontWeight.w800)),
|
||||
2.sizeBoxW,
|
||||
const GradientText(
|
||||
'优惠',
|
||||
gradient: LinearGradient(colors: [Color(0xffFFE3A0), Color(0xffF0A93C)]),
|
||||
style: TextStyle(color: Colors.white, fontSize: 26, fontWeight: FontWeight.w800),
|
||||
gradient: LinearGradient(colors: [
|
||||
Color(0xffFFE3A0),
|
||||
Color(0xffF0A93C)
|
||||
]),
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 26,
|
||||
fontWeight: FontWeight.w800),
|
||||
),
|
||||
2.sizeBoxW,
|
||||
const Text('福利', style: TextStyle(color: Colors.white, fontSize: 19, fontWeight: FontWeight.w800)),
|
||||
const Text('福利',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 19,
|
||||
fontWeight: FontWeight.w800)),
|
||||
],
|
||||
),
|
||||
15.sizeBoxH,
|
||||
@@ -119,15 +136,24 @@ class GuideCountdownDialog extends StatelessWidget {
|
||||
height: 52,
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
gradient: const LinearGradient(colors: [Color(0xffFFB03F), Color(0xffF2680C)]),
|
||||
gradient: const LinearGradient(colors: [
|
||||
Color(0xffFFB03F),
|
||||
Color(0xffF2680C)
|
||||
]),
|
||||
borderRadius: BorderRadius.circular(26),
|
||||
boxShadow: [
|
||||
BoxShadow(color: const Color(0x73F2680C), blurRadius: 18, offset: const Offset(0, 6))
|
||||
BoxShadow(
|
||||
color: const Color(0x73F2680C),
|
||||
blurRadius: 18,
|
||||
offset: const Offset(0, 6))
|
||||
], // rgba(242,104,12,0.45)
|
||||
),
|
||||
child: Text(
|
||||
'立即开通 · 仅需¥${card.discountedPriceUI}',
|
||||
style: const TextStyle(color: Colors.white, fontSize: 17, fontWeight: FontWeight.w700),
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 17,
|
||||
fontWeight: FontWeight.w700),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -140,7 +166,8 @@ class GuideCountdownDialog extends StatelessWidget {
|
||||
child: SizedBox(
|
||||
width: 270,
|
||||
height: 122,
|
||||
child: NetworkImageLoader(imageUrl: cover, fit: BoxFit.fill, borderRadius: 8),
|
||||
child: NetworkImageLoader(
|
||||
imageUrl: cover, fit: BoxFit.fill, borderRadius: 8),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -193,7 +220,11 @@ class _CountdownRowState extends State<_CountdownRow> {
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Text('距优惠结束', style: TextStyle(color: Color(0xffB8AE9C), fontSize: 12, fontWeight: FontWeight.w500)),
|
||||
const Text('距优惠结束',
|
||||
style: TextStyle(
|
||||
color: Color(0xffB8AE9C),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500)),
|
||||
8.sizeBoxW,
|
||||
ValueListenableBuilder<Duration>(
|
||||
valueListenable: _remain,
|
||||
@@ -215,15 +246,22 @@ class _CountdownRowState extends State<_CountdownRow> {
|
||||
// 时/分/秒块
|
||||
Widget _timeCell(int v) => Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 4),
|
||||
decoration: BoxDecoration(color: const Color(0xffE23B2E), borderRadius: BorderRadius.circular(6)),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xffE23B2E),
|
||||
borderRadius: BorderRadius.circular(6)),
|
||||
child: Text(
|
||||
v.toString().padLeft(2, '0'),
|
||||
style: const TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w700),
|
||||
style: const TextStyle(
|
||||
color: Colors.white, fontSize: 14, fontWeight: FontWeight.w700),
|
||||
),
|
||||
);
|
||||
|
||||
Widget get _colon => const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 3),
|
||||
child: Text(':', style: TextStyle(color: Color(0xffE85B4F), fontSize: 14, fontWeight: FontWeight.w700)),
|
||||
child: Text(':',
|
||||
style: TextStyle(
|
||||
color: Color(0xffE85B4F),
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w700)),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:hgmj/assets_tool/images.dart';
|
||||
import 'package:hgmj/hj_model/splash/domain_source_model.dart';
|
||||
import 'package:hgmj/hj_page/home/activity_float/home_activity_float.dart';
|
||||
import 'package:hgmj/hj_page/main_page/provider/msg_provider.dart';
|
||||
import 'package:hgmj/hj_utils/screen.dart';
|
||||
import 'package:hgmj/tools_base/widget/fly_to_overlay.dart';
|
||||
import 'package:hgmj/tools_base/widget/net_image_widget.dart';
|
||||
import 'package:wydj/assets_tool/images.dart';
|
||||
import 'package:wydj/hj_model/splash/domain_source_model.dart';
|
||||
import 'package:wydj/hj_page/home/activity_float/home_activity_float.dart';
|
||||
import 'package:wydj/hj_page/main_page/provider/msg_provider.dart';
|
||||
import 'package:wydj/hj_utils/screen.dart';
|
||||
import 'package:wydj/tools_base/widget/fly_to_overlay.dart';
|
||||
import 'package:wydj/tools_base/widget/net_image_widget.dart';
|
||||
|
||||
/// 支付分层首页弹窗:展示后端 homePage 图,点击跳会员页并选中 config.vipCard。
|
||||
/// 倒计时读 config.lastDiscountTime,秒级刷新由 MineMsgProvider().tick 驱动,过期自动停
|
||||
@@ -60,7 +60,8 @@ class _GuideHomeDialogState extends State<GuideHomeDialog> {
|
||||
if (box == null || !box.hasSize) return null;
|
||||
final origin = box.localToGlobal(Offset.zero);
|
||||
const w = 60.0, h = 66.0; // 与 _LayeredFloatView 的尺寸一致
|
||||
return Rect.fromLTWH(origin.dx + box.size.width - w, origin.dy + box.size.height - h, w, h);
|
||||
return Rect.fromLTWH(
|
||||
origin.dx + box.size.width - w, origin.dy + box.size.height - h, w, h);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -104,7 +105,8 @@ class _GuideHomeDialogState extends State<GuideHomeDialog> {
|
||||
imageUrl: config.homePage ?? "",
|
||||
fit: BoxFit.fill,
|
||||
borderRadius: 0,
|
||||
placeHolderWidget: Container(color: const Color(0x00000000)),
|
||||
placeHolderWidget:
|
||||
Container(color: const Color(0x00000000)),
|
||||
),
|
||||
// 倒计时胶囊:海报右上角,听 tick 每秒刷新,过期自动收起
|
||||
Positioned(
|
||||
@@ -112,7 +114,10 @@ class _GuideHomeDialogState extends State<GuideHomeDialog> {
|
||||
right: 0,
|
||||
child: ValueListenableBuilder<int>(
|
||||
valueListenable: MineMsgProvider().tick,
|
||||
builder: (_, __, ___) => config.hasDiscountCountdown ? _buildCountdownPill() : const SizedBox.shrink(),
|
||||
builder: (_, __, ___) =>
|
||||
config.hasDiscountCountdown
|
||||
? _buildCountdownPill()
|
||||
: const SizedBox.shrink(),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -123,7 +128,8 @@ class _GuideHomeDialogState extends State<GuideHomeDialog> {
|
||||
20.sizeBoxH,
|
||||
GestureDetector(
|
||||
onTap: _close,
|
||||
child: Image.asset("close_button.png".commonImgPath, width: 32),
|
||||
child: Image.asset("close_button.png".commonImgPath,
|
||||
width: 32),
|
||||
)
|
||||
],
|
||||
),
|
||||
@@ -149,7 +155,10 @@ class _GuideHomeDialogState extends State<GuideHomeDialog> {
|
||||
),
|
||||
child: Text(
|
||||
'${config.discountHour}:${config.discountMin}:${config.discountSec}',
|
||||
style: const TextStyle(color: Color(0xffFFF0D1), fontSize: 20, fontWeight: FontWeight.w600),
|
||||
style: const TextStyle(
|
||||
color: Color(0xffFFF0D1),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w600),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:get/get.dart';
|
||||
import 'package:hgmj/hj_model/splash/domain_source_model.dart';
|
||||
import 'package:wydj/hj_model/splash/domain_source_model.dart';
|
||||
|
||||
import '../../hj_page/main_page/provider/msg_provider.dart';
|
||||
import 'guide_config.dart';
|
||||
@@ -45,8 +45,12 @@ class GuideManager {
|
||||
/// 请求还没回来,硬判成老用户会让新用户永远错过新人引导,且 _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;
|
||||
if (tier == null)
|
||||
return [GuideScene.homeNewUser, GuideScene.homeOldUser]
|
||||
.firstWhereOrNull(canShow);
|
||||
final scene = tier == PayTier.newUnpay
|
||||
? GuideScene.homeNewUser
|
||||
: GuideScene.homeOldUser;
|
||||
return canShow(scene) ? scene : null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user