date_range_picker_dialog.dart 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. import 'package:cs_resources/constants/color_constants.dart';
  2. import 'package:cs_resources/generated/assets.dart';
  3. import 'package:flutter/cupertino.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:plugin_basic/basic_export.dart';
  6. import 'package:plugin_platform/engine/toast/toast_engine.dart';
  7. import 'package:shared/utils/date_time_utils.dart';
  8. import 'package:shared/utils/log_utils.dart';
  9. import 'package:widgets/ext/ex_widget.dart';
  10. import 'package:widgets/my_load_image.dart';
  11. import 'package:widgets/my_text_view.dart';
  12. import 'package:widgets/picker/date_picker_util.dart';
  13. import 'package:widgets/widget_export.dart';
  14. class DateRangePickerDialog extends StatefulWidget {
  15. final void Function(String) confirmAction; // 回调确认的时间区间
  16. final VoidCallback? cancelAction;
  17. final String? dateRange; // 时间区间参数
  18. DateRangePickerDialog({
  19. required this.confirmAction,
  20. this.cancelAction,
  21. this.dateRange, // 接收时间区间
  22. });
  23. @override
  24. _DateRangePickerDialogState createState() => _DateRangePickerDialogState();
  25. }
  26. class _DateRangePickerDialogState extends State<DateRangePickerDialog> {
  27. DateTime? startDate;
  28. DateTime? endDate;
  29. @override
  30. void initState() {
  31. super.initState();
  32. // 如果 dateRange 不为空,则解析并设置开始和结束日期
  33. if (widget.dateRange != null && widget.dateRange!.isNotEmpty) {
  34. List<String> dates = widget.dateRange!.split(',');
  35. if (dates.length >= 2) {
  36. startDate = DateTime.parse(dates[0]);
  37. endDate = DateTime.parse(dates[dates.length - 1]);
  38. }
  39. }
  40. }
  41. @override
  42. Widget build(BuildContext context) {
  43. return Column(
  44. crossAxisAlignment: CrossAxisAlignment.center,
  45. mainAxisAlignment: MainAxisAlignment.center,
  46. children: [
  47. Container(
  48. width: double.infinity,
  49. decoration: const BoxDecoration(
  50. color: Colors.white,
  51. borderRadius: BorderRadius.all(Radius.circular(15)),
  52. ),
  53. child: Column(
  54. children: [
  55. MyTextView(
  56. "Select Date Range".tr,
  57. fontSize: 19,
  58. isFontMedium: true,
  59. textColor: ColorConstants.black,
  60. marginTop: 15,
  61. marginBottom: 15,
  62. ),
  63. InkWell(
  64. onTap: () {
  65. DatePickerUtil.showCupertinoDatePicker(
  66. selectedDateTime: startDate ?? DateTime.now(),
  67. mode: CupertinoDatePickerMode.date,
  68. onDateTimeChanged: (date) {
  69. setState(() {
  70. startDate = date;
  71. });
  72. },
  73. title: "Start Time".tr,
  74. );
  75. },
  76. child: Container(
  77. decoration: const BoxDecoration(
  78. color: ColorConstants.grayECECEC,
  79. borderRadius: BorderRadius.all(Radius.circular(5)),
  80. ),
  81. margin: const EdgeInsets.symmetric(horizontal: 15),
  82. padding: const EdgeInsets.all(15.0),
  83. child: Row(
  84. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  85. children: [
  86. MyTextView(
  87. startDate != null ? DateTimeUtils.formatDate(startDate, format: 'yyyy-MM-dd') : "Select Start Time",
  88. fontSize: 15,
  89. isFontRegular: true,
  90. textColor: ColorConstants.black33,
  91. ),
  92. const MyAssetImage(
  93. Assets.cptJobPickDateIcon,
  94. width: 20,
  95. height: 20,
  96. color: ColorConstants.secondaryAppColor,
  97. ),
  98. ],
  99. ),
  100. ),
  101. ),
  102. InkWell(
  103. onTap: () {
  104. DatePickerUtil.showCupertinoDatePicker(
  105. selectedDateTime: endDate ?? DateTime.now(),
  106. mode: CupertinoDatePickerMode.date,
  107. onDateTimeChanged: (date) {
  108. setState(() {
  109. endDate = date;
  110. });
  111. },
  112. title: "End Time".tr,
  113. );
  114. },
  115. child: Container(
  116. decoration: const BoxDecoration(
  117. color: ColorConstants.grayECECEC,
  118. borderRadius: BorderRadius.all(Radius.circular(5)),
  119. ),
  120. margin: const EdgeInsets.only(left: 15, right: 15, top: 15),
  121. padding: const EdgeInsets.all(15.0),
  122. child: Row(
  123. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  124. children: [
  125. MyTextView(
  126. endDate != null ? DateTimeUtils.formatDate(endDate, format: 'yyyy-MM-dd') : "Select End Time",
  127. fontSize: 15,
  128. isFontRegular: true,
  129. textColor: ColorConstants.black33,
  130. ),
  131. const MyAssetImage(
  132. Assets.cptJobPickDateIcon,
  133. width: 20,
  134. height: 20,
  135. color: ColorConstants.secondaryAppColor,
  136. ),
  137. ],
  138. ),
  139. ),
  140. ),
  141. Container(
  142. margin: const EdgeInsets.only(top: 25),
  143. color: const Color(0XFFCECECE),
  144. height: 0.5,
  145. ),
  146. Row(
  147. children: [
  148. Expanded(
  149. flex: 1,
  150. child: InkWell(
  151. onTap: () {
  152. onCancel();
  153. widget.cancelAction?.call();
  154. },
  155. child: MyTextView(
  156. "Cancel".tr,
  157. fontSize: 17.5,
  158. isFontMedium: true,
  159. textAlign: TextAlign.center,
  160. textColor: const Color(0XFF0085C4),
  161. cornerRadius: 3,
  162. borderWidth: 1,
  163. ),
  164. )),
  165. Container(
  166. color: const Color(0xff09141F).withOpacity(0.13),
  167. width: 0.5,
  168. ),
  169. Expanded(
  170. flex: 1,
  171. child: InkWell(
  172. onTap: () async {
  173. if (startDate != null && endDate != null) {
  174. // 判断结束日期是否小于开始日期
  175. if (endDate!.isBefore(startDate!)) {
  176. ToastEngine.show("End date must be greater than start date");
  177. } else {
  178. onCancel();
  179. // 确保开始日期和结束日期都已选择
  180. String dateRange = _getDateRange(startDate!, endDate!);
  181. widget.confirmAction(dateRange);
  182. }
  183. // if (endDate!.isBefore(startDate!.add(const Duration(hours: 6)))) {
  184. // ToastEngine.show("End date must be greater than start date");
  185. // } else {
  186. // onCancel();
  187. // // 确保开始日期和结束日期都已选择
  188. // String dateRange = _getDateRange(startDate!, endDate!);
  189. // widget.confirmAction(dateRange);
  190. // }
  191. } else {
  192. ToastEngine.show("Select Date");
  193. }
  194. },
  195. child: MyTextView(
  196. "Confirm".tr,
  197. marginLeft: 10,
  198. fontSize: 17.5,
  199. isFontMedium: true,
  200. textAlign: TextAlign.center,
  201. textColor: const Color(0XFF0085C4),
  202. cornerRadius: 3,
  203. ),
  204. )),
  205. ],
  206. ).constrained(height: 46),
  207. ],
  208. ),
  209. ),
  210. ],
  211. ).constrained(width: 295);
  212. }
  213. String _getDateRange(DateTime start, DateTime end) {
  214. List<String> dateList = [];
  215. DateTime current = start;
  216. String endFormat = DateTimeUtils.formatDate(end, format: 'yyyy-MM-dd');
  217. // 逐日增加,直到达到结束日期,包括结束日期
  218. while (current.isBefore(end) || current.isAtSameMomentAs(end)) {
  219. dateList.add(DateTimeUtils.formatDate(current, format: 'yyyy-MM-dd'));
  220. current = current.add(const Duration(days: 1));
  221. }
  222. if (!dateList.contains(endFormat)) {
  223. dateList.add(endFormat);
  224. }
  225. return dateList.join(','); // 使用逗号连接日期
  226. }
  227. void onCancel() async {
  228. SmartDialog.dismiss();
  229. }
  230. }