job_applied_controller.dart 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. import 'package:cpt_job/modules/applied_staff_detail/applied_staff_detail_page.dart';
  2. import 'package:cpt_job/modules/job_applied_edit/job_applied_edit_page.dart';
  3. import 'package:cpt_job/widget/applied_staff_reviews.dart';
  4. import 'package:domain/entity/response/job_list_applied_staff_list_entity.dart';
  5. import 'package:domain/repository/job_repository.dart';
  6. import 'package:get/get.dart';
  7. import 'package:plugin_basic/constants/app_constant.dart';
  8. import 'package:plugin_platform/engine/dialog/dialog_engine.dart';
  9. import 'package:plugin_platform/engine/notify/notify_engine.dart';
  10. import 'package:plugin_platform/engine/toast/toast_engine.dart';
  11. import 'package:plugin_platform/http/dio/dio_cancelable_mixin.dart';
  12. import 'package:shared/utils/date_time_utils.dart';
  13. import 'package:shared/utils/event_bus.dart';
  14. import 'package:shared/utils/util.dart';
  15. import 'package:widgets/dialog/app_default_dialog.dart';
  16. import 'package:widgets/load_state_layout.dart';
  17. import 'package:widgets/widget_export.dart';
  18. import '../../widget/applied_add_staff.dart';
  19. import '../../widget/applied_butch_modify.dart';
  20. import '../applied_workflow/applied_workflow_page.dart';
  21. import 'job_applied_state.dart';
  22. class JobAppliedController extends GetxController with DioCancelableMixin {
  23. final JobRepository _jobRepository = Get.find();
  24. final JobAppliedState state = JobAppliedState();
  25. var _curPage = 1;
  26. var _needShowPlaceholder = true;
  27. //页面PlaceHolder的展示
  28. LoadState loadingState = LoadState.State_Success;
  29. String? errorMessage;
  30. //刷新页面状态
  31. void changeLoadingState(LoadState state) {
  32. loadingState = state;
  33. update();
  34. }
  35. // Refresh 控制器
  36. final EasyRefreshController refreshController = EasyRefreshController(
  37. controlFinishRefresh: true,
  38. controlFinishLoad: true,
  39. );
  40. // Refresh 刷新事件
  41. Future onRefresh() async {
  42. _curPage = 1;
  43. fetchAppliedStaffList();
  44. }
  45. // Refresh 加载事件
  46. Future loadMore() async {
  47. _curPage++;
  48. fetchAppliedStaffList();
  49. }
  50. // 重试请求
  51. Future retryRequest() async {
  52. _curPage = 1;
  53. _needShowPlaceholder = true;
  54. fetchAppliedStaffList();
  55. }
  56. /// 获取服务器数据,通知消息列表
  57. Future fetchAppliedStaffList() async {
  58. if (_needShowPlaceholder) {
  59. changeLoadingState(LoadState.State_Loading);
  60. }
  61. if (state.jobInfo == null) {
  62. //不是并发的,顺序执行接口
  63. var jobInfoResult = await _jobRepository.fetchJobAppliedInfo(
  64. state.jobId,
  65. cancelToken: cancelToken,
  66. );
  67. if (jobInfoResult.isSuccess) {
  68. state.jobInfo = jobInfoResult.data;
  69. update();
  70. } else {
  71. errorMessage = jobInfoResult.errorMsg;
  72. changeLoadingState(LoadState.State_Error);
  73. return;
  74. }
  75. }
  76. // 获取 Applied 列表
  77. var listResult = await _jobRepository.fetchJobAppliedStaffs(
  78. state.jobId,
  79. state.keyword,
  80. curPage: _curPage,
  81. cancelToken: cancelToken,
  82. );
  83. // 处理数据
  84. if (listResult.isSuccess) {
  85. handleList(listResult.data?.rows);
  86. } else {
  87. errorMessage = listResult.errorMsg;
  88. changeLoadingState(LoadState.State_Error);
  89. }
  90. // 最后赋值
  91. _needShowPlaceholder = false;
  92. }
  93. // 处理数据与展示的逻辑
  94. void handleList(List<JobListAppliedStaffListRows>? list) {
  95. if (list != null && list.isNotEmpty) {
  96. //有数据,判断是刷新还是加载更多的数据
  97. if (_curPage == 1) {
  98. //刷新的方式
  99. state.datas.clear();
  100. state.datas.addAll(list);
  101. refreshController.finishRefresh();
  102. //更新展示的状态
  103. changeLoadingState(LoadState.State_Success);
  104. } else {
  105. //加载更多
  106. state.datas.addAll(list);
  107. refreshController.finishLoad();
  108. update();
  109. }
  110. } else {
  111. if (_curPage == 1) {
  112. //展示无数据的布局
  113. state.datas.clear();
  114. changeLoadingState(LoadState.State_Empty);
  115. refreshController.finishRefresh();
  116. } else {
  117. //展示加载完成,没有更多数据了
  118. refreshController.finishLoad(IndicatorResult.noMore);
  119. }
  120. }
  121. }
  122. @override
  123. void onReady() {
  124. super.onReady();
  125. fetchAppliedStaffList();
  126. registerEventBus();
  127. }
  128. @override
  129. void onClose() {
  130. unregisterEventBus();
  131. state.datas.clear();
  132. super.onClose();
  133. }
  134. // EventBus 的事件接收
  135. Subscription? subscribe;
  136. void registerEventBus() {
  137. subscribe = bus.on(AppConstant.eventAppliedListRefresh, (arg) {
  138. var appliedId = arg as String;
  139. if (Utils.isNotEmpty(appliedId)) {
  140. fetchItemByIdAndRefreshItem(appliedId);
  141. } else {
  142. refreshController.callRefresh();
  143. }
  144. });
  145. }
  146. void unregisterEventBus() {
  147. bus.off(AppConstant.eventAppliedListRefresh, subscribe);
  148. }
  149. /// 搜索员工
  150. void doSearch(String keyword) {
  151. state.keyword = keyword;
  152. //赋值之后刷新
  153. refreshController.callRefresh();
  154. }
  155. /// 清空筛选条件
  156. void resetFiltering() {
  157. state.keyword = "";
  158. state.searchController.text = "";
  159. //赋值之后刷新
  160. refreshController.callRefresh();
  161. }
  162. /// 展示添加员工的弹窗
  163. void showAddStaffDialog() {
  164. DialogEngine.show(
  165. widget: AppliedAddStaff(
  166. jobId: state.jobId!,
  167. confirmAction: (selectedIds) {
  168. //调用接口添加员工
  169. _requestAddStaff2Applied(selectedIds);
  170. },
  171. ),
  172. );
  173. }
  174. //调用接口添加员工
  175. void _requestAddStaff2Applied(String selectedIds) async {
  176. var result = await _jobRepository.addStaff2Job(state.jobId, selectedIds, cancelToken: cancelToken);
  177. if (result.isSuccess) {
  178. var addStaffEntity = result.data;
  179. List<String> filteredMessages = [];
  180. if (addStaffEntity != null && addStaffEntity.resultList?.isNotEmpty == true) {
  181. filteredMessages = addStaffEntity.resultList!
  182. .where((resultList) => resultList.result == false && Utils.isNotEmpty(resultList.msg))
  183. .map((resultList) => '${resultList.name} : ${resultList.msg!}')
  184. .toList();
  185. }
  186. if (filteredMessages.isNotEmpty) {
  187. //有错误信息
  188. NotifyEngine.showFailure(filteredMessages.join(" , "));
  189. } else {
  190. //无错误信息
  191. NotifyEngine.showSuccess("Successful".tr);
  192. //添加成功之后刷新页面
  193. refreshController.callRefresh();
  194. }
  195. } else {
  196. ToastEngine.show(result.errorMsg ?? "Network Load Error".tr);
  197. return;
  198. }
  199. }
  200. /// 去编辑员工信息页面
  201. void gotoAppliedEditPage(JobListAppliedStaffListRows data) {
  202. JobAppliedEditPage.startInstance(data.appliedId.toString());
  203. }
  204. /// 展示评论的弹窗
  205. void showRemarkDialog(JobListAppliedStaffListRows data) async {
  206. //请求接口获取到已评论的数据
  207. var result = await _jobRepository.fetchAppliedStaffReviewView(data.appliedId.toString());
  208. if (result.isSuccess) {
  209. //接口数据获取成功,展示弹窗
  210. DialogEngine.show(
  211. widget: AppliedStaffReviews(
  212. appliedReviews: result.data!,
  213. confirmAction: (attitudeRate, performanceRate, experienceRate, groomingRate, content) async {
  214. //请求接口,提交评论
  215. var submitResult = await _jobRepository.remarkAppliedSingleStaffSubmit(
  216. data.appliedId.toString(),
  217. attitudeRate,
  218. groomingRate,
  219. performanceRate,
  220. experienceRate,
  221. content,
  222. );
  223. if (submitResult.isSuccess) {
  224. NotifyEngine.showSuccess("Successful".tr);
  225. } else {
  226. ToastEngine.show(submitResult.errorMsg ?? "Network Load Error".tr);
  227. }
  228. },
  229. ),
  230. );
  231. } else {
  232. ToastEngine.show(result.errorMsg ?? "Network Load Error".tr);
  233. return;
  234. }
  235. }
  236. /// 去展示员工状态的审核流程页面
  237. void gotoAppliedWorkflowPage(JobListAppliedStaffListRows data) {
  238. AppliedWorkflowPage.startInstance(data.appliedId.toString());
  239. }
  240. /// 去查看员工详情页面
  241. void gotoStaffDetailPage(JobListAppliedStaffListRows data) {
  242. AppliedStaffDetailPage.startInstance(data.memberId.toString());
  243. }
  244. /// Item选中与未选中设置
  245. void doSelectedOrNot(JobListAppliedStaffListRows data) {
  246. //只有 Approve = 3 的状态才能选中
  247. if (data.status == 3) {
  248. data.isSelected = !data.isSelected;
  249. update();
  250. }
  251. }
  252. /// 批量修改的弹窗
  253. void showBatchModifyDialog() async {
  254. if (state.jobInfo == null) return;
  255. //找出已经选中的员工(只有状态为3 Approve的状态才能修改)
  256. var selectedList = state.datas.where((element) => element.isSelected && element.status == 3).toList(growable: false);
  257. if (selectedList.isNotEmpty) {
  258. var ids = selectedList.map((e) => e.appliedId.toString()).toList(growable: false);
  259. var separatedIds = ids.join(',');
  260. DialogEngine.show(
  261. widget: AppliedButchModify(
  262. selectedStartDate: DateTimeUtils.getDateTime(state.jobInfo?.startTime ?? ""),
  263. selectedEndDate: DateTimeUtils.getDateTime(state.jobInfo?.endTime ?? ""),
  264. confirmAction: (start, end) {
  265. _requestBatchModify(start, end, separatedIds);
  266. }));
  267. } else {
  268. ToastEngine.show("Please select the applied record".tr);
  269. }
  270. }
  271. /// 执行批量修改的请求
  272. void _requestBatchModify(DateTime start, DateTime end, String separatedIds) async {
  273. //执行请求
  274. var result = await _jobRepository.batchEditStaffCheckTime(
  275. state.jobId,
  276. separatedIds,
  277. DateTimeUtils.formatDate(start),
  278. DateTimeUtils.formatDate(end),
  279. cancelToken: cancelToken,
  280. );
  281. if (result.isSuccess) {
  282. NotifyEngine.showSuccess("Successful".tr);
  283. //调用接口刷新指定的Staff的信息
  284. fetchItemByIdAndRefreshItem(separatedIds);
  285. } else {
  286. ToastEngine.show(result.errorMsg ?? "Network Load Error".tr);
  287. return;
  288. }
  289. }
  290. /// 批准的操作
  291. void operationApprove() async {
  292. //找出已经选中的员工(只有状态为3 Approve的状态才能修改)
  293. var selectedList = state.datas.where((element) => element.isSelected && element.status == 3).toList(growable: false);
  294. if (selectedList.isNotEmpty) {
  295. var ids = selectedList.map((e) => e.appliedId.toString()).toList(growable: false);
  296. var separatedIds = ids.join(',');
  297. // Are you sure 的弹窗
  298. DialogEngine.show(
  299. widget: AppDefaultDialog(
  300. title: "Message".tr,
  301. message: "Are you sure you want to setting approved?".tr,
  302. confirmAction: () async {
  303. //执行请求
  304. var result = await _jobRepository.submitBatchStaffApprove(separatedIds, cancelToken: cancelToken);
  305. if (result.isSuccess) {
  306. NotifyEngine.showSuccess("Successful".tr);
  307. //调用接口刷新指定的Staff的信息
  308. fetchItemByIdAndRefreshItem(separatedIds);
  309. } else {
  310. ToastEngine.show(result.errorMsg ?? "Network Load Error".tr);
  311. return;
  312. }
  313. },
  314. ),
  315. );
  316. } else {
  317. ToastEngine.show("Please select the applied record".tr);
  318. }
  319. }
  320. /// 根据ID获取Item对象,用于刷新
  321. void fetchItemByIdAndRefreshItem(String appliedIds) async {
  322. var result = await _jobRepository.fetchItemByAppliedIds(
  323. state.jobId,
  324. appliedIds,
  325. cancelToken: cancelToken,
  326. );
  327. //处理数据
  328. if (result.isSuccess) {
  329. var data = result.data;
  330. if (data != null && data.rows != null && data.rows!.isNotEmpty) {
  331. List<JobListAppliedStaffListRows> newItem = data.rows!;
  332. // 创建一个 Map 来加速查找
  333. Map<int, JobListAppliedStaffListRows> newItemMap = {for (var item in newItem) item.appliedId: item};
  334. // 遍历 state.datas 进行替换
  335. for (int i = 0; i < state.datas.length; i++) {
  336. if (newItemMap.containsKey(state.datas[i].appliedId)) {
  337. state.datas[i] = newItemMap[state.datas[i].appliedId]!;
  338. }
  339. }
  340. //刷新
  341. update();
  342. }
  343. } else {
  344. ToastEngine.show(result.errorMsg ?? "Network Load Error".tr);
  345. }
  346. }
  347. }