addMember.vue 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <template>
  2. <view class="container">
  3. <view class="content">
  4. <view class="public_tip">请正确填写就诊人姓名、身份证号、手机号,并再次核实就诊 人信息的正确性</view>
  5. <formPage :formConfigList="formConfigList" @toSelect="toSelect"></formPage>
  6. </view>
  7. </view>
  8. </template>
  9. <script lang="ts" setup>
  10. import { ref } from 'vue';
  11. import { useOnLoad, usePreserMember } from '@/hook';
  12. import {
  13. addBaseMemberByEncryptionStore_V3,
  14. queryMemberCardList_V3,
  15. checkVerificationCode_V3
  16. } from '@/pagesPersonal/service/patientManagement';
  17. import { common } from '@/utils';
  18. import formPage from "@/pagesPersonal/st1/components/formPage/formPage.vue";
  19. const app = getApp();
  20. const formConfigList = ref<any[]>([]);
  21. const queryBean = ref<any>({});
  22. const pageType = ref("");
  23. const dialogIsShow = ref(false);
  24. const dialogIsSuccess = ref(true);
  25. const currentType = ref('default'); // Default value based on usage in dialogConfirmClick
  26. useOnLoad((options) => {
  27. let configList = common.deepCopy(uni.getStorageSync('formConfigList'), []).filter((item: any) => item.formScene == 'ADDMEMBER');
  28. // 如果有传queryBean,方向添值进入表单内容
  29. if (options.queryBean) {
  30. let qBean = options.queryBean ? JSON.parse(decodeURIComponent(options.queryBean)) : {};
  31. configList.map((item: any) => {
  32. if (common.isNotEmpty(qBean[item.vModel])) {
  33. // 判断等于input输入框类型 直接复制
  34. if (item.type == 'text') {
  35. item.defValue = qBean[item.vModel];
  36. }
  37. // 判断等于下拉框类型 直接复制
  38. if (item.type == 'select') {
  39. // item.options
  40. }
  41. }
  42. });
  43. queryBean.value = qBean;
  44. }
  45. pageType.value = options.pageType || "";
  46. formConfigList.value = configList;
  47. });
  48. /**
  49. * 接收到组件弹框触发的确定事件
  50. */
  51. const dialogConfirmClick = async () => {
  52. dialogIsShow.value = false;
  53. /**默认方式 需要成功才去跳转 推荐方式和新生儿方式 失败也会添加无卡就诊人 直接跳转即可*/
  54. if ((currentType.value == 'default' && dialogIsSuccess.value && app.globalData.toUrl) || (currentType.value != 'default' && app.globalData.toUrl)) {
  55. /**如果是成功 并且全局存了url变量 跳转到全局URL */
  56. common.goToUrl(app.globalData.toUrl, {
  57. skipWay: "redirectTo"
  58. });
  59. } else {
  60. common.navigateBack(1);
  61. }
  62. };
  63. /**
  64. * 点击下一步
  65. */
  66. const toSelect = async (e: any) => {
  67. // e.detail in Vue might be just e if the event emits the object directly.
  68. // Assuming formPage emits the same object structure as before.
  69. // If formPage uses defineEmits(['toSelect']) and emit('toSelect', detail), then e is detail.
  70. // Checking the old code: bindtoSelect="toSelect", e.detail was used.
  71. // In Vue 3: @toSelect="toSelect", the payload is the first argument.
  72. // We assume the payload structure matches e.detail from the old code.
  73. // However, if formPage is still legacy-style but imported as Vue, let's assume standard Vue event emission.
  74. let detail = e.detail || e; // Fallback for safety
  75. let cType = detail.currentType;
  76. currentType.value = cType;
  77. let fConfigList = detail.formConfigList;
  78. /**过滤出当前展示的表单 */
  79. let currentList = fConfigList.filter((item: any) => item.store.type.indexOf(cType) != '-1' && item.isShow == '1');
  80. let provingCode = currentList.filter((item: any) => item.vModel == 'provingCode')[0]; /**验证码 */
  81. let queryData: any = {
  82. isChildren: cType == 'children' ? '1' : '0',
  83. hosId: app.globalData.districtId || app.globalData.hosId,
  84. pcId: detail.pcId,
  85. verificationCode: provingCode && provingCode.defValue || "",
  86. };
  87. for (let item of currentList) {
  88. /**校验正则 */
  89. if (!check(item, currentList)) {
  90. return;
  91. }
  92. /**添加请求参数 */
  93. if ((item.type == 'text' && item.vModel != "provingCode") || item.type == 'datePicker') {
  94. queryData[item.vModel] = item.defValue;
  95. } else if (item.type == 'region') {
  96. queryData[item.vModel] = item.defValue.join('');
  97. } else if (item.type == 'select' || item.type == 'radio') {
  98. queryData[item.vModel] = item.defValue ? item.options[item.defValue].value : '';
  99. }
  100. }
  101. /**儿童的还要判断姓名跟监护人不一致 */
  102. if (cType == 'children') {
  103. let membername = currentList.filter((item: any) => item.vModel == 'memberName')[0].defValue;
  104. let guardianName = currentList.filter((item: any) => item.vModel == 'guardianName')[0].defValue;
  105. if (membername == guardianName) {
  106. common.showToast('监护人姓名与儿童姓名不能一致');
  107. return;
  108. }
  109. }
  110. let checkType = formConfigList.value.filter((item: any) => item.vModel == 'checkType')[0];
  111. if (checkType && checkType.defValue == '1') {
  112. /**如果是人脸识别 */
  113. let data = {
  114. memberName: formConfigList.value.filter((item: any) => item.vModel == 'memberName')[0].defValue,
  115. idCardNo: formConfigList.value.filter((item: any) => item.vModel == 'certNum')[0].defValue
  116. };
  117. let resp = await startFacialRecognitionVerify(data).then(res => res).catch(err => err);
  118. if (!resp.success) {
  119. return;
  120. }
  121. }
  122. // 判断是否有输入验证码
  123. if (common.isNotEmpty(queryData.verificationCode) && await checkVerificationCode(queryData)) return;
  124. // 校验成功情况验证码数据
  125. queryData.pcId = "";
  126. queryData.verificationCode = "";
  127. // 判断当前为卡号查询就诊信息添加,且没在我们程序内绑定过时,补充信息
  128. if (pageType.value == 'cardAddMember') {
  129. let querData = {
  130. cardEncryptionStore: queryBean.value.encryptionStore,
  131. ...queryData,
  132. };
  133. let { resData: res } = await addBaseMemberByEncryptionStore_V3(querData);
  134. if (res.RespCode == 10000) {
  135. await usePreserMember();
  136. common.navigateBack(2);
  137. }
  138. return;
  139. }
  140. // 然后查询 就诊人院内卡信息走后续流程
  141. let { resp, resData } = await queryMemberCardList_V3(queryData);
  142. if (resData.RespCode == 10000) {
  143. let url = "/pagesPersonal/st1/business/patientManagement/faceChooseVisiCard/faceChooseVisiCard";
  144. let data = "";
  145. if (common.isNotEmpty(resp) && resp.length >= 1) {
  146. queryData.CardType = 1;
  147. data = 'queryData=' + JSON.stringify(queryData) + "&serviceType=addMember";
  148. } else {
  149. data = 'queryData=' + JSON.stringify(queryData) + "&serviceType=noCard_idCard";
  150. }
  151. //如果是添加健康卡
  152. if (pageType.value) {
  153. data += '&pageType=' + pageType.value;
  154. }
  155. common.goToUrl(url, { data, skipWay: 'redirectTo' });
  156. }
  157. };
  158. // 检验验证码
  159. const checkVerificationCode = async (queryData: any) => {
  160. return new Promise(async (resolve, reject) => {
  161. if (common.isEmpty(queryData.pcId)) {
  162. common.showModal('请先获取验证码');
  163. } else {
  164. let reqData = {
  165. pcId: queryData.pcId || '',
  166. verificationCode: queryData.verificationCode,
  167. };
  168. let { resData } = await checkVerificationCode_V3(reqData);
  169. if (resData.RespCode == 10000) {
  170. resolve(false);
  171. return;
  172. }
  173. }
  174. resolve(true);
  175. });
  176. };
  177. /**
  178. * 获取校验规则
  179. */
  180. const check = (item: any, currentList: any[]) => {
  181. if (item.isShow == '1' && item.isMust == '1') {
  182. // 字符串去除所有空格
  183. if (typeof (item.defValue) == "string") {
  184. item.defValue = item.defValue.replace(/\s+/g, "");
  185. }
  186. /**只校验显示 和必填的 */
  187. if (common.isEmpty(item.defValue)) {
  188. common.showToast(item.warnMessage);
  189. return false;
  190. } else {
  191. let reg = item.regularExpressions ? new RegExp(item.regularExpressions) : "";
  192. /**有正则 则校验正则 */
  193. if (!common.isEmpty(item.regularExpressions) && !reg.test(item.defValue)) {
  194. /** 如果类型不是身份证时 证件号码不作格式校验 */
  195. if (item.vModel == 'certNum' || item.vModel == 'guardianCertNum') {
  196. let certType = currentList.filter((ele: any) => (item.vModel == 'certNum' && ele.vModel == 'certType') || (item.vModel == 'guardianCertNum' && ele.vModel == 'guardianCertType'))[0];
  197. if (certType.options[certType.defValue].value != '01') {
  198. return true;
  199. }
  200. }
  201. common.showToast(item.warnMessage);
  202. return false;
  203. }
  204. }
  205. }
  206. return true;
  207. };
  208. // Start Facial Recognition Verify Wrapper
  209. const startFacialRecognitionVerify = (data: any) => {
  210. return new Promise((resolve, reject) => {
  211. // #ifdef MP-WEIXIN
  212. uni.startFacialRecognitionVerify({
  213. checkAliveType: 1, // 1: 读数字 2: 屏幕闪烁
  214. name: data.memberName,
  215. idCardNumber: data.idCardNo,
  216. success: (res) => {
  217. resolve({ success: true, res });
  218. },
  219. fail: (err) => {
  220. console.error('人脸识别失败', err);
  221. common.showToast('人脸识别失败');
  222. resolve({ success: false, err });
  223. }
  224. });
  225. // #endif
  226. // #ifndef MP-WEIXIN
  227. common.showToast('当前环境不支持人脸识别');
  228. resolve({ success: false });
  229. // #endif
  230. });
  231. };
  232. </script>
  233. <style lang="scss" scoped>
  234. </style>