提交 a6bc143c authored 作者: yueweilu's avatar yueweilu

结算界面 所有逻辑完成(除提交接口)

上级 8c870c25
......@@ -95,5 +95,19 @@ abstract class ShopAPI {
return CouponListModel.fromJson(result.data);
}
/// 7、获取优惠券可使用和不可使用数量
static Future<CouponNumModel> couponNum({
required String price
}) async {
final result = await HttpService.to.post(
'/v1/coupon/Coupon/getCouponNum',
params: {
'price':price
},
);
if (result.data is! Map ) return CouponNumModel();
return CouponNumModel.fromJson(result.data);
}
}
\ No newline at end of file
......@@ -71,17 +71,18 @@ class RecordModel {
class CouponModel {
CouponModel({
this.couponRecId,
// this.endTime,
this.endTime,
this.couponId,
this.useStatus,
this.couponName,
this.normPrice,
this.reducedPrice,
this.type
});
CouponModel.fromJson(dynamic json) {
couponRecId = json['coupon_rec_id'];
// endTime = json['end_time'];
endTime = json['end_time'];
couponId = json['coupon_id'];
useStatus = json['use_status'];
couponName = json['coupon_name'];
......@@ -90,12 +91,13 @@ class CouponModel {
}
num? couponRecId;
// String? endTime;
String? endTime;
num? couponId;
num? useStatus;
String? couponName;
num? normPrice;
String? reducedPrice;
num? type;
CouponModel copyWith({
num? couponRecId,
......@@ -108,7 +110,7 @@ class CouponModel {
}) =>
CouponModel(
couponRecId: couponRecId ?? this.couponRecId,
// endTime: endTime ?? this.endTime,
endTime: endTime ?? this.endTime,
couponId: couponId ?? this.couponId,
useStatus: useStatus ?? this.useStatus,
couponName: couponName ?? this.couponName,
......
......@@ -122,4 +122,30 @@ class CouponListModel {
return map;
}
}
/// 优惠券可使用和不可使用数量
class CouponNumModel {
CouponNumModel({
this.availableNum,
this.unavailableNum,});
CouponNumModel.fromJson(dynamic json) {
availableNum = json['available_num'];
unavailableNum = json['unavailable_num'];
}
num? availableNum;
num? unavailableNum;
CouponNumModel copyWith({ num? availableNum,
num? unavailableNum,
}) => CouponNumModel( availableNum: availableNum ?? this.availableNum,
unavailableNum: unavailableNum ?? this.unavailableNum,
);
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['available_num'] = availableNum;
map['unavailable_num'] = unavailableNum;
return map;
}
}
\ No newline at end of file
......@@ -11,6 +11,10 @@ class BookPayController extends GetxController {
// 是否使用积分
bool useCreditPoint = false;
// 优惠券可用不可用数量模型
CouponNumModel couponNumModel = CouponNumModel();
// 选择的优惠券模型
late CouponModel useCouponModel = CouponModel(couponId: 0,reducedPrice: '0.00');
// 支付方式
List<PayModel> pays = Platform.isIOS ?[
......@@ -29,23 +33,34 @@ class BookPayController extends GetxController {
late double finalPrice = 0.00;
@override
void onReady() {
_getCreditPoints(price: '100');
_getCreditPoints(price: originalPrice.toString());
_getShow();
computeFinalPrice();
_getCouponNumber();
super.onReady();
}
// 支付方式
/// 使用优惠券
void setUseCoupon(CouponModel model){
useCouponModel = model;
print('使用优惠券。。。。。。。。。。。。。。。。');
computeFinalPrice();
}
/// 支付方式 默认第一个
late PayModel _payModel = pays.first;
PayModel get payModel => _payModel;
/// 选择积分状态
void show(){
showDetail = !showDetail;
update();
}
/// 设置支付渠道
void setPayModel(PayModel payModel){
for (PayModel model in pays) {
if (model.type == payModel.type){
......@@ -59,6 +74,7 @@ class BookPayController extends GetxController {
update();
}
/// 是否使用积分
void setUse(){
useCreditPoint = !useCreditPoint;
// 计算
......@@ -74,12 +90,18 @@ class BookPayController extends GetxController {
creditPointModel = await ShopAPI.creditPoints(price: price);
update();
}
/// 是否展示优惠券 和积分使用 模型
void _getShow () async {
showModel = await ShopAPI.show();
update();
}
/// 获取优惠券可用数量与不可用数量模型
void _getCouponNumber() async{
couponNumModel = await ShopAPI.couponNum(price: originalPrice.toString());
update();
}
/// 获取优惠前的价钱
/// 总价钱
......@@ -101,6 +123,10 @@ class BookPayController extends GetxController {
if (useCreditPoint){
finalPrice = finalPrice - Decimal.parse(creditPointModel.deductibleAmount??'0.00').toDouble();
}
// 不等0的时候证明使用了 优惠券
if (useCouponModel.couponId !=0){
finalPrice = finalPrice - Decimal.parse(useCouponModel.reducedPrice??'0.00').toDouble();
}
update();
}
......
......@@ -55,7 +55,7 @@ class _BookPayPageState extends State<BookPayPage> {
controller.showModel.couponSwitch =='0'?const SizedBox():GestureDetector(
child: _buildCouponWidget(controller,title: '优惠券',icon: 'assets/images/pay_coupon.png',),
onTap: (){
context.pushNamed(Routes.payCoupon);
context.pushNamed(Routes.payCoupon,extra: controller);
},
),
Container(height: 0.5.w,color: Colours.cF0,margin: EdgeInsets.only(left: 10.w),),
......@@ -109,7 +109,7 @@ class _BookPayPageState extends State<BookPayPage> {
showTap: (){
controller.show();
Console.log('--------------展示优惠详情------------------');
}
}, controller: controller,
)),
),
controller.showDetail?Positioned(
......@@ -153,7 +153,7 @@ class _BookPayPageState extends State<BookPayPage> {
child: const Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('应付明细',textAlign:TextAlign.center),
Text('应付明细',textAlign:TextAlign.center,style: TextStyle(fontSize: 15,height: 1.1,color: Colours.c3,fontWeight: Fonts.medium),),
],
),
),
......@@ -182,25 +182,25 @@ class _BookPayPageState extends State<BookPayPage> {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('总价',style: TextStyle(fontSize: 16.w,height: 1.5,color: Colours.c3,fontWeight: Fonts.medium),),
Text('¥199.80',style: TextStyle(fontSize: 15.w,height: 1.5,color: AppTheme.primary,fontWeight: Fonts.medium),)
Text('¥${controller.finalPrice}',style: TextStyle(fontSize: 15.w,height: 1.5,color: AppTheme.primary,fontWeight: Fonts.medium),)
],
),
Gaps.vGaps15,
Row(
controller.showModel.couponSwitch =='1'? Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('优惠券抵扣',style: TextStyle(fontSize: 13.w,height: 1.5,color: Colours.c9,),),
Text('减¥199.80',style: TextStyle(fontSize: 13.w,height: 1.5,color: AppTheme.primary),)
Text('减¥${controller.useCouponModel.reducedPrice}',style: TextStyle(fontSize: 13.w,height: 1.5,color: AppTheme.primary),)
],
),
):const SizedBox(),
Gaps.vGaps10,
Row(
controller.showModel.integralSwitch =='1'? Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('积分抵扣',style: TextStyle(fontSize: 13.w,height: 1.5,color: Colours.c9,),),
Text('减¥199.80',style: TextStyle(fontSize: 13.w,height: 1.5,color: AppTheme.primary),)
Text('减¥${controller.useCreditPoint?controller.creditPointModel.deductibleAmount:'0.00'}',style: TextStyle(fontSize: 13.w,height: 1.5,color: AppTheme.primary),)
],
)
):const SizedBox()
],
),
)
......@@ -232,12 +232,30 @@ class _BookPayPageState extends State<BookPayPage> {
Text(title,style: TextStyle(fontSize: 14.w,color: Colours.c3,height: 1.1)),
],
),
SizedBox(
// color: Colors.cyan,
width:5.w,
height:8.w,
child: Image.asset('assets/images/right_arrow.png'),
),
Row(
children: [
controller.useCouponModel.couponId!=0?Row(
children: [
Text('「满${controller.useCouponModel.normPrice}${controller.useCouponModel.reducedPrice}」-¥${controller.useCouponModel.reducedPrice}',style: TextStyle(fontSize: 13.w,height: 1.3,color: AppTheme.primary),),
Gaps.hGaps10,
GestureDetector(
child: Image.asset('assets/images/unused_coupon.png'),
onTap: (){
CouponModel model = CouponModel(couponId: 0);
controller.setUseCoupon(model);
},
)
],
):controller.couponNumModel.availableNum ==0?Text('暂无可用',style: TextStyle(fontSize:13.w,color: Colours.c9,height:1.4)):Text('${controller.couponNumModel.availableNum??''}个可用',style: TextStyle(fontSize:13.w,color: AppTheme.primary,height:1.4)),
Gaps.hGaps10,
SizedBox(
// color: Colors.cyan,
width:5.w,
height:8.w,
child: Image.asset('assets/images/right_arrow.png'),
),
],
)
],
),
);
......
......@@ -3,10 +3,12 @@ part of book_pay;
class BuildPayCount extends StatelessWidget {
final void Function()? payTap;
final void Function()? showTap;
final BookPayController controller;
const BuildPayCount({
Key? key,
required this.payTap,
required this.showTap,
required this.controller
}) : super(key: key);
......@@ -22,20 +24,23 @@ class BuildPayCount extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
GestureDetector(
onTap: showTap,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text('应付:',style: TextStyle(fontSize:14.w,color: Colours.c3 ,height: 1.1),),
Text('¥${controller.finalPrice}',style: TextStyle(fontSize:15.w,color:AppTheme.primary,fontWeight: Fonts.medium ,height: 1.1),),
SizedBox(
// color: Colors.cyan,
width: 20.w,
height: 20.w,
child: Image.asset('assets/images/pay_up.png')
)
],
IgnorePointer(
ignoring: controller.showModel.integralSwitch =='0'&& controller.showModel.couponSwitch ==''?true:false,
child: GestureDetector(
onTap: showTap,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text('应付:',style: TextStyle(fontSize:14.w,color: Colours.c3 ,height: 1.1),),
Text('¥${controller.finalPrice}',style: TextStyle(fontSize:15.w,color:AppTheme.primary,fontWeight: Fonts.medium ,height: 1.1),),
controller.showModel.integralSwitch =='1'&& controller.showModel.couponSwitch =='1'?SizedBox(
// color: Colors.cyan,
width: 20.w,
height: 20.w,
child: Image.asset('assets/images/pay_up.png')
):const SizedBox()
],
),
),
),
GestureDetector(
......
part of pay_coupon;
class PayCouponController extends GetxController with GetSingleTickerProviderStateMixin{
final String tag;
PayCouponController(this.tag);
final BookPayController payController;
PayCouponController(this.tag,this.payController){
// tabs = [
// Tab(text: '可用(${payController.couponNumModel.availableNum})',),
// Tab(text: '不可用(${payController.couponNumModel.unavailableNum})',),
// ];
}
List <Widget>tabs = [
const Tab(text: '可用',),
const Tab(text: '不可用',),
];
late TabController tabController = TabController(length:tabs.length, vsync: this);
// List <Widget>tabs = [];
// late TabController tabController = TabController(length:tabs.length, vsync: this);
final EasyRefreshController refreshController = EasyRefreshController(
controlFinishLoad: true,
......@@ -36,11 +40,11 @@ class PayCouponController extends GetxController with GetSingleTickerProviderSta
type: tag,
price: price
);
for(CouponModel model in result.list!) {
print('================================${tag}');
model.type = num.parse(tag);
}
tabs = [
Tab(text: '可用(${tag =='0'?result.list!.length:''})',),
Tab(text: '不可用(${tag =='1'?result.list!.length:''})',),
];
// 如果是刷新 清理数据
if (isRefresh) coupons.clear();
......
......@@ -7,11 +7,13 @@ import 'package:flutter_book/pages/user_coupon/index.dart';
import 'package:flutter_book/widgets/index.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:go_router/go_router.dart';
import '../../apis/index.dart';
import '../../models/index.dart';
import '../../theme.dart';
import '../../utils/index.dart';
import '../book_pay/index.dart';
part 'view.dart';
......
......@@ -3,18 +3,34 @@ part of pay_coupon;
class PayCouponPage extends StatefulWidget {
const PayCouponPage({Key? key}) : super(key: key);
final BookPayController payController;
const PayCouponPage({
Key? key,
required this.payController
}) : super(key: key);
@override
State<PayCouponPage> createState() => _PayCouponPageState();
}
class _PayCouponPageState extends State<PayCouponPage> {
class _PayCouponPageState extends State<PayCouponPage> with SingleTickerProviderStateMixin{
List <Widget> tabs= [];
late TabController tabController;
@override
void initState() {
tabs = [
Tab(text: '可用(${widget.payController.couponNumModel.availableNum})',),
Tab(text: '不可用(${widget.payController.couponNumModel.unavailableNum})',),
];
tabController = TabController(length:tabs.length, vsync: this);
super.initState();
}
@override
Widget build(BuildContext context) {
return GetBuilder<PayCouponController>(
init: PayCouponController('main'),
builder: (controller) =>Scaffold(
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text('选择优惠券'),
......@@ -28,41 +44,44 @@ class _PayCouponPageState extends State<PayCouponPage> {
unselectedLabelStyle: TextStyle(fontSize: 15.w,height: 1.4),
indicatorSize: TabBarIndicatorSize.label,
indicatorColor: AppTheme.primary,
tabs:controller.tabs,
tabs:tabs,
physics: const NeverScrollableScrollPhysics(),
controller: controller.tabController,
controller: tabController,
),
Expanded(
child: TabBarView(
controller: controller.tabController,
children: List.generate(controller.tabs.length, (index){
return CouponPage(tag:'$index');
controller: tabController,
children: List.generate(tabs.length, (index){
return CouponPage(tag:'${1-index}',payController: widget.payController,);
})
),
),
],
),
),
);
);
}
}
class CouponPage extends StatefulWidget {
final String tag;
final BookPayController payController;
const CouponPage({
Key? key,
required this.tag
required this.tag,
required this.payController
}) : super(key: key);
@override
State<CouponPage> createState() => _CouponPageState();
}
class _CouponPageState extends State<CouponPage> {
class _CouponPageState extends State<CouponPage> with AutomaticKeepAliveClientMixin{
@override
Widget build(BuildContext context) {
return GetBuilder<PayCouponController>(
init: PayCouponController(widget.tag),
tag: widget.tag,
init: PayCouponController(widget.tag,widget.payController),
builder: (controller) =>CustomPullScrollView(
controller: controller.refreshController,
onRefresh: controller.onRefresh,
......@@ -70,13 +89,19 @@ class _CouponPageState extends State<CouponPage> {
child: ListView.builder(
itemBuilder: (BuildContext context, int index){
CouponModel model = controller.coupons[index];
return BuildItem(model:model,);
return BuildItem(model:model,useTap: (){
widget.payController.setUseCoupon(model);
context.pop();
},);
},
itemCount: controller.coupons.length,
),
),
);
}
@override
bool get wantKeepAlive => true;
}
......
......@@ -2,9 +2,11 @@ part of pay_coupon;
class BuildItem extends StatelessWidget {
final CouponModel model;
final void Function()? useTap;
const BuildItem({
Key? key,
required this.model
required this.model,
required this.useTap
}) : super(key: key);
@override
......@@ -28,7 +30,7 @@ class BuildItem extends StatelessWidget {
children: [
Stack(
children: [
Image.asset('assets/images/coupon_yes.png'),
Image.asset(model.type ==1?'assets/images/coupon_yes.png':'assets/images/coupon_no.png'),
Positioned(
left: 0.w,
right: 0.w,
......@@ -42,16 +44,16 @@ class BuildItem extends StatelessWidget {
children: <TextSpan>[
TextSpan(
text: '¥',
style: TextStyle(fontSize: 15.w,fontWeight: Fonts.boldSemi,height: 1.5,color: Colors.white)
style: TextStyle(fontSize: 15.w,fontWeight: Fonts.boldSemi,height: 1.5,color: model.type ==1?Colors.white:Colours.cC8)
),
TextSpan(
text: '5',
style: TextStyle(fontSize: 40.w,fontWeight: Fonts.boldSemi,height: 1.5,color: Colors.white)
text: model.reducedPrice??'',
style: TextStyle(fontSize: 40.w,fontWeight: Fonts.boldSemi,height: 1.5,color: model.type ==1?Colors.white:Colours.cC8)
),
]
),
),
Text('满${model.normPrice}可用',style: TextStyle(fontSize: 11.w,height: 1.5,color: Colors.white),)
Text('满${model.normPrice}可用',style: TextStyle(fontSize: 11.w,height: 1.5,color: model.type ==1?Colors.white:Colours.cC8),)
],
),
)
......@@ -67,24 +69,27 @@ class BuildItem extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(model.couponName??'',style: TextStyle(fontSize: 16.w,fontWeight: Fonts.medium,height: 1.5,color: Colours.c3),),
Text(model.couponName??'',style: TextStyle(fontSize: 16.w,fontWeight: Fonts.medium,height: 1.5,color: model.type ==1?Colours.c3:Colours.c9),),
Gaps.vGaps5,
Text('满${model.normPrice}${model.reducedPrice}元',style: TextStyle(fontSize: 12.w,height: 1.5,color: Colours.c9),),
Gaps.vGaps5,
Text('有效',style: TextStyle(fontSize: 12.w,height: 1.5,color: Colours.c9),),
Text('有效至:${model.endTime}',style: TextStyle(fontSize: 12.w,height: 1.5,color: Colours.c9),),
],
),
Container(
width: 65.w,
height: 24.w,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.w),
color: Colors.white,
border: Border.all(width: 1.w,color: AppTheme.primary)
if (model.type == 1) GestureDetector(
onTap: useTap,
child: Container(
width: 65.w,
height: 24.w,
alignment: Alignment.center,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.w),
color: Colors.white,
border: Border.all(width: 1.w,color: AppTheme.primary)
),
child: Text('立即使用',style: TextStyle(fontSize: 12.w,fontWeight: Fonts.medium,color: AppTheme.primary),),
),
child: Text('立即使用',style: TextStyle(fontSize: 12.w,fontWeight: Fonts.medium,color: AppTheme.primary),),
)
) else const SizedBox()
],
),
),
......
......@@ -287,7 +287,9 @@ abstract class Routes {
pageBuilder: (context, state) =>CupertinoPage(
name: state.uri.toString(),
key: state.pageKey,
child: const PayCouponPage()
child: PayCouponPage(
payController: state.extra as BookPayController,
)
)
),
GoRoute(
......
......@@ -35,6 +35,7 @@ class Colours {
static const cF8 = Color(0xFFF8F8F8);
static const cF9 = Color(0xFFF9F9F9);
static const cC7 = Color(0xFFC7C7C7);
static const cC8 = Color(0xFFC8C8C8);
static const cAB1941 = Color(0xB3AB1941);
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论