controller.dart 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. import 'package:fis_jsonrpc/rpc.dart';
  2. import 'package:get/get.dart';
  3. import 'package:vitalapp/architecture/defines.dart';
  4. import 'package:vitalapp/architecture/utils/prompt_box.dart';
  5. import 'package:vitalapp/managers/interfaces/patient.dart';
  6. import 'package:vitalapp/pages/controllers/crowd_labels.dart';
  7. import 'package:vitalapp/pages/controllers/home_nav_mixin.dart';
  8. import 'package:vitalapp/pages/patient/card_reader/index.dart';
  9. import 'package:vitalapp/pages/patient/create/state.dart';
  10. import 'package:vitalapp/pages/patient/list/controller.dart';
  11. import 'package:vitalapp/routes/nav_ids.dart';
  12. class CreatePatientController extends FControllerBase with HomeNavMixin {
  13. final _patientManager = Get.find<IPatientManager>();
  14. final crowdLabelsController = Get.find<CrowdLabelsController>();
  15. final state = CreatePatientState();
  16. @override
  17. Future<void> onLoad() {
  18. final params = Get.parameters;
  19. if (params.containsKey("from")) {
  20. if (params["from"] == "list") {
  21. state.isCreateOnly = true;
  22. }
  23. }
  24. return super.onLoad();
  25. }
  26. /// 保存档案,调整签约
  27. void gotoSignContract() async {
  28. setBusy("正在保存...");
  29. final code = await _submitForm();
  30. if (code == null) {
  31. busy = false;
  32. PromptBox.toast("保存失败");
  33. return;
  34. }
  35. // final code = "13B95A2B2790464BBFD9B30A71F15C95";
  36. busy = false;
  37. Future.delayed(
  38. const Duration(milliseconds: 800),
  39. () {
  40. state.reset(); // 重置状态
  41. },
  42. );
  43. Get.toNamed(
  44. "/contract/package_list",
  45. parameters: {"patientCode": code},
  46. );
  47. // Get.find<HomeController>().switchNavByName("/patient/list");
  48. // Future.delayed(
  49. // const Duration(milliseconds: 800),
  50. // () {
  51. // // TODO:
  52. // Get.find<PatientListController>().gotoDetail(code);
  53. // busy = false;
  54. // },
  55. // );
  56. }
  57. /// 存为档案,调整到档案详情
  58. void gotoPatientDetail() async {
  59. setBusy("正在保存...");
  60. final code = await _submitForm();
  61. if (code == null) {
  62. busy = false;
  63. PromptBox.toast("保存失败");
  64. return;
  65. } else {
  66. Future.delayed(
  67. const Duration(milliseconds: 800),
  68. () {
  69. state.reset(); // 重置状态
  70. busy = false;
  71. PromptBox.toast("保存成功");
  72. },
  73. );
  74. }
  75. ///不跳转到详情页
  76. // Get.find<HomeController>().switchNavByName("/patient/list");
  77. Get.put(PatientListController());
  78. Future.delayed(
  79. const Duration(milliseconds: 800),
  80. () {
  81. Get.find<PatientListController>().gotoDetail(code);
  82. busy = false;
  83. },
  84. );
  85. }
  86. /// 打开读卡器弹窗
  87. void openCardReader() async {
  88. final CardReaderResult? result = await Get.dialog<CardReaderResult>(
  89. const CardReaderDialog(),
  90. );
  91. if (result != null && result.success) {
  92. print("读卡成功,身份证号:${result.code}");
  93. } else {
  94. print("读卡取消");
  95. }
  96. }
  97. /// 保存并返回
  98. void saveAndBack() async {
  99. setBusy("正在保存...");
  100. final code = await _submitForm();
  101. busy = false;
  102. if (code == null) {
  103. busy = false;
  104. return;
  105. }
  106. Get.back(result: code, id: NavIds.HOME);
  107. }
  108. /// 点击读卡事件
  109. void onReadCardClicked() {
  110. Get.snackbar(
  111. "提示",
  112. "此功能尚未开发",
  113. duration: const Duration(seconds: 2),
  114. );
  115. }
  116. /// 处理 “同户籍地址” 勾选变更事件
  117. void onSyncAddressCheckChanged(bool isChecked) {
  118. state.isSyncAddresses = isChecked;
  119. if (isChecked) {
  120. // 同步户籍地址到现住地址
  121. state.address = state.censusRegister;
  122. } else {
  123. state.address = "";
  124. }
  125. }
  126. /// 处理户籍地址变更
  127. void onCensusRegisterChanged(String value) {
  128. state.censusRegister = value;
  129. if (state.isSyncAddresses) {
  130. state.address = value;
  131. }
  132. }
  133. Future<String?> _submitForm() async {
  134. final validateMsg = await _validateForm();
  135. if (validateMsg != null) {
  136. toast(validateMsg);
  137. return null;
  138. }
  139. final crowdLabelCodes = crowdLabelsController.state.selectedCodes;
  140. final request = CreatePatientRequest(
  141. patientName: state.name,
  142. phone: state.phoneNo,
  143. patientGender: state.gender,
  144. nationality: state.nation,
  145. birthday: state.birthday?.toUtc(),
  146. cardType: state.cardType,
  147. cardNo: state.cardNo,
  148. patientAddress: state.address,
  149. permanentResidenceAddress: state.censusRegister,
  150. crowdLabels: crowdLabelCodes,
  151. );
  152. final result = await _patientManager.create(request);
  153. return result;
  154. }
  155. bool validateIDCard(String idCard) {
  156. // 校验身份证号码长度
  157. if (idCard.length != 18) {
  158. return false;
  159. }
  160. // 校验前17位是否为数字
  161. String idCard17 = idCard.substring(0, 17);
  162. if (!isNumeric(idCard17)) {
  163. return false;
  164. }
  165. // 校验最后一位校验码
  166. String checkCode = getCheckCode(idCard17);
  167. if (idCard[17].toUpperCase() != checkCode) {
  168. return false;
  169. }
  170. return true;
  171. }
  172. bool isNumeric(String str) {
  173. if (str.isEmpty) {
  174. return false;
  175. }
  176. return double.tryParse(str) != null;
  177. }
  178. String getCheckCode(String idCard17) {
  179. List<int> coefficients = [
  180. 7,
  181. 9,
  182. 10,
  183. 5,
  184. 8,
  185. 4,
  186. 2,
  187. 1,
  188. 6,
  189. 3,
  190. 7,
  191. 9,
  192. 10,
  193. 5,
  194. 8,
  195. 4,
  196. 2
  197. ];
  198. List<String> checkCodes = [
  199. '1',
  200. '0',
  201. 'X',
  202. '9',
  203. '8',
  204. '7',
  205. '6',
  206. '5',
  207. '4',
  208. '3',
  209. '2'
  210. ];
  211. int sum = 0;
  212. for (int i = 0; i < idCard17.length; i++) {
  213. int digit = int.parse(idCard17[i]);
  214. sum += digit * coefficients[i];
  215. }
  216. int remainder = sum % 11;
  217. return checkCodes[remainder];
  218. }
  219. Future<String?> _validateForm() async {
  220. if (state.name.isEmpty) {
  221. return "请填写姓名";
  222. }
  223. if (state.cardNo.isEmpty) {
  224. return "请填写证件号";
  225. }
  226. bool isNotIDCard = validateIDCard(state.cardNo);
  227. if (!isNotIDCard && state.cardType == CardTypeEnum.Identity) {
  228. return "请填写正确的证件号";
  229. }
  230. /// TODO 需求变更暂时删除
  231. // final selectedNormalCodes = crowdLabelsController.state.selectedNormalCodes;
  232. // if (selectedNormalCodes.length > 1) {
  233. // return "人群分类:一般人群、儿童、孕妇、老年人,只可选择其一!";
  234. // }
  235. // final crowdLabelCodes = crowdLabelsController.state.selectedCodes;
  236. // if (crowdLabelCodes.isEmpty) {
  237. // return "请选择人群分类";
  238. // }
  239. // if (state.gender == GenderEnum.Male &&
  240. // crowdLabelCodes.contains('RQFL_YF')) {
  241. // return "当前居民性别为“男”,人群分类不可选择孕妇!";
  242. // }
  243. return null;
  244. }
  245. }