Procházet zdrojové kódy

task-237 健康分析 / 舌面象分析报告添加扫码注册

cc12458 před 5 měsíci
rodič
revize
2981853e1c

+ 1 - 0
miniprogram/app.json

@@ -100,6 +100,7 @@
   "usingComponents": {
     "t-navbar": "tdesign-miniprogram/navbar/navbar",
     "t-message": "tdesign-miniprogram/message/message",
+    "popup-user-auth": "./components/popup-user-auth/popup-user-auth",
     "popup-privacy": "./components/popup-privacy/popup-privacy"
   },
   "requiredPrivateInfos": ["getFuzzyLocation", "chooseAddress"],

+ 1 - 0
miniprogram/components/popup-privacy/popup-privacy.ts

@@ -43,6 +43,7 @@ Component({
   properties: {
     pre: { type: Boolean, value: false },
     show: { type: Boolean, value: false },
+    overlay: { type: Boolean, value: true },
   },
   data: {
     visible: false,

+ 1 - 1
miniprogram/components/popup-privacy/popup-privacy.wxml

@@ -1,5 +1,5 @@
 <!--components/popup-privacy/popup-privacy.wxml-->
-<t-popup placement="bottom" show-overlay="{{true}}" visible="{{visible}}">
+<t-popup placement="bottom" show-overlay="{{overlay}}" visible="{{visible}}">
   <view class="popup">
     <view class="popup__header">{{title}}</view>
     <view class="popup__content">

+ 10 - 0
miniprogram/components/popup-user-auth/popup-user-auth.json

@@ -0,0 +1,10 @@
+{
+  "component": true,
+  "usingComponents": {
+    "t-cell": "tdesign-miniprogram/cell/cell",
+    "t-loading": "tdesign-miniprogram/loading/loading",
+    "t-radio": "tdesign-miniprogram/radio/radio",
+    "t-popup": "tdesign-miniprogram/popup/popup",
+    "form-button": "../button/button"
+  }
+}

+ 86 - 0
miniprogram/components/popup-user-auth/popup-user-auth.scss

@@ -0,0 +1,86 @@
+/* components/popup-user-auth/popup-user-auth.wxss */
+@import "../../themes/t.scss";
+@import "../../themes/t.cell.scss";
+@import "../../themes/button.scss";
+
+.popup {
+  &__header {
+    padding: 12px;
+    font-size: 18px;
+    text-align: center;
+  }
+
+  &__content {
+    padding: 0 12px;
+  }
+}
+
+.user-auth-form {
+  .open-button {
+    position: relative;
+    font-size: 14px;
+
+    &__inner {
+      position: absolute;
+      top: 0;
+      bottom: 0;
+      left: var(--td-cell-horizontal-padding, 32rpx);
+      right: var(--td-cell-horizontal-padding, 32rpx);
+      opacity: 0;
+    }
+  }
+
+  .cell-field {
+    .t-cell__title {
+      flex: none;
+    }
+  }
+
+  .field-container {
+    display: flex;
+    align-items: center;
+    font-size: var(--td-cell-title-font-size,var(--td-font-size-m,32rpx));
+
+    text {
+      flex: none;
+      color: #666;
+    }
+
+    input {
+      min-width: calc(var(--td-cell-title-font-size,var(--td-font-size-m,32rpx)) * 6 * 0.6);
+      text-align: center;
+    }
+  }
+
+  .privacy-contract-wrapper {
+    --td-radio-icon-checked-color: #1D6FF6;
+    --td-radio-font-size: 12px;
+    --td-radio-icon-size: 20px;
+
+    .privacy-contract {
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+    }
+
+    padding: 6px var(--td-cell-horizontal-padding, 32rpx);
+    font-size: 12px;
+
+    .name {
+      // color: var(--primary-color, #38FF6E);
+      color: #1D6FF6;
+    }
+
+    .no-border {
+      display: none;
+    }
+  }
+}
+
+.phone-cell {
+  color: black !important; // 使用 !important 确保优先级
+
+  .note-class {
+    color: black !important; // 确保 note 字体为黑色
+  }
+}

+ 123 - 0
miniprogram/components/popup-user-auth/popup-user-auth.ts

@@ -0,0 +1,123 @@
+// components/popup-user-auth/popup-user-auth.ts
+import { openPrivacyContract } from "../../lib/wx/open-api";
+import { login } from "../../lib/logic";
+import { usePhoneNumber } from "../../lib/use/use-phone";
+import { getSceneRegisterMethod, setSceneRegisterMethod } from "../../lib/request/common";
+let submitting = false;
+Component({
+  properties: {
+    visible: { type: Boolean, value: false },
+    overlay: { type: Boolean, value: true },
+    scene: { type: String, value: '' },
+    cardno: { type: String, value: '' },
+    phone: { type: String, value: '' },
+  },
+  data: {
+    title: '完善信息',
+    privacyContract: { agree: false, name: "《隐私政策》", show: false },
+
+    loading: false,
+    submitting: false,
+
+    cardnoProps: { prefix: '', suffix: '', fill: '', length: 0 },
+    phoneProps: { prefix: '', suffix: '', fill: '', length: 0 },
+  },
+  observers: {
+    cardno(value: string) {
+      if (!value) return;
+      const length = 18;
+      const tag = '*';
+      if (!value.includes(tag)) value = value.padEnd(length, tag);
+      const [_, prefix = '', fill = '', suffix = ''] = value.match(/(\d+)?(\*+)?(\d+)?/) || [];
+      this.setData({ cardnoProps: { prefix, suffix, fill: '', length: fill.length === length ? 0 : fill.length } });
+      if (this.data.cardnoProps.length) this.setData({ visible: true });
+    },
+    phone(value: string) {
+      if (!value) return;
+      const length = 11;
+      const tag = '*';
+      if (!value.includes(tag)) value = value.padEnd(length, tag);
+      const [_, prefix = '', fill = '', suffix = ''] = value.match(/(\d+)?(\*+)?(\d+)?/) || [];
+      this.setData({ phoneProps: { prefix, suffix, fill: '', length: fill.length === length ? 0 : fill.length } });
+      if (this.data.phoneProps.length) this.setData({ visible: true });
+    },
+    scene(value: string) { this.init(value); }
+  },
+  methods: {
+    async init(scene: string) {
+      if (!scene) return;
+      await login();
+      const data = await getSceneRegisterMethod(scene);
+      this.setData({ ...data });
+      this.triggerEvent('loaded', { visible: this.data.visible, scene });
+      if (data.patientId) this.register(data.patientId);
+    },
+    getPhoneNumberHandle(event: WechatMiniprogram.ButtonGetPhoneNumber) {
+      this.setData({ loading: true });
+      const { getPhoneNumber } = usePhoneNumber();
+      getPhoneNumber(event, (value) => {
+        this.setData({ "phoneProps.fill": value, loading: false })
+      })
+    },
+    openPrivacyContract: openPrivacyContract,
+    onPrivacySetting({ detail }: { detail: WechatMiniprogram.GetPrivacySettingSuccessCallbackResult; }) {
+      this.setData({
+        "privacyContract.name": detail.privacyContractName,
+        // 'privacyContract.agree': !detail.needAuthorization,
+      });
+    },
+    onAgreeChange(event: any) {
+      const agree = event?.detail?.checked;
+      if (agree) this.setData({ "privacyContract.show": true });
+      else this.setData({ "privacyContract.agree": agree });
+    },
+    onAgree() {
+      this.setData({ "privacyContract.agree": true });
+    },
+    onDisagree() {
+      this.setData({ "privacyContract.agree": false });
+    },
+    register(patientId: string) {
+      if (!patientId) return;
+      wx.setStorageSync("patientId", patientId);
+      this.setData({ 'visible': false });
+      this.triggerEvent('register', { patientId });
+    },
+    async onSubmit(event: WechatMiniprogram.FormSubmit) {
+      if (this.data.submitting || submitting) return;
+      submitting = true;
+      try {
+        const data = { agemust: this.data.privacyContract.agree ? 'Y' : 'N', phone: '' } as any;
+        if (data.agemust === "N") {
+          this.setData({ "privacyContract.show": true });
+          throw `请阅读并同意${this.data.privacyContract.name}`;
+        }
+
+        const phone = this.data.phoneProps;
+        if (phone.length && phone.fill.length !== phone.length) throw `手机号码请补充完整`;
+        else if (!phone.fill) throw `请获取手机号码`;
+        else data.phone = `${phone.prefix}${phone.fill}${phone.suffix}`;
+
+        const cardno = this.data.cardnoProps;
+        if (cardno.length && cardno.fill.length !== cardno.length) throw `身份证号请补充完整`;
+        else if (cardno.length) data.cardno = `${phone.prefix}${phone.fill}${phone.suffix}`;
+
+        if (this.data.scene) data.scene = decodeURIComponent(this.data.scene);
+
+        this.setData({ "submitting": submitting });
+        const { patientId } = await setSceneRegisterMethod(data);
+        this.register(patientId);
+      } catch (error) {
+        if (typeof error === 'string') this.triggerEvent('message', { type: 'warning', content: error });
+        else if (error.errMsg) {
+          this.triggerEvent('message', { type: 'error', content: error.errMsg });
+          if (!this.data.phoneProps.length) this.setData({ "phoneProps.fill": '', loading: false });
+        }
+      }
+      setTimeout(() => {
+        submitting = false;
+        this.setData({ "submitting": submitting });
+      }, 100);
+    },
+  }
+})

+ 41 - 0
miniprogram/components/popup-user-auth/popup-user-auth.wxml

@@ -0,0 +1,41 @@
+<!--components/popup-user-auth/popup-user-auth.wxml-->
+<t-popup placement="bottom" show-overlay="{{overlay}}" visible="{{visible}}">
+  <view class="popup">
+    <view class="popup__header">{{title}}</view>
+    <view class="popup__content">
+      <form class="user-auth-form" bindsubmit="onSubmit">
+        <view wx:if="{{!phoneProps.length}}" class="open-button">
+          <t-cell t-class="cell-border-gradient phone-cell" t-class-note="note-class" required title="手机号" hover="{{!phoneProps.fill}}" note="{{loading ? '' : phoneProps.fill || '点击获取手机号码'}}">
+            <t-loading wx:if="{{loading}}" theme="spinner" size="24rpx" slot="note" />
+          </t-cell>
+          <button wx:if="{{!loading && !phoneProps.fill}}" class="open-button__inner" size="mini" open-type="getPhoneNumber" bind:getphonenumber="getPhoneNumberHandle">选择授权手机</button>
+        </view>
+        <label wx:else>
+          <t-cell t-class="cell-border-gradient cell-field" t-class-note="cell-field__wrapper" required title="手机号">
+            <view class="field-container" slot="note">
+              <text wx:if="{{phoneProps.prefix}}">{{ phoneProps.prefix }}</text>
+              <input name="phone" type="number" model:value="{{phoneProps.fill}}" maxlength="{{phoneProps.length}}" placeholder="请补充" placeholder-style="color:#F76260" confirm-type="next" />
+              <text wx:if="{{phoneProps.suffix}}">{{ phoneProps.suffix }}</text>
+            </view>
+          </t-cell>
+        </label>
+        <label wx:if="{{cardnoProps.length}}">
+          <t-cell t-class="cell-border-gradient cell-field" t-class-note="cell-field__wrapper" required title="身份证号">
+            <view class="field-container" slot="note">
+              <text wx:if="{{cardnoProps.prefix}}">{{ cardnoProps.prefix }}</text>
+              <input name="cardno" type="idcard" model:value="{{cardnoProps.fill}}" maxlength="{{cardnoProps.length}}" placeholder="请补充" placeholder-style="color:#F76260" confirm-type="next" />
+              <text wx:if="{{cardnoProps.suffix}}">{{ cardnoProps.suffix }}</text>
+            </view>
+          </t-cell>
+        </label>
+        <view class="privacy-contract-wrapper">
+          <t-radio t-class="privacy-contract" t-class-border="no-border" icon="circle" block="{{false}}" checked="{{privacyContract.agree}}" bind:change="onAgreeChange">
+            <text slot="content" style="font-size: 14px;">我已阅读与同意 <text class="name" catch:tap="openPrivacyContract">{{privacyContract.name}}</text></text>
+          </t-radio>
+        </view>
+        <form-button block index="1" loading="{{submitting}}" disableOnClick="{{false}}">提交</form-button>
+      </form>
+    </view>
+  </view>
+</t-popup>
+<popup-privacy show="{{privacyContract.show}}" overlay="{{false}}" bind:setting="onPrivacySetting" bind:agree="onAgree" bind:disagree="onDisagree" />

+ 19 - 0
miniprogram/lib/request/common.ts

@@ -0,0 +1,19 @@
+import { Get } from "./method";
+
+// 获取扫码注册参数
+export function getSceneRegisterMethod(scene: string) {
+  const params = { scene: decodeURIComponent(scene) };
+  const transform = ({ data }: AnyObject) => {
+    const { cardno, phone, patientId } = data;
+    return { cardno, phone, patientId, visible: !patientId }
+  }
+  return Get(`/patientInfoManage/getCardnoPhoneMantissaByScene`, { params, transform }).catch(() => ({ visible: false }));
+}
+
+// 扫码注册
+export function setSceneRegisterMethod(params: { scene: string; phone: string; cardno?: string }) {
+  const transform = ({ data }: AnyObject) => {
+    return { patientId: data }
+  }
+  return Get(`/patientInfoManage/scanAuth`, { params, transform })
+}

+ 10 - 11
miniprogram/module/health/pages/analysis/analysis.ts

@@ -20,19 +20,14 @@ Page({
     switchType: "",
   },
   onLoad(query: any) {
-    this._load(query);
     if (query.scene) {
-      this.setData({
-        switchType: query.scene,
-      });
-    }
-    console.log(this.data.switchType,"query1111",query)
+      this.setData({ switchType: query.scene });
+      wx.showLoading({ title: "加载中" });
+    } else this._load(query);
   },
-
-  async _load(query: Record<'id' | 'scene', string>) {
-    console.log(query,"111");
-    
-    wx.showLoading({ title: '加载中' });
+  load(event: AnyObject) { this._load(event.detail, false); },
+  async _load(query: Record<'id' | 'scene', string>, loading = true) {
+    if (loading) wx.showLoading({ title: '加载中' });
     try {
       const { tongue, face, ...dataset } = await healthAnalysisMethod(query);
       this.setData({ tongue, face, dataset });
@@ -43,4 +38,8 @@ Page({
   },
 
   toHomePage() { toHomePage(this.data.switchType as string); },
+  openMessage(event: any) {
+    const message = event?.detail?.content;
+    if (message) getTickleContext.call(this).showMessage(event.detail.type || 'info', message);
+  }
 });

+ 2 - 1
miniprogram/module/health/pages/analysis/analysis.wxml

@@ -12,4 +12,5 @@
   <card-analysis-content tongue="{{tongue}}" face="{{face}}" exception></card-analysis-content>
 </scroll-view>
 </view>
-<t-message id="{{$messageId}}"></t-message>
+<t-message id="{{$messageId}}"></t-message>
+<popup-user-auth scene="{{switchType}}" bind:loaded="load" bind:message="openMessage"></popup-user-auth>

+ 11 - 11
miniprogram/module/health/pages/report/report.ts

@@ -20,19 +20,15 @@ Page({
     switchType: "",
   },
   onLoad(query: any) {
-    this._load(query).then((id: string) => {
-      if (id) this.getHealthIndex(id);
-    });
     if (query.scene) {
-      this.setData({
-        switchType: query.scene,
-      });
-    }
+      this.setData({ switchType: query.scene });
+      wx.showLoading({ title: "加载中" });
+    } else this._load(query);
   },
-
-  async _load(query: Record<"id" | "scene", string>) {
+  load(event: AnyObject) { this._load(event.detail, false); },
+  async _load(query: Record<"id" | "scene", string>, loading = true) {
     let id = "";
-    wx.showLoading({ title: "加载中" });
+    if (loading) wx.showLoading({ title: "加载中" });
     try {
       const { __origin__, ...dataset } = await healthReportMethod(query);
       id = dataset.id;
@@ -53,7 +49,7 @@ Page({
     }
     wx.hideLoading();
 
-    return id;
+    if (id) this.getHealthIndex(id);
   },
 
   async getHealthIndex(id?: string) {
@@ -78,4 +74,8 @@ Page({
   toSchemePage() {
     toSchemePage(this.data.schemeId);
   },
+  openMessage(event: any) {
+    const message = event?.detail?.content;
+    if (message) getTickleContext.call(this).showMessage(event.detail.type || 'info', message);
+  }
 });

+ 2 - 1
miniprogram/module/health/pages/report/report.wxml

@@ -92,4 +92,5 @@
     </report-health-index>
   </scroll-view>
 </view>
-<t-message id="{{$messageId}}"></t-message>
+<t-message id="{{$messageId}}"></t-message>
+<popup-user-auth scene="{{switchType}}" bind:loaded="load" bind:message="openMessage"></popup-user-auth>

+ 2 - 2
miniprogram/pages/home/home.ts

@@ -400,9 +400,9 @@ Page({
       const { patient } = await getPatients(/*this.data.patientId*/);
       // if (!patient) await toCertificationPage();
       if (!patient) {
-        if (wx.getStorageSync("doctorId")) {
+        /*if (wx.getStorageSync("doctorId")) {
           toCertificationPage();
-        }
+        }*/
         this.setData({
           "healthReport.loading": false,
           isShowComplete: true,

+ 6 - 1
miniprogram/pages/home/request.ts

@@ -39,7 +39,12 @@ export function getPatients(id?: string) {
 
     return { patient, patients: data };
   };
-  return Post("/mobileAccountManage/getPatsByAid", {}, { transform });
+  return Post("/mobileAccountManage/getPatsByAid", {}, { transform }).then(res => {
+    const patientId = res.patient?.patientId;
+    if (patientId) wx.setStorageSync("patientId", patientId);
+    else wx.removeStorageSync("patientId");
+    return res;
+  });
 }
 
 export async function getPatientDescription(patient: {