张田田 7 месяцев назад
Родитель
Сommit
ae2be37784

+ 0 - 1
miniprogram/module/health/components/care-record/care-record.ts

@@ -25,7 +25,6 @@ Component({
     goDetail(this: any, e: any) {
     goDetail(this: any, e: any) {
       const id = e.currentTarget.dataset.id;
       const id = e.currentTarget.dataset.id;
       const name = e.currentTarget.dataset.name;
       const name = e.currentTarget.dataset.name;
-      console.log(id, name, "数据");
       if (id) {
       if (id) {
         wx.navigateTo({
         wx.navigateTo({
           url: `/module/care/pages/careDetail/careDetail?id=${id}&name=${name}`,
           url: `/module/care/pages/careDetail/careDetail?id=${id}&name=${name}`,

+ 1 - 1
miniprogram/module/health/components/report-health-index/report-health-index.wxml

@@ -18,7 +18,7 @@
       </block>
       </block>
 
 
     </view>
     </view>
-    <view class="nodata-box">
+    <view class="nodata-box" wx:if="{{!loading && !dataset.length}}">
       <view slot="description" wx:if="{{!loading && !dataset.length}}" >暂无数据</view>
       <view slot="description" wx:if="{{!loading && !dataset.length}}" >暂无数据</view>
     </view>
     </view>
   </view>
   </view>

+ 2 - 2
miniprogram/module/health/components/report-health-patient/report-health-patient.scss

@@ -3,8 +3,8 @@
 @import "../../../../themes/card.scss";
 @import "../../../../themes/card.scss";
 /* module/health/components/report-health-patient/report-health-patient.wxss */
 /* module/health/components/report-health-patient/report-health-patient.wxss */
 .user-image {
 .user-image {
-  width: 104px;
-  height: 104px;
+  width: 208px;
+  height: 208px;
   border-radius: 10px;
   border-radius: 10px;
   margin-right: 10px;
   margin-right: 10px;
 }
 }

+ 1 - 1
miniprogram/module/health/components/report-health-patient/report-health-patient.wxml

@@ -16,7 +16,7 @@
             </block>
             </block>
             <text class="text-item" wx:for="{{job}}" wx:key="*this">{{dictionary.label($dictionaries, 'job', item)}}</text>
             <text class="text-item" wx:for="{{job}}" wx:key="*this">{{dictionary.label($dictionaries, 'job', item)}}</text>
             <view class="text-items" wx:if="{{dataset.phone}}"><text style="color:#8C8C8C">手机号:</text><text style="color:black">{{dataset.phone}}</text></view>
             <view class="text-items" wx:if="{{dataset.phone}}"><text style="color:#8C8C8C">手机号:</text><text style="color:black">{{dataset.phone}}</text></view>
-            <view class="text-items"><text style="color:#8C8C8C" wx:if="{{dataset.cardno}}">身份证号:</text>
+            <view class="text-items" wx:if="{{dataset.cardno}}"><text style="color:#8C8C8C">身份证号:</text>
               <view style="color:black">{{dataset.cardno}}</view>
               <view style="color:black">{{dataset.cardno}}</view>
             </view>
             </view>
           </span>
           </span>

+ 2 - 2
miniprogram/module/user/components/user-data-edit/user-data-edit.wxml

@@ -29,11 +29,11 @@
   </t-cell>
   </t-cell>
 
 
   <t-cell t-class="cell-field" title="饮酒情况">
   <t-cell t-class="cell-field" title="饮酒情况">
-    <field-radio slot="note" name="drinkState" default-value="N" value="{{model['drinkState']}}" options="{{dictionary.options($dictionaries, 'sys_yes_no')}}">
+    <field-radio slot="note" name="drinkState" default-value="N" value="{{model['drinkState'] || 'N'}}" options="{{dictionary.options($dictionaries, 'sys_yes_no')}}">
     </field-radio>
     </field-radio>
   </t-cell>
   </t-cell>
   <t-cell t-class="cell-field" title="吸烟情况">
   <t-cell t-class="cell-field" title="吸烟情况">
-    <field-radio slot="note" name="smokeState" default-value="N" value="{{model['smokeState']}}" options="{{dictionary.options($dictionaries, 'sys_yes_no')}}">
+    <field-radio slot="note" name="smokeState" default-value="N" value="{{model['smokeState'] || 'N'}}" options="{{dictionary.options($dictionaries, 'sys_yes_no')}}">
     </field-radio>
     </field-radio>
   </t-cell>
   </t-cell>
 
 

+ 2 - 1
miniprogram/module/user/pages/user-edit/user-edit.json

@@ -4,6 +4,7 @@
   "usingComponents": {
   "usingComponents": {
     "t-cell": "tdesign-miniprogram/cell/cell",
     "t-cell": "tdesign-miniprogram/cell/cell",
     "form-button": "../../../../components/button/button",
     "form-button": "../../../../components/button/button",
-    "user-data-edit": "../../components/user-data-edit/user-data-edit"
+    "user-data-edit": "../../components/user-data-edit/user-data-edit",
+    "field-radio": "../../components/field-radio/field-radio"
   }
   }
 }
 }

+ 8 - 0
miniprogram/module/user/pages/user-edit/user-edit.scss

@@ -7,4 +7,12 @@
   height: var(--page-container-safeHeight, 100vh);
   height: var(--page-container-safeHeight, 100vh);
   background-color: #F3F3F3;
   background-color: #F3F3F3;
   padding-top: 10px;
   padding-top: 10px;
+}
+.cell-field__inner {
+  padding-left: unset !important;
+  width: 100% !important;
+  height: 100% !important;
+  text-align: right !important;
+  box-sizing: border-box !important;
+  /* margin-left: 29px ; */
 }
 }

+ 117 - 13
miniprogram/module/user/pages/user-edit/user-edit.ts

@@ -21,47 +21,151 @@ Component({
   data: {
   data: {
     model: null as App.Patient.Model | null,
     model: null as App.Patient.Model | null,
     dirty: false,
     dirty: false,
+    idCardValid: false,
+  },
+  observers: {
+    'model.cardno'(value: string) {
+      const that = this as any;
+      const v = (value || '').trim();
+      if (!v) return that.setData({ idCardValid: false });
+      if (/^\d{17}[\dXx]$/.test(v)) {
+        const { valid } = (that as any).validateIdCard18(v);
+        that.setData({ idCardValid: !!valid });
+      } else {
+        that.setData({ idCardValid: false });
+      }
+    },
   },
   },
   methods: {
   methods: {
+    validateIdCard18(cardno: string): { valid: boolean; message?: string } {
+      const code = (cardno || '').toUpperCase();
+      if (!/^\d{17}[\dX]$/.test(code)) return { valid: false, message: '身份证号格式不正确' };
+      const year = parseInt(code.substring(6, 10));
+      const month = parseInt(code.substring(10, 12));
+      const day = parseInt(code.substring(12, 14));
+      const birth = new Date(year, month - 1, day);
+      if (
+        birth.getFullYear() !== year ||
+        birth.getMonth() + 1 !== month ||
+        birth.getDate() !== day
+      ) return { valid: false, message: '出生日期无效' };
+      const Wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
+      const Vi = ['1','0','X','9','8','7','6','5','4','3','2'];
+      let sum = 0;
+      for (let i = 0; i < 17; i++) sum += parseInt(code[i]) * Wi[i];
+      const check = Vi[sum % 11];
+      if (check !== code[17]) return { valid: false, message: '校验位错误' };
+      return { valid: true };
+    },
+    onFormInput(event: WechatMiniprogram.Input) {
+      const that = this as any;
+      const field = (event.currentTarget?.dataset as any)?.field || (event.target?.dataset as any)?.field;
+      if (!field) return;
+      const value = (event.detail as any)?.value;
+      if (field === 'cardno') {
+        that.updateByCardno(value);
+      } else if (field === 'age') {
+        that.setData({ ['model.age']: value });
+      }
+    },
+    onFormChange(event: WechatMiniprogram.CustomEvent) {
+      const that = this as any;
+      const { name, value } = (event.detail as any) || {};
+      if (!name) return;
+      that.setData({ [`model.${name}`]: value });
+    },
+    onSexChange(event: WechatMiniprogram.CustomEvent) {
+      const that = this as any;
+      const value = (event as any)?.detail; // field-radio 直接传递选中值
+      that.setData({ ['model.sex']: value });
+    },
+    updateByCardno(cardno?: string) {
+      const that = this as any;
+      const normalized = (cardno || '').trim();
+      that.setData({ ['model.cardno']: normalized });
+      if (!normalized) {
+        // 清空身份证:同步清空年龄与性别
+        return that.setData({ ['model.age']: '', ['model.sex']: '', idCardValid: false });
+      }
+      // 仅支持18位身份证解析
+      if (/^\d{17}[\dXx]$/.test(normalized)) {
+        const { valid, message } = (this as any).validateIdCard18(normalized);
+        if (!valid) {
+          that.setData({ ['model.age']: '', ['model.sex']: '', idCardValid: false });
+          return getTickleContext.call(that).showWarnMessage(message || '身份证号不合法');
+        }
+        const year = parseInt(normalized.substring(6, 10));
+        const month = parseInt(normalized.substring(10, 12));
+        const day = parseInt(normalized.substring(12, 14));
+        const birth = new Date(year, month - 1, day);
+        const now = new Date();
+        let age = now.getFullYear() - birth.getFullYear();
+        const m = now.getMonth() - birth.getMonth();
+        if (m < 0 || (m === 0 && now.getDate() < birth.getDate())) age--;
+        const sexCode = parseInt(normalized.substring(16, 17));
+        // 字典通常 0=男 1=女 或 1=女? 需与现有校验一致:文件中 womenSpecialPeriod 用 sex==='1' 判断为女性
+        const sex = sexCode % 2 === 0 ? '1' : '0';
+        that.setData({ ['model.age']: age, ['model.sex']: sex, idCardValid: true });
+      } else {
+        // 未满18位时,实时清空由身份证推导的年龄/性别,保持可编辑
+        that.setData({ ['model.age']: '', ['model.sex']: '', idCardValid: false });
+      }
+    },
     async onSubmit(event: WechatMiniprogram.FormSubmit) {
     async onSubmit(event: WechatMiniprogram.FormSubmit) {
-      const submitBtn = this.selectComponent("#submitBtn");
-      this.setData({ dirty: true });
-      const data = { ...this.data.model, ...event.detail.value };
-      if (!data.patientId) data.patientId = wx.getStorageSync("patientId");
-      // 表单验证
-      if (!data.sex) {
+      const that = this as any;
+      const submitBtn = that.selectComponent("#submitBtn");
+      that.setData({ dirty: true });
+      const data = { ...(that.data.model || {}), ...event.detail.value } as any;
+      // 如填写了身份证,进行18位身份证合法性校验
+      if (data.cardno) {
+        const { valid, message } = (this as any).validateIdCard18((data.cardno || '').toString());
+        if (!valid) {
+          if (submitBtn) submitBtn.resetState();
+          return getTickleContext.call(that).showWarnMessage(message || '身份证号不合法');
+        }
+      }
+      // 必填:年龄、性别
+      if (!data.age) {
         if (submitBtn) submitBtn.resetState();
         if (submitBtn) submitBtn.resetState();
+        return getTickleContext.call(that).showWarnMessage("请填写年龄");
       }
       }
+      if (data.sex === undefined || data.sex === null || data.sex === '') {
+        if (submitBtn) submitBtn.resetState();
+        return getTickleContext.call(that).showWarnMessage("请选择性别");
+      }
+      if (!data.patientId) data.patientId = wx.getStorageSync("patientId");
+      // 表单验证
       if (data.sex.toString() === "1" && !data.womenSpecialPeriod) {
       if (data.sex.toString() === "1" && !data.womenSpecialPeriod) {
         if (submitBtn) submitBtn.resetState();
         if (submitBtn) submitBtn.resetState();
         return getTickleContext
         return getTickleContext
-          .call(this)
+          .call(that)
           .showWarnMessage("请至少选择一项女性特殊期");
           .showWarnMessage("请至少选择一项女性特殊期");
       }
       }
       if (!data.height) {
       if (!data.height) {
         if (submitBtn) submitBtn.resetState();
         if (submitBtn) submitBtn.resetState();
-        return getTickleContext.call(this).showWarnMessage("请填写身高");
+        return getTickleContext.call(that).showWarnMessage("请填写身高");
       }
       }
       if (!data.weight) {
       if (!data.weight) {
         if (submitBtn) submitBtn.resetState();
         if (submitBtn) submitBtn.resetState();
-        return getTickleContext.call(this).showWarnMessage("请填写体重");
+        return getTickleContext.call(that).showWarnMessage("请填写体重");
       }
       }
       try {
       try {
         await updateUserInfoMethod(<any>data)
         await updateUserInfoMethod(<any>data)
           .then(() => wx.navigateBack())
           .then(() => wx.navigateBack())
           .then(() => {
           .then(() => {
-            this.getOpenerEventChannel().emit("update2", event.detail.value);
+            that.getOpenerEventChannel().emit("update2", event.detail.value);
           })
           })
           .catch((error) => {
           .catch((error) => {
-            // 请求失败时恢复按钮状态
             if (submitBtn) {
             if (submitBtn) {
               submitBtn.resetState();
               submitBtn.resetState();
             }
             }
-            getTickleContext.call(this).showWarnMessage(error.errMsg);
+            const msg = (error as any)?.errMsg || '更新失败';
+            getTickleContext.call(that).showWarnMessage(msg);
           });
           });
       } catch (error) {
       } catch (error) {
         if (submitBtn) submitBtn.resetState();
         if (submitBtn) submitBtn.resetState();
-        getTickleContext.call(this).showWarnMessage(error.errMsg);
+        const msg = (error as any)?.errMsg || '更新失败';
+        getTickleContext.call(that).showWarnMessage(msg);
       }
       }
     },
     },
   },
   },

+ 20 - 5
miniprogram/module/user/pages/user-edit/user-edit.wxml

@@ -2,12 +2,27 @@
 <wxs src="../../../../core/wxs/dictionary.wxs" module="dictionary" />
 <wxs src="../../../../core/wxs/dictionary.wxs" module="dictionary" />
 <t-navbar title="完善信息" left-arrow />
 <t-navbar title="完善信息" left-arrow />
 <scroll-view class="page-scroll__container" type="list" scroll-y style="{{containerStyle}}">
 <scroll-view class="page-scroll__container" type="list" scroll-y style="{{containerStyle}}">
-  <form bindsubmit="onSubmit">
+  <form bindsubmit="onSubmit" bindinput="onFormInput">
     <!-- <t-cell t-class="cell-border-gradient" title="手机号" note="{{model['phone']}}" /> -->
     <!-- <t-cell t-class="cell-border-gradient" title="手机号" note="{{model['phone']}}" /> -->
-    <t-cell title="姓名" note="{{model['name']}}"  />
-    <t-cell title="身份证号" note="{{model['cardno']}}" />
-    <t-cell title="年龄" note="{{model['age']}}岁" />
-    <t-cell title="性别" note="{{dictionary.label($dictionaries, 'sys_user_sex', model['sex'])}}" />
+    <t-cell title="姓名">
+      <input class="cell-field__inner" slot="note" name="name" value="{{model['name']}}" type="text" placeholder="请输入姓名" confirm-type="next" />
+    </t-cell>
+    <t-cell title="身份证号">
+      <input class="cell-field__inner" slot="note" name="cardno" value="{{model['cardno']}}" type="idcard" placeholder="请输入身份证号" confirm-type="next" data-field="cardno" bindinput="onFormInput" />
+    </t-cell>
+    <block wx:if="{{!idCardValid}}">
+      <t-cell title="年龄" required>
+        <input class="cell-field__inner" slot="note" name="age" value="{{model['age']}}" type="number" placeholder="请输入年龄" confirm-type="next" data-field="age" bindinput="onFormInput" style="padding-right:12%" />
+        <view class="cell-field__suffix" slot="note">岁</view>
+      </t-cell>
+      <t-cell title="性别" required>
+        <field-radio slot="note" name="sex" value="{{model['sex']}}" options="{{dictionary.options($dictionaries, 'sys_user_sex')}}" catch:change="onSexChange" />
+      </t-cell>
+    </block>
+    <block wx:else>
+      <t-cell title="年龄" note="{{model['age']}}岁" required />
+      <t-cell title="性别" note="{{dictionary.label($dictionaries, 'sys_user_sex', model['sex'])}}" required />
+    </block>
     <user-data-edit model="{{model}}" dirty="{{dirty}}"></user-data-edit>
     <user-data-edit model="{{model}}" dirty="{{dirty}}"></user-data-edit>
 
 
     <form-button block index="1" id="submitBtn"></form-button>
     <form-button block index="1" id="submitBtn"></form-button>

+ 5 - 2
miniprogram/pages/home/home.scss

@@ -231,7 +231,7 @@ $scale: 0.5;
     &-description {
     &-description {
       flex: auto;
       flex: auto;
       margin-left: 4px;
       margin-left: 4px;
-      font-size: 8px;
+      font-size: 24rpx;
     }
     }
   }
   }
 }
 }
@@ -426,7 +426,10 @@ $scale: 0.5;
   padding-bottom: calc(100rpx + env(safe-area-inset-bottom));
   padding-bottom: calc(100rpx + env(safe-area-inset-bottom));
   box-sizing: border-box;
   box-sizing: border-box;
 }
 }
-
+.user-pageBox{
+  display: flex;
+  align-items: center;
+}
 .care-container {
 .care-container {
   margin-top: 10px;
   margin-top: 10px;
   border-radius: 12rpx;
   border-radius: 12rpx;

+ 1 - 1
miniprogram/pages/home/home.wxml

@@ -29,7 +29,7 @@
             <text class="user-name">{{patient.name}}</text>
             <text class="user-name">{{patient.name}}</text>
             <t-icon color="{{patientIconColor}}" name="{{patientIcon}}" size="20px"></t-icon>
             <t-icon color="{{patientIconColor}}" name="{{patientIcon}}" size="20px"></t-icon>
           </view>
           </view>
-          <view>
+          <view class="user-pageBox">
             <text class="user-age" wx:if="{{patient.age}}">{{patient.age}}岁</text>
             <text class="user-age" wx:if="{{patient.age}}">{{patient.age}}岁</text>
             <text class="user-description" overflow="fade" max-lines="1">{{patientDescription}}</text>
             <text class="user-description" overflow="fade" max-lines="1">{{patientDescription}}</text>
           </view>
           </view>