expense_apply_controller.dart 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import 'package:flutter_riverpod/flutter_riverpod.dart';
  2. import 'expense_model.dart';
  3. import 'expense_api.dart';
  4. class ExpenseApplyState {
  5. final ExpenseModel expense;
  6. final bool isSubmitting;
  7. const ExpenseApplyState({required this.expense, this.isSubmitting = false});
  8. ExpenseApplyState copyWith({ExpenseModel? expense, bool? isSubmitting}) {
  9. return ExpenseApplyState(
  10. expense: expense ?? this.expense,
  11. isSubmitting: isSubmitting ?? this.isSubmitting,
  12. );
  13. }
  14. }
  15. class ExpenseApplyController extends StateNotifier<ExpenseApplyState> {
  16. final ExpenseApi _api;
  17. ExpenseApplyController(this._api, {ExpenseModel? initial})
  18. : super(
  19. ExpenseApplyState(
  20. expense:
  21. initial ??
  22. ExpenseModel(
  23. id: '',
  24. reportNo: '',
  25. applicantId: '',
  26. applicantName: '',
  27. deptId: '',
  28. deptName: '',
  29. expenseType: '',
  30. totalAmount: 0.0,
  31. purpose: '',
  32. createTime: DateTime.now(),
  33. updateTime: DateTime.now(),
  34. ),
  35. ),
  36. );
  37. void updatePurpose(String purpose) {
  38. state = state.copyWith(expense: state.expense.copyWith(purpose: purpose));
  39. }
  40. void addDetail(ExpenseDetailModel detail) {
  41. final details = [...state.expense.details, detail];
  42. state = state.copyWith(expense: state.expense.copyWith(details: details));
  43. }
  44. void removeDetail(int index) {
  45. final details = [...state.expense.details]..removeAt(index);
  46. state = state.copyWith(expense: state.expense.copyWith(details: details));
  47. }
  48. void recalculateAmount() {
  49. final total = state.expense.details.fold<double>(
  50. 0,
  51. (sum, d) => sum + d.totalAmount,
  52. );
  53. state = state.copyWith(expense: state.expense.copyWith(totalAmount: total));
  54. }
  55. Future<bool> submit() async {
  56. state = state.copyWith(isSubmitting: true);
  57. try {
  58. await _api.submit(state.expense.copyWith(status: 'pending'));
  59. return true;
  60. } catch (_) {
  61. return false;
  62. } finally {
  63. state = state.copyWith(isSubmitting: false);
  64. }
  65. }
  66. Future<bool> saveDraft() async {
  67. state = state.copyWith(isSubmitting: true);
  68. try {
  69. await _api.saveDraft(state.expense);
  70. return true;
  71. } catch (_) {
  72. return false;
  73. } finally {
  74. state = state.copyWith(isSubmitting: false);
  75. }
  76. }
  77. }
  78. final expenseApplyProvider = StateNotifierProvider.autoDispose
  79. .family<ExpenseApplyController, ExpenseApplyState, String?>((ref, editId) {
  80. final api = ref.watch(expenseApiProvider);
  81. return ExpenseApplyController(api);
  82. });