Files
2026-09-15 15:44:13 +07:00

190 lines
6.6 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ignore_for_file: use_build_context_synchronously
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:hgdj/extension/extensions.dart';
import 'package:hgdj/hj_utils/screen.dart';
import 'package:hgdj/tools_base/toast.dart';
import 'package:hgdj/tools_base/widget/sheet_handle_bar.dart';
import 'package:provider/provider.dart';
import '../../assets_tool/app_colors.dart';
import '../../hj_model/acg/comic_chapters_model.dart';
import '../../hj_model/cartoon_media_info.dart';
import '../../hj_utils/pay/pay_manager.dart';
import '../../routers/jump_router.dart';
import '../../tools_base/global_store/store.dart';
///购买漫画/小说弹窗
class ComicBuyAlert extends StatefulWidget {
//// 返回值: 1 购买单集, 2 购买全集,null 啥都没购买
static Future<int?> show({
ComicChapterInfo? curModel, // 单集数据
CartoonMediaInfo? mediaInfo, // 全集数据
}) async {
return await Get.bottomSheet(ComicBuyAlert(
mediaInfo: mediaInfo,
curModel: curModel,
));
}
final ComicChapterInfo? curModel; // 单集数据
final CartoonMediaInfo? mediaInfo; // 全集数据
const ComicBuyAlert({
super.key,
this.curModel,
this.mediaInfo,
});
@override
State<ComicBuyAlert> createState() => _ComicBuyAlertState();
}
class _ComicBuyAlertState extends State<ComicBuyAlert> {
bool _isBuying = false;
//整套价格(产品当前只开整套购买)
int get _price => widget.mediaInfo?.price ?? 0;
@override
void initState() {
super.initState();
//刷完钱包会 notifyListeners,下面的 Consumer 自动重建,不用再 setState
globalStore.refreshWallet();
}
@override
Widget build(BuildContext context) {
return Material(
color: Colors.transparent,
child: Consumer<GlobalStore>(
builder: (_, store, __) {
final enough = (store.wallet?.amount ?? 0) >= _price;
return Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 18),
decoration: const BoxDecoration(
color: AppColors.primaryColor,
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const SheetHandleBar(),
18.sizeBoxH,
const Text(
'购买作品',
style: TextStyle(
color: Color(0xE5ffffff),
fontSize: 20,
fontWeight: FontWeight.w500),
),
36.sizeBoxH,
//作品解锁价
Row(
children: [
const Text('作品解锁',
style:
TextStyle(color: Color(0xE5ffffff), fontSize: 14)),
const Spacer(),
GestureDetector(
onTap: () => pushToWalletPage(tabPosition: 1),
child: Text(
'$_price 金币',
style: const TextStyle(
color: Color(0xffFF9000),
fontSize: 14,
fontWeight: FontWeight.w500),
),
),
],
),
18.sizeBoxH,
Divider(
height: 0.5, color: Colors.white.withValues(alpha: .05)),
18.sizeBoxH,
//我的金币余额 + 充值入口
Row(
children: [
const Text('我的金币',
style:
TextStyle(color: Color(0xE5ffffff), fontSize: 14)),
const Spacer(),
Text(
'${store.wallet?.amount?.toDouble().fixed(2) ?? 0}',
style: const TextStyle(
color: Color(0xE5ffffff),
fontSize: 14,
fontWeight: FontWeight.w500),
),
12.sizeBoxW,
InkWell(
enableFeedback: false,
onTap: () => pushToWalletPage(tabPosition: 1),
child: const Text(
'充值',
style: TextStyle(
color: Color(0xffA4634D),
fontSize: 14,
fontWeight: FontWeight.w400,
decoration: TextDecoration.underline,
decorationColor: Color(0xffA4634D),
),
),
),
],
),
18.sizeBoxH,
//支付按钮:余额不足直接去充值
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () => enough
? _buyProduct(true)
: pushToWalletPage(tabPosition: 1),
child: Container(
width: double.infinity,
height: 47,
decoration: BoxDecoration(
color: const Color(0xffF68804),
borderRadius: BorderRadius.circular(3)),
alignment: Alignment.center,
child: Text(
enough ? '$_price金币/立即支付' : '余额不足,前往充值',
style: const TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w500),
),
),
),
],
),
);
},
),
);
}
///购买作品:[isAll] true 整本(19)false 单集(25)
Future<void> _buyProduct(bool isAll) async {
if (_isBuying) return; //纯防重入,build 不依赖它,改了不用 setState
_isBuying = true;
final productType = isAll ? ProductType.mediaAll : ProductType.mediaChapter;
final productID = isAll
? (widget.mediaInfo?.id ?? widget.curModel?.mediaId)
: widget.curModel?.id;
await PayManager().buy(
productID,
productType,
source: 'comic_buy',
onSuccess: (data) {
globalStore.refreshWallet();
showToast("购买成功");
Get.back(result: isAll ? 2 : 1);
},
);
_isBuying = false;
}
}