新增:店铺信息开启关闭时间,预约信息保存,确认扣款接口; 商品列表实体类更改; 自定义选择器适配更改; 新增预约/预售页面; 在售页面商品列表ui更改; 订单列表新增确认扣款按钮,新增确认扣款提示弹窗; 订单页面日期选择器优化更改; 票券列表,票券记录金额ui更改; 票券板块日期选择器更改; 生意总览:商品,总览,订单页面自定义时间选择器更改; app-我的-个人信息页面,更改用户信息时,接口请求失败新增失败提示; 新增店铺信息开启关闭时间实体类;wr_2023_business
After Width: | Height: | Size: 860 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1020 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 632 B |
After Width: | Height: | Size: 720 B |
After Width: | Height: | Size: 696 B |
After Width: | Height: | Size: 776 B |
After Width: | Height: | Size: 712 B |
@ -0,0 +1,813 @@ |
|||||||
|
import 'package:dio/dio.dart'; |
||||||
|
import 'package:flutter/cupertino.dart'; |
||||||
|
import 'package:flutter/material.dart'; |
||||||
|
import 'package:flutter_easyloading/flutter_easyloading.dart'; |
||||||
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; |
||||||
|
import 'package:pull_to_refresh/pull_to_refresh.dart'; |
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
||||||
|
import '../../../retrofit/business_api.dart'; |
||||||
|
import '../../../utils/font_weight.dart'; |
||||||
|
import '../../generated/l10n.dart'; |
||||||
|
import '../../retrofit/data/base_data.dart'; |
||||||
|
import '../../retrofit/data/business_goods.dart'; |
||||||
|
import '../../retrofit/data/store_time_info_list.dart'; |
||||||
|
import '../../utils/business_instance.dart'; |
||||||
|
import '../../utils/flutter_utils.dart'; |
||||||
|
import '../../view_widget/my_appbar.dart'; |
||||||
|
|
||||||
|
class ReservationPage extends StatefulWidget { |
||||||
|
final Map<String, dynamic> arguments; |
||||||
|
|
||||||
|
ReservationPage({this.arguments}); |
||||||
|
|
||||||
|
@override |
||||||
|
State<StatefulWidget> createState() { |
||||||
|
return _ReservationPage(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class _ReservationPage extends State<ReservationPage> { |
||||||
|
final RefreshController _refreshController = RefreshController(); |
||||||
|
BusinessApiService businessService; |
||||||
|
String networkError = ""; |
||||||
|
int networkStatus = 0; |
||||||
|
final TextEditingController editingController = TextEditingController(); |
||||||
|
final TextEditingController daysAfterController = TextEditingController(); |
||||||
|
final TextEditingController daysWithinController = TextEditingController(); |
||||||
|
FocusNode _focusNode = FocusNode(); |
||||||
|
bool isKeyBoardShow = false; |
||||||
|
bool _subscribeSwitch = false; |
||||||
|
bool _paySubscribeSwitch = false; |
||||||
|
StoreTimeInfoList storeTimeInfoList; |
||||||
|
List<String> timeSlots = []; |
||||||
|
SubscribeParam subscribeParam; |
||||||
|
String selectTimeDate = ""; |
||||||
|
|
||||||
|
///离开页面记着销毁和清除 |
||||||
|
@override |
||||||
|
void dispose() { |
||||||
|
super.dispose(); |
||||||
|
_refreshController.dispose(); |
||||||
|
_focusNode.unfocus(); |
||||||
|
} |
||||||
|
|
||||||
|
@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; |
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
subscribeParam = widget.arguments["subscribeParam"]; |
||||||
|
queryReservationDetails(widget.arguments["shopId"]); |
||||||
|
} |
||||||
|
|
||||||
|
///预约时间详情 |
||||||
|
queryReservationDetails(shopId) async { |
||||||
|
try { |
||||||
|
if (subscribeParam != null) |
||||||
|
EasyLoading.show( |
||||||
|
status: S.current.zhengzaijiazai, |
||||||
|
maskType: EasyLoadingMaskType.black); |
||||||
|
if (businessService == null) { |
||||||
|
businessService = BusinessApiService(Dio(), |
||||||
|
context: context, |
||||||
|
token: BusinessInstance.instance.businessToken, |
||||||
|
tenant: BusinessInstance.instance.businessTenant, |
||||||
|
storeId: widget.arguments["storeId"]); |
||||||
|
} |
||||||
|
BaseData<StoreTimeInfoList> baseData = |
||||||
|
await businessService.storeOpenTime(shopId).catchError((error) { |
||||||
|
networkStatus = -1; |
||||||
|
networkError = AppUtils.dioErrorTypeToString(error.type); |
||||||
|
}); |
||||||
|
if (baseData != null && baseData.isSuccess) { |
||||||
|
storeTimeInfoList = baseData.data; |
||||||
|
if (subscribeParam != null) { |
||||||
|
timeSlots = subscribeParam.subscribeTimes; |
||||||
|
_subscribeSwitch = subscribeParam.isEnableSubscribe; |
||||||
|
_paySubscribeSwitch = subscribeParam.isEnableSubscribePay; |
||||||
|
universalTypeSelect = subscribeParam.dayOrDate; |
||||||
|
|
||||||
|
setState(() {}); |
||||||
|
} |
||||||
|
networkStatus = 1; |
||||||
|
} |
||||||
|
} finally { |
||||||
|
EasyLoading.dismiss(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
///设置间隔的时间段list |
||||||
|
List<String> getTimeSlots(String st, String et, int n) { |
||||||
|
List<String> tempTimes = []; |
||||||
|
try { |
||||||
|
DateTime start = DateTime.parse(st); |
||||||
|
DateTime end = DateTime.parse(et); |
||||||
|
Duration interval = Duration(minutes: n); |
||||||
|
|
||||||
|
while (start.isBefore(end)) { |
||||||
|
DateTime current = start.add(interval); |
||||||
|
if (current.isBefore(end)) { |
||||||
|
String startTime = start.toString().substring(11, 16); |
||||||
|
String endTime = current.toString().substring(11, 16); |
||||||
|
tempTimes.add('$startTime-$endTime'); |
||||||
|
} else { |
||||||
|
String startTime = start.toString().substring(11, 16); |
||||||
|
String endTime = end.toString().substring(11, 16); |
||||||
|
tempTimes.add('$startTime-$endTime'); |
||||||
|
} |
||||||
|
start = current; |
||||||
|
} |
||||||
|
} catch (ex) { |
||||||
|
EasyLoading.dismiss(); |
||||||
|
} |
||||||
|
return tempTimes; |
||||||
|
} |
||||||
|
|
||||||
|
///预约信息保存 |
||||||
|
updateSubscribeInfo() async { |
||||||
|
try { |
||||||
|
EasyLoading.show( |
||||||
|
status: S.current.zhengzaijiazai, |
||||||
|
maskType: EasyLoadingMaskType.black); |
||||||
|
if (businessService == null) { |
||||||
|
businessService = BusinessApiService(Dio(), |
||||||
|
context: context, |
||||||
|
token: BusinessInstance.instance.businessToken, |
||||||
|
tenant: BusinessInstance.instance.businessTenant, |
||||||
|
storeId: widget.arguments["storeId"]); |
||||||
|
} |
||||||
|
BaseData baseData = await businessService.updateSubscribe({ |
||||||
|
"productId": widget.arguments["productId"], |
||||||
|
"subscribe": { |
||||||
|
"isEnableSubscribe": _subscribeSwitch, |
||||||
|
"isEnableSubscribePay": _paySubscribeSwitch, |
||||||
|
"timePeriod": editingController.text != "" |
||||||
|
? editingController.text |
||||||
|
: subscribeParam?.timePeriod ?? "", |
||||||
|
"subscribeTimes": timeSlots, |
||||||
|
"dayOrDate": (storeTimeInfoList?.posType ?? "") == "FAST_SERVICE" |
||||||
|
? 0 |
||||||
|
: universalTypeSelect, |
||||||
|
"startAfterDays": daysAfterController?.text ?? "", |
||||||
|
"daysValidate": daysWithinController?.text ?? "", |
||||||
|
"subscribeStartTime": selectTimeDate == "" |
||||||
|
? "" |
||||||
|
: selectTimeDate |
||||||
|
.replaceAll("年", "-") |
||||||
|
.replaceAll("月", "-") |
||||||
|
.replaceAll("日", "") |
||||||
|
.substring(0, 19), |
||||||
|
"subscribeEndTime": selectTimeDate == "" |
||||||
|
? "" |
||||||
|
: selectTimeDate |
||||||
|
.replaceAll("年", "-") |
||||||
|
.replaceAll("月", "-") |
||||||
|
.replaceAll("日", "") |
||||||
|
.substring(23, 41), |
||||||
|
"stores": [] |
||||||
|
} |
||||||
|
}).catchError((error) {}); |
||||||
|
if (baseData != null && baseData.isSuccess) { |
||||||
|
Navigator.of(context).pop(1); |
||||||
|
SmartDialog.showToast("预约信息编辑成功", alignment: Alignment.center); |
||||||
|
setState(() {}); |
||||||
|
} else { |
||||||
|
SmartDialog.showToast(baseData.msg, alignment: Alignment.center); |
||||||
|
} |
||||||
|
} finally { |
||||||
|
EasyLoading.dismiss(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@override |
||||||
|
Widget build(BuildContext context) { |
||||||
|
return Scaffold( |
||||||
|
resizeToAvoidBottomInset: false, |
||||||
|
appBar: MyAppBar( |
||||||
|
title: "预约", |
||||||
|
titleColor: Colors.black, |
||||||
|
leadingColor: Colors.black, |
||||||
|
background: Colors.white, |
||||||
|
), |
||||||
|
body: networkStatus == -1 |
||||||
|
? noNetwork() |
||||||
|
: Container( |
||||||
|
color: Colors.white, |
||||||
|
padding: EdgeInsets.symmetric(horizontal: 16.w), |
||||||
|
child: Column( |
||||||
|
crossAxisAlignment: CrossAxisAlignment.start, |
||||||
|
children: [ |
||||||
|
if (networkStatus == 1) |
||||||
|
Row( |
||||||
|
children: [ |
||||||
|
Text( |
||||||
|
"预约开关", |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 14.sp, |
||||||
|
color: Color(0xFF0D0D0D), |
||||||
|
fontWeight: MyFontWeight.bold), |
||||||
|
), |
||||||
|
SizedBox( |
||||||
|
width: 24.w, |
||||||
|
), |
||||||
|
GestureDetector( |
||||||
|
behavior: HitTestBehavior.opaque, |
||||||
|
onTap: () { |
||||||
|
setState(() { |
||||||
|
_subscribeSwitch = !_subscribeSwitch; |
||||||
|
}); |
||||||
|
}, |
||||||
|
child: Padding( |
||||||
|
padding: EdgeInsets.symmetric(horizontal: 24.w), |
||||||
|
child: _subscribeSwitch |
||||||
|
? Image.asset( |
||||||
|
"assets/image/reservation_switch.webp", |
||||||
|
width: 44.w, |
||||||
|
height: 24.h, |
||||||
|
fit: BoxFit.fill, |
||||||
|
) |
||||||
|
: Image.asset( |
||||||
|
"assets/image/reservation_unswitch.webp", |
||||||
|
width: 44.w, |
||||||
|
height: 24.h, |
||||||
|
fit: BoxFit.fill, |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
if (networkStatus == 1) |
||||||
|
Expanded( |
||||||
|
child: |
||||||
|
(storeTimeInfoList?.posType ?? "") == "FAST_SERVICE" |
||||||
|
? timeIntervalType() |
||||||
|
: universalType()), |
||||||
|
if (networkStatus == 1) |
||||||
|
GestureDetector( |
||||||
|
behavior: HitTestBehavior.opaque, |
||||||
|
onTap: () { |
||||||
|
updateSubscribeInfo(); |
||||||
|
}, |
||||||
|
child: Container( |
||||||
|
width: double.infinity, |
||||||
|
alignment: Alignment.center, |
||||||
|
margin: EdgeInsets.only(bottom: 55.h, top: 15.h), |
||||||
|
padding: EdgeInsets.symmetric(vertical: 16.h), |
||||||
|
decoration: BoxDecoration( |
||||||
|
borderRadius: BorderRadius.circular(27), |
||||||
|
color: Color(0xFF30415B)), |
||||||
|
child: Text( |
||||||
|
S.of(context).baocun, |
||||||
|
style: TextStyle( |
||||||
|
fontWeight: MyFontWeight.semi_bold, |
||||||
|
fontSize: 16.sp, |
||||||
|
color: Colors.white, |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
) |
||||||
|
], |
||||||
|
), |
||||||
|
), |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
///时间间隔预约类型 |
||||||
|
Widget timeIntervalType() { |
||||||
|
return Column( |
||||||
|
crossAxisAlignment: CrossAxisAlignment.start, |
||||||
|
children: [ |
||||||
|
Container( |
||||||
|
width: double.infinity, |
||||||
|
height: 1.h, |
||||||
|
color: Color(0x14000000), |
||||||
|
margin: EdgeInsets.symmetric(vertical: 24.h), |
||||||
|
), |
||||||
|
Row( |
||||||
|
children: [ |
||||||
|
Text( |
||||||
|
"付费预约开关", |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 14.sp, |
||||||
|
color: Color(0xFF0D0D0D), |
||||||
|
fontWeight: MyFontWeight.bold), |
||||||
|
), |
||||||
|
SizedBox( |
||||||
|
width: 24.w, |
||||||
|
), |
||||||
|
GestureDetector( |
||||||
|
behavior: HitTestBehavior.opaque, |
||||||
|
onTap: () { |
||||||
|
setState(() { |
||||||
|
_paySubscribeSwitch = !_paySubscribeSwitch; |
||||||
|
}); |
||||||
|
}, |
||||||
|
child: Padding( |
||||||
|
padding: EdgeInsets.symmetric(horizontal: 24.w), |
||||||
|
child: _paySubscribeSwitch |
||||||
|
? Image.asset( |
||||||
|
"assets/image/reservation_switch.webp", |
||||||
|
width: 44.w, |
||||||
|
height: 24.h, |
||||||
|
fit: BoxFit.fill, |
||||||
|
) |
||||||
|
: Image.asset( |
||||||
|
"assets/image/reservation_unswitch.webp", |
||||||
|
width: 44.w, |
||||||
|
height: 24.h, |
||||||
|
fit: BoxFit.fill, |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
Container( |
||||||
|
width: double.infinity, |
||||||
|
height: 1.h, |
||||||
|
color: Color(0x14000000), |
||||||
|
margin: EdgeInsets.only(top: 24.h, bottom: 10.h), |
||||||
|
), |
||||||
|
Row( |
||||||
|
children: [ |
||||||
|
Expanded( |
||||||
|
child: Text( |
||||||
|
"预约间隔时(分钟)", |
||||||
|
style: TextStyle( |
||||||
|
color: Color(0xFF0D0D0D), |
||||||
|
fontSize: 14.sp, |
||||||
|
fontWeight: FontWeight.bold, |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
Expanded( |
||||||
|
child: TextField( |
||||||
|
controller: editingController, |
||||||
|
keyboardType: TextInputType.phone, |
||||||
|
onChanged: (value) { |
||||||
|
timeSlots = getTimeSlots( |
||||||
|
"2023-11-14 ${storeTimeInfoList?.openStartTime ?? ""}", |
||||||
|
"2023-11-14 ${storeTimeInfoList?.openEndTime ?? ""}", |
||||||
|
int.tryParse(editingController.text) ?? 30); |
||||||
|
}, |
||||||
|
decoration: InputDecoration( |
||||||
|
hintText: subscribeParam != null |
||||||
|
? (subscribeParam?.timePeriod ?? 0).toString() |
||||||
|
: "分钟", |
||||||
|
hintTextDirection: TextDirection.rtl, |
||||||
|
hintStyle: TextStyle( |
||||||
|
color: Color(0xFF0D0D0D), |
||||||
|
fontSize: 14.sp, |
||||||
|
fontWeight: MyFontWeight.semi_bold, |
||||||
|
), |
||||||
|
border: InputBorder.none, |
||||||
|
contentPadding: EdgeInsets.only(left: 16.w), |
||||||
|
), |
||||||
|
textAlign: TextAlign.right, |
||||||
|
style: TextStyle( |
||||||
|
color: Color(0xFF0D0D0D), |
||||||
|
fontSize: 14.sp, |
||||||
|
fontWeight: MyFontWeight.semi_bold), |
||||||
|
), |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
Padding( |
||||||
|
padding: EdgeInsets.only(bottom: 16.h, top: 38.h), |
||||||
|
child: Text( |
||||||
|
"选择预约时间段", |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 14.sp, |
||||||
|
color: Color(0xFF0D0D0D), |
||||||
|
fontWeight: MyFontWeight.bold), |
||||||
|
)), |
||||||
|
Expanded( |
||||||
|
child: GridView.builder( |
||||||
|
itemCount: timeSlots.length, |
||||||
|
shrinkWrap: true, |
||||||
|
physics: BouncingScrollPhysics(), |
||||||
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( |
||||||
|
//一行的Widget数量 |
||||||
|
crossAxisCount: 3, |
||||||
|
//水平子Widget之间间距 |
||||||
|
crossAxisSpacing: 14, |
||||||
|
//垂直子Widget之间间距 |
||||||
|
mainAxisSpacing: 20, |
||||||
|
//子Widget宽高比例 |
||||||
|
childAspectRatio: 3, |
||||||
|
), |
||||||
|
itemBuilder: (context, index) { |
||||||
|
return reservationTimeList(index); |
||||||
|
}, |
||||||
|
)), |
||||||
|
], |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
///通用预约类型 |
||||||
|
Widget universalType() { |
||||||
|
return Column( |
||||||
|
crossAxisAlignment: CrossAxisAlignment.start, |
||||||
|
children: [ |
||||||
|
Padding( |
||||||
|
padding: EdgeInsets.only(top: 34.h, bottom: 16.h), |
||||||
|
child: Text( |
||||||
|
"增加有效期", |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 14.sp, |
||||||
|
color: Color(0xFF0D0D0D), |
||||||
|
fontWeight: MyFontWeight.bold), |
||||||
|
)), |
||||||
|
Row( |
||||||
|
children: [ |
||||||
|
Expanded( |
||||||
|
child: GestureDetector( |
||||||
|
behavior: HitTestBehavior.opaque, |
||||||
|
onTap: () { |
||||||
|
setState(() { |
||||||
|
universalTypeSelect = 1; |
||||||
|
}); |
||||||
|
}, |
||||||
|
child: Row( |
||||||
|
crossAxisAlignment: CrossAxisAlignment.center, |
||||||
|
children: [ |
||||||
|
checkView(1), |
||||||
|
Text( |
||||||
|
"任意时间", |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 12.sp, |
||||||
|
color: Color(0xFF1A1A1A), |
||||||
|
fontWeight: MyFontWeight.regular), |
||||||
|
) |
||||||
|
], |
||||||
|
))), |
||||||
|
Expanded( |
||||||
|
child: GestureDetector( |
||||||
|
behavior: HitTestBehavior.opaque, |
||||||
|
onTap: () { |
||||||
|
setState(() { |
||||||
|
universalTypeSelect = 3; |
||||||
|
}); |
||||||
|
}, |
||||||
|
child: Row( |
||||||
|
crossAxisAlignment: CrossAxisAlignment.center, |
||||||
|
children: [ |
||||||
|
checkView(3), |
||||||
|
Text( |
||||||
|
"日期范围", |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 12.sp, |
||||||
|
color: Color(0xFF1A1A1A), |
||||||
|
fontWeight: MyFontWeight.regular), |
||||||
|
) |
||||||
|
], |
||||||
|
))), |
||||||
|
Expanded( |
||||||
|
child: GestureDetector( |
||||||
|
behavior: HitTestBehavior.opaque, |
||||||
|
onTap: () { |
||||||
|
setState(() { |
||||||
|
universalTypeSelect = 2; |
||||||
|
}); |
||||||
|
}, |
||||||
|
child: Row( |
||||||
|
crossAxisAlignment: CrossAxisAlignment.center, |
||||||
|
children: [ |
||||||
|
checkView(2), |
||||||
|
Text( |
||||||
|
"可预定的期限", |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 12.sp, |
||||||
|
color: Color(0xFF1A1A1A), |
||||||
|
fontWeight: MyFontWeight.regular), |
||||||
|
) |
||||||
|
], |
||||||
|
))), |
||||||
|
], |
||||||
|
), |
||||||
|
if ((universalTypeSelect != 0 && universalTypeSelect != 1)) |
||||||
|
Expanded( |
||||||
|
child: |
||||||
|
universalTypeSelect == 2 ? expectedDeadline() : dateRange()), |
||||||
|
], |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
///可预订的期限UI |
||||||
|
Widget expectedDeadline() { |
||||||
|
return Column( |
||||||
|
crossAxisAlignment: CrossAxisAlignment.start, |
||||||
|
children: [ |
||||||
|
Padding( |
||||||
|
padding: EdgeInsets.only(top: 34.h, bottom: 16.h), |
||||||
|
child: Text( |
||||||
|
"预约多少天以后", |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 14.sp, |
||||||
|
color: Color(0xFF0D0D0D), |
||||||
|
fontWeight: MyFontWeight.bold), |
||||||
|
)), |
||||||
|
Container( |
||||||
|
width: 164.w, |
||||||
|
margin: EdgeInsets.only(bottom: 8.h), |
||||||
|
padding: EdgeInsets.symmetric(vertical: 5.h), |
||||||
|
decoration: BoxDecoration( |
||||||
|
color: Color(0xFFF8F9FA), |
||||||
|
borderRadius: BorderRadius.circular(4), |
||||||
|
), |
||||||
|
child: Row( |
||||||
|
crossAxisAlignment: CrossAxisAlignment.center, |
||||||
|
children: [ |
||||||
|
Expanded( |
||||||
|
child: TextField( |
||||||
|
controller: daysAfterController, |
||||||
|
keyboardType: TextInputType.phone, |
||||||
|
onEditingComplete: () { |
||||||
|
FocusScope.of(context).requestFocus(FocusNode()); |
||||||
|
}, |
||||||
|
decoration: InputDecoration( |
||||||
|
border: InputBorder.none, |
||||||
|
isCollapsed: true, |
||||||
|
hintText: subscribeParam != null |
||||||
|
? (subscribeParam?.startAfterDays ?? "").toString() |
||||||
|
: "", |
||||||
|
hintStyle: TextStyle( |
||||||
|
color: Color(0xFF0D0D0D), |
||||||
|
fontSize: 14.sp, |
||||||
|
fontWeight: MyFontWeight.regular, |
||||||
|
), |
||||||
|
contentPadding: EdgeInsets.only(left: 16.w), |
||||||
|
), |
||||||
|
style: TextStyle( |
||||||
|
color: Color(0xFF0D0D0D), |
||||||
|
fontSize: 14.sp, |
||||||
|
fontWeight: MyFontWeight.regular), |
||||||
|
), |
||||||
|
), |
||||||
|
Padding( |
||||||
|
padding: EdgeInsets.only(right: 13.w), |
||||||
|
child: Text( |
||||||
|
"天", |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 14.sp, |
||||||
|
color: Color(0xFF7B8CA7), |
||||||
|
fontWeight: MyFontWeight.medium), |
||||||
|
), |
||||||
|
) |
||||||
|
], |
||||||
|
), |
||||||
|
), |
||||||
|
Text( |
||||||
|
"*设定预定后整数天后才有效", |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 12.sp, |
||||||
|
color: Color(0xFFFA5151), |
||||||
|
fontWeight: MyFontWeight.regular), |
||||||
|
), |
||||||
|
Padding( |
||||||
|
padding: EdgeInsets.only(top: 25.h, bottom: 16.h), |
||||||
|
child: Text( |
||||||
|
"预约多少天以内", |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 14.sp, |
||||||
|
color: Color(0xFF0D0D0D), |
||||||
|
fontWeight: MyFontWeight.bold), |
||||||
|
)), |
||||||
|
Container( |
||||||
|
width: 164.w, |
||||||
|
margin: EdgeInsets.only(bottom: 8.h), |
||||||
|
padding: EdgeInsets.symmetric(vertical: 5.h), |
||||||
|
decoration: BoxDecoration( |
||||||
|
color: Color(0xFFF8F9FA), |
||||||
|
borderRadius: BorderRadius.circular(4), |
||||||
|
), |
||||||
|
child: Row( |
||||||
|
crossAxisAlignment: CrossAxisAlignment.center, |
||||||
|
children: [ |
||||||
|
Expanded( |
||||||
|
child: TextField( |
||||||
|
controller: daysWithinController, |
||||||
|
keyboardType: TextInputType.phone, |
||||||
|
onEditingComplete: () { |
||||||
|
FocusScope.of(context).requestFocus(FocusNode()); |
||||||
|
}, |
||||||
|
decoration: InputDecoration( |
||||||
|
isCollapsed: true, |
||||||
|
border: InputBorder.none, |
||||||
|
hintText: subscribeParam != null |
||||||
|
? (subscribeParam?.daysValidate ?? "").toString() |
||||||
|
: "", |
||||||
|
hintStyle: TextStyle( |
||||||
|
color: Color(0xFF0D0D0D), |
||||||
|
fontSize: 14.sp, |
||||||
|
fontWeight: MyFontWeight.regular, |
||||||
|
), |
||||||
|
contentPadding: EdgeInsets.only(left: 16.w), |
||||||
|
), |
||||||
|
style: TextStyle( |
||||||
|
color: Color(0xFF0D0D0D), |
||||||
|
fontSize: 14.sp, |
||||||
|
fontWeight: MyFontWeight.regular), |
||||||
|
), |
||||||
|
), |
||||||
|
Padding( |
||||||
|
padding: EdgeInsets.symmetric(horizontal: 13.w), |
||||||
|
child: Text( |
||||||
|
"天", |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 14.sp, |
||||||
|
color: Color(0xFF7B8CA7), |
||||||
|
fontWeight: MyFontWeight.medium), |
||||||
|
), |
||||||
|
) |
||||||
|
], |
||||||
|
), |
||||||
|
), |
||||||
|
Text( |
||||||
|
"*设定预定后整数天内有效", |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 12.sp, |
||||||
|
color: Color(0xFFFA5151), |
||||||
|
fontWeight: MyFontWeight.regular), |
||||||
|
) |
||||||
|
], |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
///日期范围UI |
||||||
|
Widget dateRange() { |
||||||
|
return Column( |
||||||
|
crossAxisAlignment: CrossAxisAlignment.start, |
||||||
|
children: [ |
||||||
|
Padding( |
||||||
|
padding: EdgeInsets.only(top: 34.h, bottom: 16.h), |
||||||
|
child: Text( |
||||||
|
"日期范围", |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 14.sp, |
||||||
|
color: Color(0xFF0D0D0D), |
||||||
|
fontWeight: MyFontWeight.bold), |
||||||
|
)), |
||||||
|
timeSelect(), |
||||||
|
], |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
///时间选择 |
||||||
|
Widget timeSelect() { |
||||||
|
return Container( |
||||||
|
color: Colors.white, |
||||||
|
child: GestureDetector( |
||||||
|
onTap: () { |
||||||
|
Navigator.of(context).pushNamed('/router/custom_page', |
||||||
|
arguments: {"beyondDateRange": "1"}).then((value) { |
||||||
|
setState(() { |
||||||
|
selectTimeDate = value; |
||||||
|
}); |
||||||
|
}); |
||||||
|
}, |
||||||
|
child: Container( |
||||||
|
decoration: BoxDecoration( |
||||||
|
color: Color(0xFFF7F8FA), |
||||||
|
borderRadius: BorderRadius.circular(2), |
||||||
|
), |
||||||
|
padding: EdgeInsets.symmetric(horizontal: 14.w, vertical: 12.h), |
||||||
|
child: Row( |
||||||
|
mainAxisAlignment: MainAxisAlignment.center, |
||||||
|
children: [ |
||||||
|
Text( |
||||||
|
(selectTimeDate == "" || selectTimeDate == null) |
||||||
|
? (((subscribeParam?.subscribeEndTime ?? "") != "" && |
||||||
|
(subscribeParam?.subscribeStartTime ?? "") != "") |
||||||
|
? "${subscribeParam?.subscribeStartTime ?? ""} 至 ${subscribeParam?.subscribeEndTime ?? ""}" |
||||||
|
: "选择开始时间 至 结束时间") |
||||||
|
: "${selectTimeDate.replaceAll("年", "-").replaceAll("月", "-").replaceAll("日", "").substring(0, 19)} " |
||||||
|
"${selectTimeDate.replaceAll("年", "-").replaceAll("月", "-").replaceAll("日", "").substring(20, 41)}", |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 14.sp, |
||||||
|
color: Color(0xFF30415B), |
||||||
|
fontWeight: MyFontWeight.regular), |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
var universalTypeSelect = 0; |
||||||
|
|
||||||
|
Widget checkView(var index) { |
||||||
|
return Container( |
||||||
|
padding: EdgeInsets.only( |
||||||
|
right: 6.w, |
||||||
|
), |
||||||
|
alignment: Alignment.center, |
||||||
|
child: Image.asset( |
||||||
|
universalTypeSelect != index |
||||||
|
? "assets/image/bus_time_unSelect.webp" |
||||||
|
: "assets/image/bus_time_select.webp", |
||||||
|
width: 20.w, |
||||||
|
height: 20.h, |
||||||
|
), |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
Widget reservationTimeList(int index) { |
||||||
|
return Container( |
||||||
|
decoration: new BoxDecoration( |
||||||
|
color: Color(0xFFEFF5FF), |
||||||
|
borderRadius: BorderRadius.circular(2), |
||||||
|
), |
||||||
|
child: Row( |
||||||
|
crossAxisAlignment: CrossAxisAlignment.center, |
||||||
|
mainAxisAlignment: MainAxisAlignment.center, |
||||||
|
children: [ |
||||||
|
Text( |
||||||
|
timeSlots[index], |
||||||
|
style: TextStyle( |
||||||
|
fontWeight: MyFontWeight.medium, |
||||||
|
fontSize: 14.sp, |
||||||
|
color: Color(0xFF30415B), |
||||||
|
), |
||||||
|
), |
||||||
|
GestureDetector( |
||||||
|
behavior: HitTestBehavior.opaque, |
||||||
|
onTap: () { |
||||||
|
timeSlots.removeAt(index); |
||||||
|
setState(() {}); |
||||||
|
}, |
||||||
|
child: Container( |
||||||
|
padding: EdgeInsets.all(4), |
||||||
|
child: Image.asset( |
||||||
|
"assets/image/bus_close_circle.webp", |
||||||
|
width: 16.h, |
||||||
|
height: 16.h, |
||||||
|
fit: BoxFit.fill, |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
Widget noNetwork() { |
||||||
|
return Container( |
||||||
|
width: double.infinity, |
||||||
|
child: Column( |
||||||
|
mainAxisAlignment: MainAxisAlignment.center, |
||||||
|
crossAxisAlignment: CrossAxisAlignment.center, |
||||||
|
children: [ |
||||||
|
Text( |
||||||
|
networkError.substring(0, networkError.indexOf(",")), |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 14.sp, |
||||||
|
color: Color(0xFF0D0D0D), |
||||||
|
fontWeight: MyFontWeight.bold), |
||||||
|
), |
||||||
|
Padding( |
||||||
|
padding: EdgeInsets.symmetric(vertical: 10.h), |
||||||
|
child: Text( |
||||||
|
"请检查网络设置或稍后重试", |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 12.sp, |
||||||
|
color: Color(0xFF7A797F), |
||||||
|
fontWeight: MyFontWeight.regular), |
||||||
|
), |
||||||
|
), |
||||||
|
GestureDetector( |
||||||
|
behavior: HitTestBehavior.opaque, |
||||||
|
onTap: () { |
||||||
|
queryReservationDetails(widget.arguments["shopId"]); |
||||||
|
}, |
||||||
|
child: Container( |
||||||
|
decoration: BoxDecoration( |
||||||
|
color: Color(0xFF30415B), |
||||||
|
borderRadius: BorderRadius.circular(15), |
||||||
|
), |
||||||
|
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 3.h), |
||||||
|
child: Text( |
||||||
|
"重试", |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 14.sp, |
||||||
|
color: Colors.white, |
||||||
|
fontWeight: MyFontWeight.regular), |
||||||
|
)), |
||||||
|
) |
||||||
|
], |
||||||
|
), |
||||||
|
); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,42 @@ |
|||||||
|
/// openEndTime : "20:30:00" |
||||||
|
/// openStartTime : "09:00:00" |
||||||
|
/// posType : "FAST_SERVICE" |
||||||
|
|
||||||
|
class StoreTimeInfoList { |
||||||
|
StoreTimeInfoList({ |
||||||
|
String openEndTime, |
||||||
|
String openStartTime, |
||||||
|
String posType,}){ |
||||||
|
_openEndTime = openEndTime; |
||||||
|
_openStartTime = openStartTime; |
||||||
|
_posType = posType; |
||||||
|
} |
||||||
|
|
||||||
|
StoreTimeInfoList.fromJson(dynamic json) { |
||||||
|
_openEndTime = json['openEndTime']; |
||||||
|
_openStartTime = json['openStartTime']; |
||||||
|
_posType = json['posType']; |
||||||
|
} |
||||||
|
String _openEndTime; |
||||||
|
String _openStartTime; |
||||||
|
String _posType; |
||||||
|
StoreTimeInfoList copyWith({ String openEndTime, |
||||||
|
String openStartTime, |
||||||
|
String posType, |
||||||
|
}) => StoreTimeInfoList( openEndTime: openEndTime ?? _openEndTime, |
||||||
|
openStartTime: openStartTime ?? _openStartTime, |
||||||
|
posType: posType ?? _posType, |
||||||
|
); |
||||||
|
String get openEndTime => _openEndTime; |
||||||
|
String get openStartTime => _openStartTime; |
||||||
|
String get posType => _posType; |
||||||
|
|
||||||
|
Map<String, dynamic> toJson() { |
||||||
|
final map = <String, dynamic>{}; |
||||||
|
map['openEndTime'] = _openEndTime; |
||||||
|
map['openStartTime'] = _openStartTime; |
||||||
|
map['posType'] = _posType; |
||||||
|
return map; |
||||||
|
} |
||||||
|
|
||||||
|
} |