list.dart 11 KB

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