user-edit.ts 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. import tickleBehavior, {
  2. getTickleContext,
  3. } from "../../../../core/behavior/tickle.behavior";
  4. import DictionariesBehavior from "../../../../core/behavior/dictionaries.behavior";
  5. import PageContainerBehavior from "../../../../core/behavior/page-container.behavior";
  6. import { PageLoadBehavior } from "../../../../core/behavior/page-loading.behavior";
  7. import { getUserInfoMethod, updateUserInfoMethod } from "../../request";
  8. // module/user/pages/user-edit/user-edit.ts
  9. Component({
  10. behaviors: [
  11. PageContainerBehavior,
  12. PageLoadBehavior<App.Patient.Model>(getUserInfoMethod),
  13. DictionariesBehavior,
  14. tickleBehavior,
  15. ],
  16. lifetimes: {
  17. attached() {},
  18. },
  19. properties: {},
  20. data: {
  21. model: null as App.Patient.Model | null,
  22. name: "",
  23. cardno: "",
  24. age: "",
  25. sex: "",
  26. dirty: false,
  27. idCardValid: false,
  28. },
  29. observers: {
  30. 'model.cardno'(value: string) {
  31. const that = this as any;
  32. const v = (value || '').trim();
  33. if (!v) return that.setData({ idCardValid: false });
  34. if (/^\d{17}[\dXx]$/.test(v)) {
  35. const { valid } = (that as any).validateIdCard18(v);
  36. that.setData({ idCardValid: !!valid });
  37. } else {
  38. that.setData({ idCardValid: false });
  39. }
  40. },
  41. },
  42. methods: {
  43. validateIdCard18(cardno: string): { valid: boolean; message?: string } {
  44. const code = (cardno || '').toUpperCase();
  45. if (!/^\d{17}[\dX]$/.test(code)) return { valid: false, message: '身份证号格式不正确' };
  46. const year = parseInt(code.substring(6, 10));
  47. const month = parseInt(code.substring(10, 12));
  48. const day = parseInt(code.substring(12, 14));
  49. const birth = new Date(year, month - 1, day);
  50. if (
  51. birth.getFullYear() !== year ||
  52. birth.getMonth() + 1 !== month ||
  53. birth.getDate() !== day
  54. ) return { valid: false, message: '出生日期无效' };
  55. const Wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
  56. const Vi = ['1','0','X','9','8','7','6','5','4','3','2'];
  57. let sum = 0;
  58. for (let i = 0; i < 17; i++) sum += parseInt(code[i]) * Wi[i];
  59. const check = Vi[sum % 11];
  60. if (check !== code[17]) return { valid: false, message: '校验位错误' };
  61. return { valid: true };
  62. },
  63. onFormInput(event: WechatMiniprogram.Input) {
  64. const that = this as any;
  65. const field = (event.currentTarget?.dataset as any)?.field || (event.target?.dataset as any)?.field;
  66. if (!field) return;
  67. const value = (event.detail as any)?.value;
  68. if (field === 'cardno') {
  69. that.updateByCardno(value);
  70. } else if (field === 'age') {
  71. that.setData({ ['model.age']: value });
  72. }
  73. },
  74. onFormChange(event: WechatMiniprogram.CustomEvent) {
  75. const that = this as any;
  76. const { name, value } = (event.detail as any) || {};
  77. if (!name) return;
  78. that.setData({ [`model.${name}`]: value });
  79. },
  80. onSexChange(event: WechatMiniprogram.CustomEvent) {
  81. const that = this as any;
  82. const value = (event as any)?.detail; // field-radio 直接传递选中值
  83. that.setData({ ['model.sex']: value.sex });
  84. },
  85. updateByCardno(cardno?: string) {
  86. const that = this as any;
  87. const normalized = (cardno || '').trim();
  88. that.setData({ ['model.cardno']: normalized });
  89. if (!normalized) {
  90. // 清空身份证:同步清空年龄与性别
  91. return that.setData({ ['model.age']: '', ['model.sex']: '', idCardValid: false });
  92. }
  93. // 仅支持18位身份证解析
  94. if (/^\d{17}[\dXx]$/.test(normalized)) {
  95. const { valid, message } = (this as any).validateIdCard18(normalized);
  96. if (!valid) {
  97. that.setData({ ['model.age']: '', ['model.sex']: '', idCardValid: false });
  98. return getTickleContext.call(that).showWarnMessage(message || '身份证号不合法');
  99. }
  100. const year = parseInt(normalized.substring(6, 10));
  101. const month = parseInt(normalized.substring(10, 12));
  102. const day = parseInt(normalized.substring(12, 14));
  103. const birth = new Date(year, month - 1, day);
  104. const now = new Date();
  105. let age = now.getFullYear() - birth.getFullYear();
  106. const m = now.getMonth() - birth.getMonth();
  107. if (m < 0 || (m === 0 && now.getDate() < birth.getDate())) age--;
  108. const sexCode = parseInt(normalized.substring(16, 17));
  109. // 字典通常 0=男 1=女 或 1=女? 需与现有校验一致:文件中 womenSpecialPeriod 用 sex==='1' 判断为女性
  110. const sex = sexCode % 2 === 0 ? '1' : '0';
  111. that.setData({ ['model.age']: age, ['model.sex']: sex, idCardValid: true });
  112. } else {
  113. // 未满18位时,实时清空由身份证推导的年龄/性别,保持可编辑
  114. that.setData({ ['model.age']: '', ['model.sex']: '', idCardValid: false });
  115. }
  116. },
  117. async onSubmit(event: WechatMiniprogram.FormSubmit) {
  118. console.log(event, "onSubmit");
  119. this.setData({ dirty: true });
  120. const data = { ...this.data.model, ...event?.detail?.value } as any;
  121. console.log(data, "穿的数据");
  122. // 如填写了身份证,进行18位身份证合法性校验
  123. if (data.cardno) {
  124. const { valid, message } = (this as any).validateIdCard18((data.cardno || '').toString());
  125. if (!valid) return this.showMessageAndDirty(message || '身份证号不合法');
  126. }
  127. // 必填:年龄、性别
  128. if (!data.age) return this.showMessageAndDirty("请填写年龄");
  129. if (data.sex === undefined || data.sex === null || data.sex === '') return this.showMessageAndDirty("请选择性别");
  130. if (!data.patientId) data.patientId = wx.getStorageSync("patientId");
  131. // 表单验证
  132. if (data.sex.toString() === "1" && !data.womenSpecialPeriod) return this.showMessageAndDirty("请至少选择一项女性特殊期");
  133. if (!data.height) return this.showMessageAndDirty("请填写身高");
  134. if (!data.weight) return this.showMessageAndDirty("请填写体重");
  135. try {
  136. console.log(data, "data");
  137. await updateUserInfoMethod(<any>data)
  138. wx.navigateBack();
  139. this.getOpenerEventChannel().emit("update2", event.detail.value);
  140. } catch (error) {
  141. const msg = (error as any)?.errMsg || '更新失败';
  142. this.showMessageAndDirty(msg);
  143. }
  144. },
  145. showMessageAndDirty(message: string) {
  146. if (message) getTickleContext.call(this).showWarnMessage(message);
  147. setTimeout(() => this.setData({ dirty: false }), 200);
  148. },
  149. },
  150. });