初始化
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hgdj/assets_tool/images.dart';
|
||||
import 'package:hgdj/hj_model/mine/exchange/recharge_type_list_model.dart';
|
||||
import 'package:hgdj/hj_utils/screen.dart';
|
||||
|
||||
// 金币充值档位卡片
|
||||
class CoinItem extends StatelessWidget {
|
||||
final RechargeTypeModel model;
|
||||
final bool isSelected; // 是否选中
|
||||
final VoidCallback? onTap;
|
||||
|
||||
const CoinItem(this.model, {super.key, this.onTap, this.isSelected = false});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final couponDesc = model.couponDesc;
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Stack(
|
||||
children: [
|
||||
Container(
|
||||
width: double.infinity,
|
||||
margin: const EdgeInsets.only(top: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withValues(alpha: .1),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: isSelected
|
||||
? Border.all(width: 1, color: const Color(0xffF9C142))
|
||||
: null,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Image.asset('coin_icon.webp'.mineImgPath, width: 36),
|
||||
4.sizeBoxH,
|
||||
Text(
|
||||
"${model.amount}金币",
|
||||
style: const TextStyle(color: Colors.white, fontSize: 14),
|
||||
),
|
||||
4.sizeBoxH,
|
||||
Text(
|
||||
'¥${model.moneyYuan}',
|
||||
style: const TextStyle(
|
||||
color: Color(0xffF9C142), fontWeight: FontWeight.w500),
|
||||
),
|
||||
4.sizeBoxH,
|
||||
],
|
||||
),
|
||||
),
|
||||
// 左上角优惠角标
|
||||
if (couponDesc?.isNotEmpty == true)
|
||||
Positioned(
|
||||
top: 0,
|
||||
left: 0,
|
||||
child: Container(
|
||||
height: 20,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 5),
|
||||
decoration: const BoxDecoration(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(12),
|
||||
bottomRight: Radius.circular(12)),
|
||||
color: Color(0xffFFD460),
|
||||
),
|
||||
child: Text(
|
||||
couponDesc!,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
color: Color(0xff292929),
|
||||
fontWeight: FontWeight.w500,
|
||||
height: 1,
|
||||
fontSize: 10.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:hgdj/assets_tool/app_colors.dart';
|
||||
import 'package:hgdj/assets_tool/images.dart';
|
||||
import 'package:hgdj/hj_utils/screen.dart';
|
||||
import 'package:hgdj/hj_utils/widget_util.dart';
|
||||
import 'package:hgdj/routers/jump_router.dart';
|
||||
import 'package:hgdj/tools_base/global_store/store.dart';
|
||||
import 'package:hgdj/tools_base/loading/loading_center_widget.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:hgdj/tools_base/widget/sheet_handle_bar.dart';
|
||||
|
||||
import '../../make_money/mine_withdrawal_record_page.dart';
|
||||
import '../mine_charge_coin_logic.dart';
|
||||
import '../pay_order_source.dart';
|
||||
import 'coin_item.dart';
|
||||
|
||||
/// 金币支付底部弹窗(按设计稿:余额卡片 + 档位网格 + 立即支付)
|
||||
class CoinPayBottomSheet extends StatelessWidget {
|
||||
/// 下单来源,默认播放页底部弹窗——本弹窗只在播放页(购买弹窗/解锁蒙层)用
|
||||
final PaySourcePage sourcePage;
|
||||
|
||||
/// 下单埋点上下文(短剧付费墙充金币要带剧/集/付费墙上下文)
|
||||
final PayOrderTrackInfo? orderTrack;
|
||||
|
||||
const CoinPayBottomSheet(
|
||||
{super.key,
|
||||
this.sourcePage = PaySourcePage.videoBottomSheet,
|
||||
this.orderTrack});
|
||||
|
||||
/// 弹窗展示中,防连点叠多个 bottomSheet
|
||||
static bool _isShowing = false;
|
||||
|
||||
static Future<T?> show<T>({
|
||||
PaySourcePage sourcePage = PaySourcePage.videoBottomSheet,
|
||||
PayOrderTrackInfo? orderTrack,
|
||||
}) async {
|
||||
if (_isShowing) return null;
|
||||
_isShowing = true;
|
||||
try {
|
||||
return await Get.bottomSheet<T>(
|
||||
CoinPayBottomSheet(sourcePage: sourcePage, orderTrack: orderTrack),
|
||||
isScrollControlled: true,
|
||||
backgroundColor: Colors.transparent,
|
||||
);
|
||||
} finally {
|
||||
_isShowing = false;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GetBuilder<MineChargeCoinLogic>(
|
||||
init: MineChargeCoinLogic(sourcePage: sourcePage, orderTrack: orderTrack),
|
||||
global: false,
|
||||
builder: (logic) {
|
||||
// Material 填深色底:圆角抗锯齿对着 #040018,避免透明底导致左右上角异色
|
||||
return Material(
|
||||
color: const Color(0xff040018),
|
||||
borderRadius: const BorderRadius.vertical(top: Radius.circular(18)),
|
||||
clipBehavior: Clip.antiAlias,
|
||||
child: Container(
|
||||
constraints: BoxConstraints(maxHeight: Get.height * 0.85),
|
||||
decoration: const BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [Color(0xff040018), Color(0xff060606)],
|
||||
),
|
||||
),
|
||||
child: Stack(
|
||||
children: [
|
||||
// 顶部径向黄光:#FACC15 16% → 0%
|
||||
const Positioned.fill(
|
||||
child: DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
gradient: RadialGradient(
|
||||
center: Alignment.topCenter,
|
||||
radius: 1.2,
|
||||
colors: [
|
||||
Color(0x29FACC15), // #FACC15 @ 16%
|
||||
Color(0x00FACC15), // #FACC15 @ 0%
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SafeArea(
|
||||
top: false,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
12.sizeBoxH,
|
||||
const SheetHandleBar(),
|
||||
16.sizeBoxH,
|
||||
const Text(
|
||||
'金币支付',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
16.sizeBoxH,
|
||||
Flexible(child: _buildBody(logic)),
|
||||
_buildBottomBar(logic),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBody(MineChargeCoinLogic logic) {
|
||||
if (logic.isInitLoading) {
|
||||
return const SizedBox(height: 220, child: LoadingCenterWidget());
|
||||
}
|
||||
if (logic.model?.list?.isEmpty != false) {
|
||||
return SizedBox(
|
||||
height: 220,
|
||||
child: CErrorWidget(retryOnTap: () => logic.loadData()),
|
||||
);
|
||||
}
|
||||
return SingleChildScrollView(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Column(
|
||||
children: [
|
||||
_buildWallet(),
|
||||
16.sizeBoxH,
|
||||
GridView.builder(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: 3,
|
||||
mainAxisSpacing: 12,
|
||||
crossAxisSpacing: 6,
|
||||
childAspectRatio: 111 / 138,
|
||||
),
|
||||
itemCount: logic.model!.list!.length,
|
||||
itemBuilder: (context, index) {
|
||||
final model = logic.model!.list![index];
|
||||
final isSelected = logic.selectedCoin?.id == model.id;
|
||||
return CoinItem(
|
||||
model,
|
||||
isSelected: isSelected,
|
||||
onTap: () => logic.onSelectCoin(index),
|
||||
);
|
||||
},
|
||||
),
|
||||
18.sizeBoxH,
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// 我的金币余额卡片
|
||||
Widget _buildWallet() {
|
||||
return Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: const EdgeInsets.fromLTRB(16, 14, 16, 14),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withValues(alpha: 0.1),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
'我的金币余额',
|
||||
style: TextStyle(
|
||||
color: Colors.white, fontSize: 14, fontWeight: FontWeight.w500),
|
||||
),
|
||||
8.sizeBoxH,
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Image.asset('coin_icon.webp'.mineImgPath, width: 36),
|
||||
4.sizeBoxW,
|
||||
Consumer<GlobalStore>(
|
||||
builder: (_, store, __) {
|
||||
final wallet = store.wallet;
|
||||
final total = (wallet?.amount ?? 0) + (wallet?.income ?? 0);
|
||||
return Text(
|
||||
'$total',
|
||||
style: const TextStyle(
|
||||
color: Color(0xffFFD460),
|
||||
fontSize: 32,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
const Spacer(),
|
||||
InkWell(
|
||||
enableFeedback: false,
|
||||
onTap: () =>
|
||||
Get.to(RecordsPage(RecordType.bill), opaque: false),
|
||||
child: Container(
|
||||
alignment: Alignment.center,
|
||||
height: 30,
|
||||
width: 90,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xffFFD460),
|
||||
borderRadius: BorderRadius.circular(999),
|
||||
),
|
||||
child: const Text(
|
||||
'余额明细',
|
||||
style: TextStyle(color: Color(0xff3D3D3D), fontSize: 14),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// 立即支付 + 在线客服
|
||||
Widget _buildBottomBar(MineChargeCoinLogic logic) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () => logic.onGotoPay(),
|
||||
child: Container(
|
||||
height: 44,
|
||||
margin: const EdgeInsets.symmetric(horizontal: 16),
|
||||
decoration: BoxDecoration(
|
||||
color: AppColors.actionRed,
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
'¥${logic.selectedCoin?.moneyYuan ?? 0}/立即支付',
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
12.sizeBoxH,
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text('支付问题反馈,点击联系 ',
|
||||
style: textStyle(12, const Color(0xffBFBFC1), FontWeight.w400)),
|
||||
GestureDetector(
|
||||
onTap: pushToCustomService,
|
||||
child: Text('在线客服',
|
||||
style:
|
||||
textStyle(12, const Color(0xffFFD460), FontWeight.w400)),
|
||||
),
|
||||
],
|
||||
),
|
||||
16.sizeBoxH,
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user