logo和名称替换

This commit is contained in:
谢宇宁
2026-10-14 11:23:36 +07:00
parent 1cb514cd02
commit c5c04a7967
478 changed files with 8990 additions and 4948 deletions
+37 -14
View File
@@ -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)),
),
),
],
+16 -8
View File
@@ -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));
}
+54 -16
View File
@@ -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)),
);
}
+21 -12
View File
@@ -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),
),
);
}
+7 -3
View File
@@ -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;
}
}