overtime_list_controller.dart 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. import 'package:flutter_riverpod/flutter_riverpod.dart';
  2. import 'overtime_model.dart';
  3. final overtimeStatusFilterProvider = StateProvider<String>((ref) => '');
  4. final overtimePageProvider = StateProvider<int>((ref) => 1);
  5. final overtimeDateStartProvider = StateProvider<DateTime?>((ref) => null);
  6. final overtimeDateEndProvider = StateProvider<DateTime?>((ref) => null);
  7. final overtimeKeywordProvider = StateProvider<String>((ref) => '');
  8. final overtimeRefreshProvider = StateProvider<int>((ref) => 0);
  9. final overtimeSortDirProvider = StateProvider<String>((ref) => 'DESC');
  10. final now = DateTime.now();
  11. final mockOvertimes = <OvertimeModel>[
  12. OvertimeModel(
  13. applyId: 1,
  14. billNo: 'JB20260520001',
  15. salesman: '张三',
  16. dept: '市场部',
  17. billType: '工作日加班',
  18. isAuditApproved: false,
  19. remark: '项目上线前紧急测试',
  20. createTime: DateTime(2026, 5, 20),
  21. updateTime: DateTime(2026, 5, 20),
  22. details: [
  23. OvertimeDetailModel(
  24. detailId: 1,
  25. applyId: 1,
  26. seqNo: 1,
  27. empCode: 'EMP001',
  28. shiftType: '白班',
  29. startDate: DateTime(2026, 5, 20),
  30. endDate: DateTime(2026, 5, 20),
  31. approvedHours: 2.5,
  32. isApproved: 'N',
  33. directOt: 'N',
  34. otQuantity: 2.5,
  35. reason: '测试加班',
  36. ),
  37. ],
  38. ),
  39. OvertimeModel(
  40. applyId: 2,
  41. billNo: 'JB20260518002',
  42. salesman: '王五',
  43. dept: '技术部',
  44. billType: '休息日加班',
  45. isAuditApproved: true,
  46. remark: '系统架构升级',
  47. createTime: DateTime(2026, 5, 17),
  48. updateTime: DateTime(2026, 5, 19),
  49. details: [
  50. OvertimeDetailModel(
  51. detailId: 2,
  52. applyId: 2,
  53. seqNo: 1,
  54. empCode: 'EMP002',
  55. shiftType: '白班',
  56. startDate: DateTime(2026, 5, 18),
  57. endDate: DateTime(2026, 5, 18),
  58. approvedHours: 7.5,
  59. isApproved: 'Y',
  60. directOt: 'N',
  61. otQuantity: 7.5,
  62. reason: '架构升级',
  63. ),
  64. ],
  65. ),
  66. OvertimeModel(
  67. applyId: 3,
  68. billNo: 'JB20260525003',
  69. salesman: '赵六',
  70. dept: '财务部',
  71. billType: '工作日加班',
  72. isAuditApproved: false,
  73. remark: '季度财务报表汇总',
  74. createTime: DateTime(2026, 5, 25),
  75. updateTime: DateTime(2026, 5, 25),
  76. ),
  77. OvertimeModel(
  78. applyId: 4,
  79. billNo: 'JB20260601004',
  80. salesman: '张三',
  81. dept: '市场部',
  82. billType: '节假日加班',
  83. isAuditApproved: false,
  84. remark: '节假日活动筹备',
  85. createTime: DateTime(2026, 5, 30),
  86. updateTime: DateTime(2026, 6, 1),
  87. ),
  88. OvertimeModel(
  89. applyId: 5,
  90. billNo: 'JB20260602005',
  91. salesman: '王五',
  92. dept: '技术部',
  93. billType: '工作日加班',
  94. isAuditApproved: false,
  95. remark: '夜间服务器维护',
  96. createTime: DateTime(2026, 6, 2),
  97. updateTime: DateTime(2026, 6, 2),
  98. ),
  99. OvertimeModel(
  100. applyId: 6,
  101. billNo: 'JB20260515006',
  102. salesman: '张三',
  103. dept: '市场部',
  104. billType: '休息日加班',
  105. isAuditApproved: true,
  106. remark: '周末展会布展',
  107. createTime: DateTime(2026, 5, 14),
  108. updateTime: DateTime(2026, 5, 15),
  109. ),
  110. ];
  111. final overtimeListProvider = FutureProvider.family<List<OvertimeModel>, String>(
  112. (ref, status) async {
  113. ref.watch(overtimePageProvider);
  114. ref.watch(overtimeRefreshProvider);
  115. ref.watch(overtimeDateStartProvider);
  116. ref.watch(overtimeDateEndProvider);
  117. ref.watch(overtimeKeywordProvider);
  118. await Future.delayed(const Duration(milliseconds: 1000));
  119. var list = mockOvertimes.toList();
  120. // 按 isAuditApproved 过滤('approved'/'pending')
  121. if (status == 'approved') {
  122. list = list.where((e) => e.isAuditApproved).toList();
  123. } else if (status == 'pending') {
  124. list = list.where((e) => !e.isAuditApproved).toList();
  125. }
  126. final dateStart = ref.read(overtimeDateStartProvider);
  127. final dateEnd = ref.read(overtimeDateEndProvider);
  128. if (dateStart != null) {
  129. list = list
  130. .where(
  131. (e) => e.createTime.isAfter(
  132. dateStart.subtract(const Duration(days: 1)),
  133. ),
  134. )
  135. .toList();
  136. }
  137. if (dateEnd != null) {
  138. list = list
  139. .where(
  140. (e) => e.createTime.isBefore(dateEnd.add(const Duration(days: 1))),
  141. )
  142. .toList();
  143. }
  144. final keyword = ref.read(overtimeKeywordProvider);
  145. if (keyword.isNotEmpty) {
  146. final kw = keyword.toLowerCase();
  147. list = list
  148. .where(
  149. (e) =>
  150. e.billNo.toLowerCase().contains(kw) ||
  151. e.salesman.toLowerCase().contains(kw) ||
  152. e.remark.toLowerCase().contains(kw),
  153. )
  154. .toList();
  155. }
  156. final sortDir = ref.read(overtimeSortDirProvider);
  157. if (sortDir == 'ASC') {
  158. list.sort((a, b) => a.createTime.compareTo(b.createTime));
  159. } else {
  160. list.sort((a, b) => b.createTime.compareTo(a.createTime));
  161. }
  162. return list;
  163. },
  164. );