overtime_api.dart 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. import 'dart:convert';
  2. import 'package:flutter_riverpod/flutter_riverpod.dart';
  3. import '../../app.dart';
  4. import '../../core/data/api_cache.dart';
  5. import '../../core/navigation/host_app_channel.dart';
  6. import '../../core/network/api_client.dart';
  7. import '../../shared/models/pagination_model.dart';
  8. import '../expense_apply/expense_apply_api.dart';
  9. import 'overtime_model.dart';
  10. final overtimeApiProvider = Provider<OvertimeApi>(
  11. (ref) => OvertimeApi(ref.read(apiClientProvider)),
  12. );
  13. class OvertimeApi {
  14. final ApiClient _client;
  15. final _cache = ApiCache(
  16. keyPrefix:
  17. '${HostAppChannel.sn}_${HostAppChannel.compNo}_${HostAppChannel.usr}',
  18. );
  19. OvertimeApi(this._client);
  20. /// 清除所有基础资料缓存(picker 下拉刷新时调用)。
  21. void clearRefCache() => _cache.clear();
  22. /// 加班申请列表(分页)
  23. Future<PaginatedData<OvertimeModel>> fetchList({
  24. String status = '',
  25. String keyword = '',
  26. String startDate = '',
  27. String endDate = '',
  28. String usr = '',
  29. String sortDir = 'DESC',
  30. int page = 1,
  31. int size = 20,
  32. }) async {
  33. final response = await _client.get<Map<String, dynamic>>(
  34. '/OA/GetOTApplyList',
  35. queryParameters: {
  36. 'status': status,
  37. 'keyword': keyword,
  38. 'startDate': startDate,
  39. 'endDate': endDate,
  40. 'usr': usr,
  41. 'sortDir': sortDir,
  42. 'page': page,
  43. 'size': size,
  44. },
  45. );
  46. return PaginatedData.fromJson(response.data!, OvertimeModel.fromJson);
  47. }
  48. /// 加班申请详情(主表+明细)
  49. Future<OvertimeModel> fetchDetail(String billNo) async {
  50. final response = await _client.get<Map<String, dynamic>>(
  51. '/OA/GetOTApplyDetail',
  52. queryParameters: {'billNo': billNo},
  53. );
  54. return OvertimeModel.fromJson(response.data!);
  55. }
  56. /// 部门
  57. Future<List<DepartmentItem>> getDepartments({
  58. String keyword = '',
  59. bool onlyActive = true,
  60. int page = 1,
  61. int size = 100,
  62. }) async {
  63. final cacheKey = 'getDepartments_${keyword}_${onlyActive}_$page';
  64. return _cache.getOrFetch(cacheKey, () async {
  65. final response = await _client.get<Map<String, dynamic>>(
  66. '/OA/GetDepartments',
  67. queryParameters: {
  68. 'keyword': keyword,
  69. 'onlyActive': onlyActive,
  70. 'page': page,
  71. 'size': size,
  72. },
  73. );
  74. final list = (response.data?['list'] as List<dynamic>?) ?? [];
  75. return list
  76. .map((e) => DepartmentItem.fromJson(e as Map<String, dynamic>))
  77. .toList();
  78. });
  79. }
  80. /// 员工查询
  81. Future<List<EmployeeItem>> getEmployees({
  82. String keyword = '',
  83. String salNo = '',
  84. int page = 1,
  85. int size = 100,
  86. }) async {
  87. final cacheKey = 'getEmployees_${keyword}_${salNo}_$page';
  88. return _cache.getOrFetch(cacheKey, () async {
  89. final response = await _client.get<Map<String, dynamic>>(
  90. '/OA/GetEmployees',
  91. queryParameters: {
  92. 'keyword': keyword,
  93. 'salNo': salNo,
  94. 'page': page,
  95. 'size': size,
  96. },
  97. );
  98. final list = (response.data?['list'] as List<dynamic>?) ?? [];
  99. return list
  100. .map((e) => EmployeeItem.fromJson(e as Map<String, dynamic>))
  101. .toList();
  102. });
  103. }
  104. /// 提交,返回申请单号(提取失败时返回 null)
  105. Future<String?> submit(Map<String, dynamic> data) async {
  106. final response = await _client.post<Map<String, dynamic>>(
  107. '/OA/BillSave',
  108. data: {
  109. 'erpCategory': 'MasterService',
  110. 'billId': 'OT',
  111. 'procId': '',
  112. 'data': data,
  113. },
  114. );
  115. final resData = response.data;
  116. if (resData == null) return null;
  117. // 从 resultData 中取
  118. final resultData = resData['resultData'];
  119. if (resultData is Map<String, dynamic>) {
  120. final bilNo = resultData['BIL_NO'] as String?;
  121. if (bilNo != null && bilNo.isNotEmpty) return bilNo;
  122. }
  123. if (resultData is String && resultData.isNotEmpty) {
  124. try {
  125. final parsed = json.decode(resultData) as Map<String, dynamic>;
  126. final bilNo = parsed['BIL_NO'] as String?;
  127. if (bilNo != null && bilNo.isNotEmpty) return bilNo;
  128. } catch (_) {}
  129. }
  130. // 兜底
  131. final rootBilNo = resData['BIL_NO'] as String?;
  132. if (rootBilNo != null && rootBilNo.isNotEmpty) return rootBilNo;
  133. return null;
  134. }
  135. /// 获取单据状态
  136. Future<Map<String, dynamic>> getBillStatus(String billNo) async {
  137. final response = await _client.get<Map<String, dynamic>>(
  138. '/OA/GetBillStatus',
  139. queryParameters: {'billId': 'OT', 'billNo': billNo},
  140. );
  141. return response.data!;
  142. }
  143. }