list.dart 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. import 'package:fis_jsonrpc/rpc.dart';
  2. import 'package:flutter/foundation.dart';
  3. import 'package:flutter/material.dart';
  4. import 'package:flutter_screenutil/flutter_screenutil.dart';
  5. import 'package:get/get.dart';
  6. import 'package:vitalapp/architecture/utils/datetime.dart';
  7. import 'package:vitalapp/architecture/utils/prompt_box.dart';
  8. import 'package:vitalapp/components/table/table_column.dart';
  9. import 'package:vitalapp/managers/interfaces/registration.dart';
  10. import 'package:vitalapp/pages/medical_checkup_station/registration/controller.dart';
  11. import 'package:vitalapp/pages/medical_checkup_station/registration/state/list.dart';
  12. import 'package:vitalapp/pages/medical_checkup_station/registration/widgets/form/index.dart';
  13. import 'package:vitalapp/pages/medical_checkup_station/registration/widgets/report/report_preview.dart';
  14. import 'package:vitalapp/pages/medical_checkup_station/usb_print/page/temp/label_temp.dart';
  15. class RegistrationListController {
  16. late RegistrationController registrationController;
  17. RegistrationListController(RegistrationController controller) {
  18. registrationController = controller;
  19. }
  20. final state = ListState();
  21. final _registrationManager = Get.find<IRegistrationManager>();
  22. ResidentModel currentResident = ResidentModel(idNumber: "");
  23. List<String> _allExam = [
  24. "HEIBasic",
  25. "HEIUrinalysis",
  26. "HEIUltrasonic",
  27. "HEIBiochemical",
  28. "HEIBloodRoutine",
  29. "HEIECG",
  30. "HEITCMC"
  31. ];
  32. List<String> examList() {
  33. List<String> missingData = _allExam
  34. .where((element) =>
  35. !(currentResident.finishedExamKeys ?? []).contains(element))
  36. .toList();
  37. return missingData;
  38. }
  39. Future<void> getRegisterInfoPage({
  40. int? pageSize = 10,
  41. int? pageIndex = 1,
  42. String? keyword = "",
  43. DateTime? startTime,
  44. DateTime? endTime,
  45. }) async {
  46. registrationController.tableLoading = true;
  47. registrationController.currPageIndex = pageIndex!;
  48. var result = await registrationController.registrationManager
  49. .getRegisterInfoPageAsync(
  50. pageSize: pageSize,
  51. pageIndex: pageIndex,
  52. keyword: keyword,
  53. startTime: startTime,
  54. endTime: endTime,
  55. );
  56. List<ResidentModel> _residentList = [];
  57. if (result?.pageData != null) {
  58. for (RegisterInfoDTO i in result!.pageData!) {
  59. String statusStr = '';
  60. ExamStateEnum status = i.state;
  61. switch (status) {
  62. case ExamStateEnum.Unchecked:
  63. statusStr = "未体检";
  64. break;
  65. case ExamStateEnum.Invalid:
  66. statusStr = "已作废";
  67. break;
  68. case ExamStateEnum.Inspected:
  69. statusStr = "已体检";
  70. break;
  71. case ExamStateEnum.Reported:
  72. statusStr = "已报告";
  73. break;
  74. }
  75. _residentList.add(
  76. ResidentModel(
  77. name: i.name ?? '',
  78. idNumber: i.iDCardNo ?? '',
  79. code: i.code ?? '',
  80. homeAddress: i.adress,
  81. age: getAgeOfIdNumber(i.iDCardNo ?? ''),
  82. physicalExamNumber: i.physicalExamNumber,
  83. phone: i.phone,
  84. finishedExamKeys: i.finishedExamKeys,
  85. physicalExamStatus: statusStr,
  86. ),
  87. );
  88. }
  89. registrationController.appointmentModelListLength = result.totalCount;
  90. }
  91. registrationController.residentList = _residentList;
  92. registrationController.tableLoading = false;
  93. registrationController.update(["registration_table"]);
  94. registrationController.update(["registration_table_pagination"]);
  95. }
  96. String getAgeOfIdNumber(String idNumber) {
  97. if (idNumber.isEmpty) return '';
  98. final idCardRegex = RegExp(r'^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})(\d|X)$');
  99. final match = idCardRegex.firstMatch(idNumber);
  100. if (match != null) {
  101. final year = int.parse(match.group(2)!);
  102. final month = int.parse(match.group(3)!);
  103. final day = int.parse(match.group(4)!);
  104. final birthDate = DateTime(year, month, day);
  105. String age = DataTimeUtils.calculateAge(birthDate);
  106. return age;
  107. }
  108. return ''; // 返回一个默认值
  109. }
  110. /// 登记列表表头
  111. List<TableColumn<ResidentModel>> buildTableColumns() {
  112. var textStyle = TextStyle(
  113. fontSize: 16,
  114. overflow: TextOverflow.ellipsis,
  115. );
  116. return <TableColumn<ResidentModel>>[
  117. TableColumn<ResidentModel>(
  118. headerText: "体检号",
  119. maxWidth: 150,
  120. render: (rowData, index) => Container(
  121. padding: const EdgeInsets.symmetric(vertical: 16),
  122. child: Text(
  123. rowData.physicalExamNumber ?? '',
  124. style: textStyle,
  125. ),
  126. ),
  127. ),
  128. TableColumn<ResidentModel>(
  129. headerText: "姓名",
  130. maxWidth: 100,
  131. render: (rowData, index) => Text(
  132. rowData.name ?? '',
  133. style: textStyle,
  134. ),
  135. ),
  136. TableColumn<ResidentModel>(
  137. headerText: "年龄",
  138. maxWidth: 80,
  139. render: (rowData, index) => Text(
  140. rowData.age != null ? rowData.age.toString() : "",
  141. style: textStyle,
  142. ),
  143. ),
  144. TableColumn<ResidentModel>(
  145. headerText: "身份证号",
  146. maxWidth: 200,
  147. render: (rowData, index) => Text(
  148. rowData.idNumber,
  149. style: textStyle,
  150. ),
  151. ),
  152. // TableColumn<ResidentModel>(
  153. // headerText: "家庭地址",
  154. // render: (rowData, index) => Center(
  155. // child: Text(
  156. // rowData.homeAddress ?? "",
  157. // style: textStyle,
  158. // ),
  159. // ),
  160. // ),
  161. TableColumn<ResidentModel>(
  162. headerText: "手机号",
  163. maxWidth: 120,
  164. render: (rowData, index) => Center(
  165. child: Text(
  166. rowData.phone ?? '',
  167. style: textStyle,
  168. ),
  169. ),
  170. ),
  171. TableColumn<ResidentModel>(
  172. headerText: "体检状态",
  173. maxWidth: 120,
  174. render: (rowData, index) => Center(
  175. child: Text(
  176. rowData.physicalExamStatus ?? "",
  177. style: textStyle,
  178. ),
  179. ),
  180. ),
  181. TableColumn<ResidentModel>(
  182. headerText: "操作",
  183. // maxWidth: 150,
  184. render: (rowData, index) => Row(
  185. mainAxisAlignment: MainAxisAlignment.center,
  186. children: [
  187. if (!kIsWeb)
  188. TextButton(
  189. onPressed: () {
  190. if (registrationController.printInfo == null) {
  191. PromptBox.toast("打印出错");
  192. return;
  193. }
  194. Get.dialog(
  195. Center(
  196. child: Stack(
  197. children: [
  198. ScreenUtilInit(
  199. designSize: const Size(360 * 1.2, 240 * 1.2),
  200. scaleByHeight: true,
  201. builder: (BuildContext context, Widget? child) {
  202. return LabelTempWidget(
  203. registrationController.printInfo!,
  204. labelWidth: 360,
  205. labelHeight: 240,
  206. residentModel: rowData,
  207. );
  208. },
  209. ),
  210. Positioned(
  211. right: 66,
  212. child: IconButton(
  213. onPressed: () {
  214. Get.back();
  215. },
  216. icon: Icon(
  217. Icons.close,
  218. size: 40,
  219. ),
  220. ),
  221. ),
  222. ],
  223. ),
  224. ),
  225. );
  226. },
  227. child: const Text("打印标签"),
  228. ),
  229. TextButton(
  230. onPressed: () async {
  231. final PatientDTO? patient = PatientDTO(
  232. patientName: rowData.name,
  233. phone: rowData.phone,
  234. patientAddress: rowData.homeAddress,
  235. cardNo: rowData.idNumber,
  236. );
  237. final PatientDTO? result = await Get.dialog<PatientDTO>(
  238. RegistrationFormDialog(
  239. patient: patient,
  240. isEdit: true,
  241. ),
  242. barrierDismissible: false,
  243. );
  244. print(result);
  245. },
  246. child: const Text("编辑"),
  247. ),
  248. if (kIsWeb)
  249. TextButton(
  250. onPressed: () {
  251. Get.dialog(
  252. _buildEditingExcepting(rowData),
  253. barrierDismissible:
  254. false, // Prevent dialog from closing on outside tap
  255. );
  256. },
  257. child: const Text("健康指导")),
  258. if (kIsWeb)
  259. TextButton(
  260. onPressed: () async {
  261. List<ReportDTO2>? reportList = await registrationController
  262. .registrationManager
  263. .getVitalReportInfoAsync(
  264. physicalExamNumber: rowData.physicalExamNumber ?? '',
  265. );
  266. ReportDTO2? report = reportList
  267. ?.firstWhereOrNull((element) => element.key == "Part");
  268. if (report != null) {
  269. Get.dialog(
  270. ReportPreview(
  271. pdfUrl: report.previewInfo?.fileToken ?? "",
  272. ),
  273. );
  274. } else {
  275. PromptBox.toast("暂无报告");
  276. }
  277. },
  278. child: const Text("查看报告"),
  279. ),
  280. ],
  281. ),
  282. ),
  283. ];
  284. }
  285. Widget _buildEditingExcepting(ResidentModel rowData) {
  286. return Dialog(
  287. backgroundColor: Colors.white, // 设置对话框背景颜色为白色
  288. child: Container(
  289. padding: EdgeInsets.all(16.0),
  290. child: Stack(
  291. children: [
  292. Column(
  293. children: [
  294. SizedBox(
  295. height: 20,
  296. ),
  297. Expanded(
  298. child: TextField(
  299. expands: true,
  300. maxLines: null,
  301. decoration: InputDecoration(
  302. hintText: '请输入健康指导信息...',
  303. border: InputBorder.none,
  304. ),
  305. onChanged: (value) {
  306. state.resultsAndSuggestions = value;
  307. },
  308. ),
  309. ),
  310. ElevatedButton(
  311. onPressed: () async {
  312. await _registrationManager.updateResultsAndSuggestionsAsync(
  313. rowData.code ?? "", state.resultsAndSuggestions ?? '');
  314. Get.back(); // Close the dialog
  315. },
  316. child: Text('提交'),
  317. ),
  318. ],
  319. ),
  320. Positioned(
  321. top: 1.0,
  322. right: 1.0,
  323. child: IconButton(
  324. icon: Icon(Icons.close),
  325. onPressed: () {
  326. Get.back();
  327. },
  328. ),
  329. ),
  330. ],
  331. ),
  332. ),
  333. );
  334. }
  335. }