You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
636 lines
24 KiB
636 lines
24 KiB
import 'package:flutter/material.dart'; |
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; |
|
import 'package:huixiang/view_widget/my_appbar.dart'; |
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
|
import '../../../generated/l10n.dart'; |
|
import '../../../retrofit/business_api.dart'; |
|
import '../../../retrofit/data/set_specs_meal_list.dart'; |
|
import '../../../utils/font_weight.dart'; |
|
import '../../../view_widget/border_text.dart'; |
|
import '../../../view_widget/round_button.dart'; |
|
import '../../../view_widget/settlement_tips_dialog.dart'; |
|
|
|
class SetMeal extends StatefulWidget { |
|
final Map<String, dynamic> arguments; |
|
|
|
SetMeal({this.arguments}); |
|
|
|
@override |
|
State<StatefulWidget> createState() { |
|
return _SetMeal(); |
|
} |
|
} |
|
|
|
class _SetMeal extends State<SetMeal> { |
|
List<SetSpecsMealList> specsMeal = []; |
|
bool isKeyBoardShow = false; |
|
FocusNode _focusNode = FocusNode(); |
|
BusinessApiService businessService; |
|
|
|
@override |
|
void initState() { |
|
super.initState(); |
|
WidgetsBinding.instance.addPostFrameCallback((_) { |
|
setState(() { |
|
print("object: ${MediaQuery.of(context).viewInsets.bottom}"); |
|
if (MediaQuery.of(context).viewInsets.bottom == 0) { |
|
if (isKeyBoardShow) { |
|
isKeyBoardShow = false; |
|
//关闭键盘 软键盘关闭了, 清除输入控件的焦点, 否则重新进入页面会导致软键盘再弹出问题 |
|
FocusScope.of(context).requestFocus(FocusNode()); |
|
} |
|
} else { |
|
isKeyBoardShow = true; |
|
} |
|
}); |
|
}); |
|
List<dynamic> mealDetails = widget?.arguments["mealDetails"] ??[]; |
|
mealDetails.forEach((element) { |
|
var tempValue = SetSpecsMealList(); |
|
tempValue.groupsNameController.text = element["groupName"]; |
|
tempValue.groupsTotal = element["totalNumber"]; |
|
tempValue.optionalNum = element["optionalNumber"]; |
|
tempValue.goodsMeal = element["productInfoList"]; |
|
specsMeal.add(tempValue); |
|
}); |
|
} |
|
|
|
///离开页面记着销毁和清除 |
|
@override |
|
void dispose() { |
|
_focusNode.unfocus(); |
|
super.dispose(); |
|
} |
|
|
|
@override |
|
Widget build(BuildContext context) { |
|
return GestureDetector( |
|
behavior: HitTestBehavior.opaque, |
|
onTap: () { |
|
FocusScope.of(context).unfocus(); |
|
}, |
|
child: Scaffold( |
|
resizeToAvoidBottomInset: false, |
|
appBar: MyAppBar( |
|
title: "套餐选择", |
|
titleColor: Colors.black, |
|
background: Colors.white, |
|
leadingColor: Colors.black, |
|
brightness: Brightness.dark, |
|
action: GestureDetector( |
|
onTap: () { |
|
bool flag = false; |
|
String tipText = ""; |
|
int index = 0; |
|
List<dynamic> mealDetail = []; |
|
if (specsMeal.length != 0) { |
|
specsMeal.forEach((element) { |
|
index += 1; |
|
if (element.groupsNameController.text.trim() == "") { |
|
flag = true; |
|
tipText = "分组$index未填写分组名"; |
|
return; |
|
} else if (element.goodsMeal.length == 0 || |
|
element.goodsMeal.length != element.groupsTotal) { |
|
flag = true; |
|
tipText = |
|
"分组${element.groupsNameController.text}已选商品数量与设定分组总数不符,请修改"; |
|
return; |
|
} else if (element.optionalNum > element.groupsTotal) { |
|
flag = true; |
|
tipText = |
|
"分组${element.groupsNameController.text}可选数量不可大于分组总数"; |
|
return; |
|
} |
|
mealDetail.add({ |
|
"groupName": element.groupsNameController.text, |
|
"totalNumber":element.groupsTotal, |
|
"optionalNumber":element.optionalNum, |
|
"productInfoList":element.goodsMeal |
|
}); |
|
}); |
|
if (flag) { |
|
SmartDialog.show( |
|
clickBgDismissTemp: false, |
|
widget: SettlementTips( |
|
() {}, |
|
text: tipText, |
|
color: Color(0xFF30415B), |
|
)); |
|
} else { |
|
Navigator.of(context).pop(mealDetail); |
|
} |
|
} else { |
|
SmartDialog.show( |
|
clickBgDismissTemp: false, |
|
widget: SettlementTips( |
|
() {}, |
|
text: "请添加设置分组后再点击确实按钮", |
|
color: Color(0xFF30415B), |
|
)); |
|
} |
|
}, |
|
child: Text( |
|
"确定", |
|
style: TextStyle( |
|
color: Color(0xFF30415B), |
|
fontSize: 14.sp, |
|
fontWeight: MyFontWeight.bold, |
|
), |
|
), |
|
), |
|
), |
|
body: Stack( |
|
children: [ |
|
SingleChildScrollView( |
|
physics: BouncingScrollPhysics(), |
|
child: Container( |
|
margin: EdgeInsets.only(bottom: 150.h), |
|
child: Column( |
|
crossAxisAlignment: CrossAxisAlignment.start, |
|
children: [ |
|
ListView.builder( |
|
padding: EdgeInsets.zero, |
|
itemCount: specsMeal.length, |
|
scrollDirection: Axis.vertical, |
|
shrinkWrap: true, |
|
physics: BouncingScrollPhysics(), |
|
itemBuilder: (context, position) { |
|
return GestureDetector( |
|
behavior: HitTestBehavior.opaque, |
|
onTap: () { |
|
FocusScope.of(context).unfocus(); |
|
}, |
|
child: mealText(position)); |
|
}, |
|
), |
|
GestureDetector( |
|
behavior: HitTestBehavior.opaque, |
|
onTap: () { |
|
setState(() { |
|
specsMeal.add(SetSpecsMealList()); |
|
}); |
|
}, |
|
child: Container( |
|
color: Colors.white, |
|
padding: EdgeInsets.symmetric(vertical: 20.h), |
|
child: Row( |
|
mainAxisAlignment: MainAxisAlignment.center, |
|
children: [ |
|
Icon( |
|
Icons.add_circle, |
|
color: Color(0xFF30415B), |
|
size: 20, |
|
), |
|
Padding( |
|
padding: EdgeInsets.only(left: 7.w), |
|
child: Text( |
|
"添加分组", |
|
style: TextStyle( |
|
color: Color(0xD9000000), |
|
fontSize: 14.sp, |
|
fontWeight: MyFontWeight.bold, |
|
), |
|
), |
|
), |
|
], |
|
), |
|
), |
|
), |
|
], |
|
), |
|
)), |
|
], |
|
), |
|
)); |
|
} |
|
|
|
///添加套餐分组样式 |
|
Widget mealText(index) { |
|
return Column( |
|
children: [ |
|
Container( |
|
color: Colors.white, |
|
margin: EdgeInsets.symmetric(vertical: 12.h), |
|
padding: EdgeInsets.only(left: 16.w, right: 16.w, bottom: 12.h), |
|
child: Column( |
|
crossAxisAlignment: CrossAxisAlignment.start, |
|
children: [ |
|
Row( |
|
crossAxisAlignment: CrossAxisAlignment.center, |
|
mainAxisAlignment: MainAxisAlignment.center, |
|
children: [ |
|
Expanded( |
|
child: Text( |
|
"分组${index + 1}", |
|
style: TextStyle( |
|
color: Color(0xD9000000), |
|
fontSize: 14.sp, |
|
fontWeight: MyFontWeight.bold, |
|
), |
|
), |
|
), |
|
Expanded( |
|
child: TextField( |
|
controller: specsMeal[index].groupsNameController, |
|
decoration: InputDecoration( |
|
hintText: "请输入分组名称", |
|
hintTextDirection: TextDirection.rtl, |
|
hintStyle: TextStyle( |
|
color: Color(0xFF7A797F), |
|
fontSize: 14.sp, |
|
fontWeight: MyFontWeight.bold, |
|
), |
|
border: InputBorder.none, |
|
), |
|
textAlign: TextAlign.right, |
|
style: TextStyle( |
|
color: Color(0xFF0D0D0D), |
|
fontSize: 14.sp, |
|
fontWeight: MyFontWeight.bold), |
|
), |
|
flex: 2, |
|
), |
|
], |
|
), |
|
Container( |
|
width: double.infinity, |
|
height: 1.h, |
|
color: Color(0x14000000), |
|
), |
|
Padding( |
|
padding: EdgeInsets.symmetric(vertical: 14.h), |
|
child: Row( |
|
crossAxisAlignment: CrossAxisAlignment.center, |
|
mainAxisAlignment: MainAxisAlignment.center, |
|
children: [ |
|
Expanded( |
|
child: Text( |
|
"分组总数", |
|
style: TextStyle( |
|
color: Color(0xD9000000), |
|
fontSize: 14.sp, |
|
fontWeight: MyFontWeight.bold, |
|
), |
|
), |
|
), |
|
GestureDetector( |
|
behavior: HitTestBehavior.opaque, |
|
onTap: () { |
|
setState(() { |
|
if (specsMeal[index].groupsTotal <= 1) return; |
|
specsMeal[index].groupsTotal = |
|
specsMeal[index].groupsTotal - 1; |
|
}); |
|
}, |
|
child: Container( |
|
padding: EdgeInsets.symmetric(horizontal: 20.w), |
|
child: Icon( |
|
Icons.remove_circle_outline, |
|
color: Color(0xFF30415B), |
|
size: 24, |
|
))), |
|
Text( |
|
specsMeal[index].groupsTotal.toString(), |
|
style: TextStyle( |
|
color: Color(0xD9000000), |
|
fontSize: 20.sp, |
|
fontWeight: MyFontWeight.regular, |
|
), |
|
), |
|
GestureDetector( |
|
behavior: HitTestBehavior.opaque, |
|
onTap: () { |
|
setState(() { |
|
specsMeal[index].groupsTotal = |
|
specsMeal[index].groupsTotal + 1; |
|
}); |
|
}, |
|
child: Container( |
|
padding: EdgeInsets.only(left: 20.w), |
|
child: Icon( |
|
Icons.add_circle, |
|
color: Color(0xFF30415B), |
|
size: 24, |
|
)), |
|
), |
|
], |
|
)), |
|
Container( |
|
width: double.infinity, |
|
height: 1.h, |
|
color: Color(0x14000000), |
|
margin: EdgeInsets.only(bottom: 18.h), |
|
), |
|
Padding( |
|
padding: EdgeInsets.only(bottom: 14.h), |
|
child: Row( |
|
crossAxisAlignment: CrossAxisAlignment.center, |
|
mainAxisAlignment: MainAxisAlignment.center, |
|
children: [ |
|
Expanded( |
|
child: Text( |
|
"可选数量", |
|
style: TextStyle( |
|
color: Color(0xD9000000), |
|
fontSize: 14.sp, |
|
fontWeight: MyFontWeight.bold, |
|
), |
|
), |
|
), |
|
GestureDetector( |
|
behavior: HitTestBehavior.opaque, |
|
onTap: () { |
|
setState(() { |
|
if (specsMeal[index].optionalNum <= 1) return; |
|
specsMeal[index].optionalNum = |
|
specsMeal[index].optionalNum - 1; |
|
}); |
|
}, |
|
child: Container( |
|
padding: EdgeInsets.symmetric(horizontal: 20.w), |
|
child: Icon( |
|
Icons.remove_circle_outline, |
|
color: Color(0xFF30415B), |
|
size: 24, |
|
))), |
|
Text( |
|
specsMeal[index].optionalNum.toString(), |
|
style: TextStyle( |
|
color: Color(0xD9000000), |
|
fontSize: 20.sp, |
|
fontWeight: MyFontWeight.regular, |
|
), |
|
), |
|
GestureDetector( |
|
behavior: HitTestBehavior.opaque, |
|
onTap: () { |
|
setState(() { |
|
specsMeal[index].optionalNum = |
|
specsMeal[index].optionalNum + 1; |
|
}); |
|
}, |
|
child: Container( |
|
padding: EdgeInsets.only(left: 20.w), |
|
child: Icon( |
|
Icons.add_circle, |
|
color: Color(0xFF30415B), |
|
size: 24, |
|
)), |
|
), |
|
], |
|
)), |
|
Container( |
|
width: double.infinity, |
|
height: 1.h, |
|
color: Color(0x14000000), |
|
margin: EdgeInsets.only(bottom: 18.h), |
|
), |
|
Padding( |
|
padding: EdgeInsets.only(bottom: 12.h), |
|
child: Row( |
|
mainAxisAlignment: MainAxisAlignment.center, |
|
children: [ |
|
GestureDetector( |
|
behavior: HitTestBehavior.opaque, |
|
onTap: () { |
|
Navigator.of(context).pushNamed('/router/batch_shelf', |
|
arguments: { |
|
"storeId": widget.arguments["storeId"], |
|
"titleName": "选择商品", |
|
"groupNum": specsMeal[index].groupsTotal |
|
}).then((value) { |
|
if (value != null && value is List) { |
|
if (specsMeal[index].goodsMeal == null) { |
|
specsMeal[index].goodsMeal = []; |
|
} |
|
specsMeal[index].goodsMeal.clear(); |
|
specsMeal[index].goodsMeal.addAll(value.map((e) => e as Map<String, dynamic>).toList()); |
|
setState(() {}); |
|
} |
|
}); |
|
}, |
|
child: Container( |
|
alignment: Alignment.center, |
|
padding: EdgeInsets.only( |
|
left: 8.w, right: 8.w, bottom: 3.h), |
|
decoration: BoxDecoration( |
|
color: Colors.white, |
|
border: Border.all( |
|
color: Color(0xFF2E3552), |
|
width: 1, |
|
), |
|
borderRadius: BorderRadius.circular(100), |
|
), |
|
child: Text( |
|
"+增加商品", |
|
style: TextStyle( |
|
color: Color(0xFF30415B), |
|
fontSize: 14.sp, |
|
fontWeight: MyFontWeight.regular, |
|
), |
|
), |
|
)), |
|
Spacer(), |
|
GestureDetector( |
|
onTap: () { |
|
deleteGroupsDialog(index); |
|
}, |
|
child: Row( |
|
mainAxisAlignment: MainAxisAlignment.end, |
|
children: [ |
|
Icon( |
|
Icons.remove_circle, |
|
color: Color(0xFFFA5151), |
|
size: 24, |
|
), |
|
Padding( |
|
padding: EdgeInsets.only(left: 7.w), |
|
child: Text( |
|
"删除分组", |
|
style: TextStyle( |
|
color: Color(0xD9000000), |
|
fontSize: 14.sp, |
|
fontWeight: MyFontWeight.bold, |
|
), |
|
), |
|
), |
|
], |
|
), |
|
) |
|
], |
|
), |
|
), |
|
Text( |
|
"*请添加或减少商品,直到达到分组总数", |
|
style: TextStyle( |
|
color: Color(0xFFFA5151), |
|
fontSize: 12.sp, |
|
fontWeight: MyFontWeight.regular, |
|
), |
|
), |
|
], |
|
), |
|
), |
|
ListView.builder( |
|
itemCount: specsMeal[index]?.goodsMeal?.length ?? 0, |
|
physics: BouncingScrollPhysics(), |
|
shrinkWrap: true, |
|
itemBuilder: (context, position) { |
|
return GestureDetector( |
|
behavior: HitTestBehavior.opaque, |
|
onTap: () {}, |
|
child: addGoodsItem(index, position), |
|
); |
|
}, |
|
) |
|
], |
|
); |
|
} |
|
|
|
///删除分组弹窗提示 |
|
deleteGroupsDialog(index) { |
|
showDialog( |
|
context: context, |
|
builder: (context) { |
|
return AlertDialog( |
|
content: Container( |
|
width: MediaQuery.of(context).size.width - 84, |
|
height: 139.h, |
|
child: Column( |
|
mainAxisAlignment: MainAxisAlignment.center, |
|
crossAxisAlignment: CrossAxisAlignment.center, |
|
children: [ |
|
Text( |
|
"此操作将直接删除当前分组, 是否继续?", |
|
style: TextStyle( |
|
color: Color(0xFFF4524D), |
|
fontSize: 16.sp, |
|
fontWeight: MyFontWeight.regular, |
|
), |
|
), |
|
SizedBox( |
|
height: 35.h, |
|
), |
|
Row( |
|
children: [ |
|
Expanded( |
|
child: InkWell( |
|
child: BorderText( |
|
text: S.of(context).quxiao, |
|
textColor: Color(0xFF30415B), |
|
fontSize: 16.sp, |
|
fontWeight: FontWeight.bold, |
|
borderColor: Color(0xFF30415B), |
|
radius: 4, |
|
padding: EdgeInsets.all(12), |
|
borderWidth: 1, |
|
), |
|
onTap: () { |
|
Navigator.of(context).pop(); |
|
}, |
|
), |
|
flex: 1, |
|
), |
|
SizedBox( |
|
width: 16.w, |
|
), |
|
Expanded( |
|
child: InkWell( |
|
child: RoundButton( |
|
text: S.of(context).queren, |
|
textColor: Colors.white, |
|
radius: 4, |
|
padding: EdgeInsets.all(12), |
|
backgroup: Color(0xFF30415B), |
|
fontSize: 16.sp, |
|
fontWeight: FontWeight.bold, |
|
), |
|
onTap: () { |
|
setState((){ |
|
Navigator.of(context).pop(); |
|
specsMeal.removeAt(index); |
|
}); |
|
}, |
|
), |
|
flex: 1, |
|
), |
|
], |
|
) |
|
], |
|
), |
|
), |
|
); |
|
}, |
|
); |
|
} |
|
|
|
///增加商品Item |
|
Widget addGoodsItem(specsIndex, index) { |
|
return Container( |
|
color: Colors.white, |
|
margin: EdgeInsets.symmetric(vertical: 8), |
|
padding: EdgeInsets.only( |
|
left: 16.w, |
|
top: 20.h, |
|
bottom: 20.h, |
|
), |
|
child: Row( |
|
crossAxisAlignment: CrossAxisAlignment.start, |
|
mainAxisAlignment: MainAxisAlignment.center, |
|
children: [ |
|
Expanded( |
|
child: Text( |
|
specsMeal[specsIndex]?.goodsMeal[index]["productName"] ?? "", |
|
maxLines: 1, |
|
overflow: TextOverflow.ellipsis, |
|
style: TextStyle( |
|
color: Color(0xFF000000), |
|
fontSize: 14.sp, |
|
fontWeight: MyFontWeight.regular, |
|
), |
|
), |
|
flex: 2, |
|
), |
|
Expanded( |
|
child: Text( |
|
"所有规格", |
|
textAlign: TextAlign.center, |
|
style: TextStyle( |
|
color: Color(0xFF000000), |
|
fontSize: 14.sp, |
|
fontWeight: MyFontWeight.regular, |
|
), |
|
), |
|
), |
|
Expanded( |
|
child: Text( |
|
specsMeal[specsIndex]?.goodsMeal[index]["number"] ?? "", |
|
textAlign: TextAlign.center, |
|
style: TextStyle( |
|
color: Color(0xFF000000), |
|
fontSize: 14.sp, |
|
fontWeight: MyFontWeight.regular, |
|
), |
|
)), |
|
GestureDetector( |
|
behavior: HitTestBehavior.opaque, |
|
onTap: () { |
|
setState(() { |
|
specsMeal[specsIndex].goodsMeal.removeAt(index); |
|
}); |
|
}, |
|
child: Container( |
|
padding: EdgeInsets.only(right: 31.h), |
|
child: Icon( |
|
Icons.remove_circle, |
|
color: Color(0xFFFA5151), |
|
size: 20, |
|
), |
|
), |
|
) |
|
], |
|
), |
|
); |
|
} |
|
}
|
|
|