Преглед изворни кода

健康档案页:重构健康状况、健康分析报告模块,添加舌面分析报告模块

kumu пре 1 година
родитељ
комит
1eeb49ea5d

+ 2 - 1
miniprogram/module/health/components/report-health-status/report-health-status.json

@@ -7,6 +7,7 @@
     "t-icon": "tdesign-miniprogram/icon/icon",
     "t-loading": "tdesign-miniprogram/loading/loading",
     "t-empty": "tdesign-miniprogram/empty/empty",
-    "card-report": "../../components/card-report/card-report"
+    "card-report": "../../components/card-report/card-report",
+    "report-health-scheme": "../../components/report-health-scheme/report-health-scheme"
   }
 }

+ 1 - 1
miniprogram/module/health/components/report-health-status/report-health-status.scss

@@ -1,10 +1,10 @@
 @import "../../../../themes/t.cell.scss";
 @import "../../report-common.scss";
 @import "../../../../themes/card.scss";
+@import '../../../../themes/draggable-sheet.scss';
 
 /* module/health/components/report-health-status/report-health-status.wxss */
 
-
 .status-data-wrapper {
   font-size: 12px;
 }

+ 127 - 32
miniprogram/module/health/components/report-health-status/report-health-status.ts

@@ -1,46 +1,141 @@
+import PageContainerBehavior from "../../../../core/behavior/page-container.behavior";
+import { DraggableSheetBehavior, getDraggableSheetContext } from "../../../../core/behavior/draggableSheet.behavior"
+import { getTickleContext } from "../../../../core/behavior/tickle.behavior";
+
 // module/health/components/report-health-status/report-health-status.ts
-function getDraggableSheetContext(this: any) {
-  return this as { scroll: WechatMiniprogram.DraggableSheetContext }
+import { healthAnalysisListMethod, healthAnalysisMethod, healthReportListMethod, healthReportMethod } from "../../request";
+import { healthAnalysisModel, healthRecord } from "../../model/health.model";
+
+interface PanelProps {
+  shade?: boolean;
+  title?: string;
+  data: AnyArray;
+  type?: 'analysis' | 'report';
 }
-const { windowHeight } = wx.getSystemInfoSync()
-const menuRect = wx.getMenuButtonBoundingClientRect()
-const menuBottom = menuRect.bottom + 1
+
 Component({
-  options: {
-    multipleSlots: true,
+  behaviors: [
+    PageContainerBehavior,
+    DraggableSheetBehavior('.health-report-list'),
+  ],
+  lifetimes: {
+    attached() {
+      this._load();
+    }
   },
-  properties: {
-    dataset: { type: Object },
-    loading: { type: Boolean, value: false },
-    message: { type: String, value: '' },
+  pageLifetimes: {
+    hide() { this._hideDraggableSheet({}); }
   },
   data: {
-    sheetHeight: windowHeight - menuBottom,
-    initialSize: 0,
-    minSize: 0,
-    maxSize: 1,
-  },
-  lifetimes: {
-    created() {
-      this.createSelectorQuery().select('.draggable-sheet-wrapper').node().exec(res => {
-        getDraggableSheetContext.call(this).scroll = res[0].node;
-      })
-    }
+    dataset: {},
+    loading: false,
+    message: '',
+    panel: {
+      shade: false,
+      data: [],
+    } as PanelProps,
+    _healthReportList: { data: [], loaded: false },
+    _healthAnalysisList: { data: [], loaded: false },
   },
   methods: {
-    showList() {
-      console.log('showList', this);
-      
-      getDraggableSheetContext.call(this).scroll.scrollTo({
-        size: 0.5,
-        pixels: 600,
+    async showReportList() {
+      if (!this.data._healthReportList.loaded) {
+        wx.showLoading({ title: '加载中' })
+        try {
+          const data = await healthReportListMethod();
+          this.setData({
+            '_healthReportList.data': data,
+            '_healthReportList.loaded': true,
+          });
+        } catch (error) {
+          getTickleContext.call(this).showErrorMessage(error.errMsg);
+        }
+        wx.hideLoading();
+      }
+      this._showDraggableSheet({
+        title: '健康分析报告记录', type: 'report',
+        data: this.data._healthReportList.data
+      });
+    },
+    async showAnalysisList() {
+      if (!this.data._healthAnalysisList.loaded) {
+        wx.showLoading({ title: '加载中' })
+        try {
+          const data = await healthAnalysisListMethod();
+          this.setData({
+            '_healthAnalysisList.data': data,
+            '_healthAnalysisList.loaded': true,
+          });
+        } catch (error) {
+          getTickleContext.call(this).showErrorMessage(error.errMsg);
+        }
+        wx.hideLoading();
+      }
+      this._showDraggableSheet({
+        title: '舌面分析报告记录', type: 'analysis',
+        data: this.data._healthAnalysisList.data,
+      });
+    },
+    showStatusList() {
+      wx.navigateTo({ url: `/module/health/pages/status-record/status-record` });
+    },
+    toPreviewPage(event: WechatMiniprogram.TouchEvent) {
+      const { id, type } = event.mark ?? {};
+      if (!id) return;
+      const route = `module/health/pages/${type}/${type}`;
+      wx.navigateTo({ url: `/${route}?id=${id}` });
+    },
+
+    async _load() {
+      this.setData({ loading: true });
+      const params = { id: void 0, scene: void 0 };
+      try {
+        const report = await healthReportMethod(params);
+        const { id: analysisId, ...analysis } = await healthAnalysisMethod(params).catch(() => healthAnalysisModel({}));
+        const data = healthRecord({ ...report, ...analysis, analysisId });
+        this.setData({
+          dataset: data,
+          loading: false,
+        });
+      } catch (error) {
+        this.setData({
+          dataset: null,
+          loading: false,
+          message: error.errMsg,
+        });
+      }
+    },
+
+    _showDraggableSheet(props: PanelProps) {
+      if (props.data?.length) {
+        getDraggableSheetContext.call(this).scrollTo({
+          size: 0.5,
+          pixels: 600,
+          animated: true,
+          duration: 300,
+          easingFunction: 'ease'
+        });
+        this.setData({ panel: { ...props, shade: true } });
+      } else {
+        wx.showToast({ title: '暂无更新记录' })
+      }
+
+    },
+    _hideDraggableSheet(e?: any) {
+      this.setData({ 'panel.shade': false });
+      if (!e) return;
+      getDraggableSheetContext.call(this).scrollTo({
+        size: 0,
         animated: true,
         duration: 300,
         easingFunction: 'ease'
-      })
+      });
+    },
+    _draggableSizeUpdate(e: any) {
+      'worklet'
+      if (e.pixels < 1) {
+        wx.worklet.runOnJS(this._hideDraggableSheet.bind(this))()
+      }
     },
-    toInfoPage() {
-      this.triggerEvent('info')
-    }
   }
 })

+ 76 - 33
miniprogram/module/health/components/report-health-status/report-health-status.wxml

@@ -7,23 +7,55 @@
       <image wx:else class="icon" src="../../assets/icon/health-status-1.icon.png" mode="heightFix"></image>
     </block>
     <block slot="right-icon">
-      <slot name="extra-status"></slot>
+      <view class="extra-warapper" slot="extra-status" catch:tap="showStatusList">
+        <text>更新记录</text>
+        <t-icon t-class="icon" name="chevron-right-double-s" size="24px" />
+      </view>
     </block>
 
-    <view slot="description" wx:if="{{!loading && !dataset}}">暂无数据</view>
+    <view slot="description" wx:if="{{!loading && !dataset.condition.length}}">暂无数据</view>
   </t-cell>
 
-  <view class="card-body status-data-wrapper">
-    <span class="row">
-      <text>症状信息:</text>
-      <text>{{dataset.pickedSymptom}}</text>
+  <view class="card-body status-data-wrapper" wx:if="{{dataset.condition.length}}">
+    <span class="row" wx:for="{{dataset.condition}}" wx:key="value">
+      <text wx:if="{{item.label}}">{{item.label}}:</text>
+      <text>{{item.value}}</text>
     </span>
   </view>
 
   <t-empty wx:if="{{message}}" t-class="empty-wrapper error" icon="info-circle" description="{{message}}" />
 </view>
 
-<view class="card-wrapper report-data-wrapper" catch:tap="toInfoPage">
+<view wx:if="{{dataset.analysisId}}" class="card-wrapper report-data-wrapper" mark:type="analysis" bind:tap="toPreviewPage">
+  <t-cell t-class="card-header cell-border-gradient" t-class-title="card-header__title">
+    <block slot="title">
+      <text>舌面分析报告</text>
+      <t-loading wx:if="{{loading}}" theme="spinner" size="20px" class="loading" />
+      <image wx:else class="icon" src="../../assets/icon/health-status-2.icon.png" mode="heightFix"></image>
+    </block>
+    <block slot="right-icon">
+      <view class="extra-warapper" catch:tap="showAnalysisList">
+        <text>更新记录</text>
+        <t-icon t-class="icon" name="chevron-right-double-s" size="24px" />
+      </view>
+    </block>
+
+    <view slot="description" wx:if="{{!loading && !dataset.analysis.length}}">暂无数据</view>
+  </t-cell>
+  <view class="card-body report-wrapper" mark:id="{{dataset.analysisId}}" wx:for="{{dataset.analysis}}" wx:key="value">
+    <view class="content-wrapper">
+      <span class="row">
+        <text wx:if="{{item.label}}">{{item.label}}:</text>
+        <text>{{item.value}}</text>
+      </span>
+    </view>
+    <image wx:if="{{item.cover[0]}}" class="image-wrapper" src="{{item.cover[0]}}" mode="aspectFill" />
+  </view>
+
+  <t-empty wx:if="{{message}}" t-class="empty-wrapper error" icon="info-circle" description="{{message}}" />
+</view>
+
+<view class="card-wrapper report-data-wrapper" mark:type="report" bind:tap="toPreviewPage">
   <t-cell t-class="card-header cell-border-gradient" t-class-title="card-header__title">
     <block slot="title">
       <text>健康分析报告</text>
@@ -31,38 +63,49 @@
       <image wx:else class="icon" src="../../assets/icon/health-status-2.icon.png" mode="heightFix"></image>
     </block>
     <block slot="right-icon">
-      <slot name="extra-report"></slot>
+      <view class="extra-warapper" catch:tap="showReportList">
+        <text>更新记录</text>
+        <t-icon t-class="icon" name="chevron-right-double-s" size="24px" />
+      </view>
     </block>
 
-    <view slot="description" wx:if="{{!loading && !dataset}}">暂无数据</view>
+    <view slot="description" wx:if="{{!loading && !dataset.report.length}}">暂无数据</view>
   </t-cell>
-  <view class="card-body report-wrapper">
+  <view class="card-body report-wrapper" mark:id="{{dataset.reportId}}">
     <view class="content-wrapper">
-      <block wx:if="dataset">
-        <span class="row">
-          <text>结果显示您是:</text>
-          <text>{{dataset.willillStateName}}</text>
-        </span>
-        <span class="row" wx:if="{{dataset.willillDegreeName}}">
-          <text>程度:</text>
-          <text>{{dataset.willillDegreeName}}</text>
-        </span>
-        <!-- <span class="row">
-            <text>类型:</text>
-            <text>{{dataset.willillSocialName}}</text>
-          </span> -->
-        <span class="row" wx:if="{{dataset.willillFunctionName}}">
-          <text>表现:</text>
-          <text>{{dataset.willillFunctionName}}</text>
-        </span>
-        <span class="row">
-          <text>体质:</text>
-          <text>{{dataset.constitutionGroupName}}</text>
-        </span>
-      </block>
+      <span class="row" wx:for="{{dataset.report}}" wx:key="value">
+        <text wx:if="{{item.label}}">{{item.label}}:</text>
+        <text>{{item.value}}</text>
+      </span>
     </view>
     <image class="image-wrapper" src="../../assets/image/health-report.png" mode="aspectFill" />
   </view>
 
   <t-empty wx:if="{{message}}" t-class="empty-wrapper error" icon="info-circle" description="{{message}}" />
-</view>
+</view>
+
+<report-health-scheme dataset="{{dataset.conditProgram}}" mark:type="scheme" mark:id="{{dataset.reportId}}" bind:tap="toPreviewPage"></report-health-scheme>
+
+<root-portal>
+  <view wx:if="{{panel.shade}}" class="draggable-sheet-shade" catch:tap="_hideDraggableSheet"></view>
+  <draggable-sheet class="draggable-sheet-wrapper health-report-list" style="height: {{container.height}}px;" initial-child-size="0" min-child-size="0" max-child-size="0.8" snap="{{true}}" snap-sizes="{{[0.5]}}" worklet:onsizeupdate="_draggableSizeUpdate" mark:type="{{panel.type}}" bind:tap="toPreviewPage">
+    <scroll-view class="scrollable draggable-sheet-container" type="custom" scroll-y associative-container="draggable-sheet" show-scrollbar="{{false}}" bounces="{{false}}">
+      <sticky-section>
+        <sticky-header>
+          <view class="draggable-sheet-bar">
+            <view class="indicator" />
+            <view wx:if="{{panel.title}}" class="title">{{panel.title}}</view>
+          </view>
+        </sticky-header>
+        <list-builder list="{{panel.data}}" child-height="90">
+          <block slot:item slot:index>
+            <t-cell t-class="cell-border-gradient" hover arrow title="{{item.reportTime}}" mark:id="{{item.id}}">
+              <image slot="image" src="../../assets/image/health-report.png" style="width: 53px;height: 53px;"></image>
+              <text slot="description" overflow="ellipsis">{{item.description}}</text>
+            </t-cell>
+          </block>
+        </list-builder>
+      </sticky-section>
+    </scroll-view>
+  </draggable-sheet>
+</root-portal>

+ 171 - 0
miniprogram/module/health/model/health.model.ts

@@ -0,0 +1,171 @@
+import { groupBy } from "../../../utils/util";
+
+export interface AnalysisModel {
+  table: {
+    columns: string[];
+    data: (string[] & { exception: boolean })[];
+  };
+  exception: AnalysisException[];
+  cover: string[];
+  result: string;
+}
+
+export interface AnalysisException {
+  key: string;
+  title: string;
+  cover?: string;
+  description?: string;
+  descriptions: { label: string; value: string }[];
+  tags: string[];
+}
+
+export function healthAnalysisModel(data: AnyObject) {
+  return {
+    id: data?.id ?? '',
+    reportTime: data?.reportTime,
+    tongue: tongueAnalysisModel(data),
+    face: faceAnalysisModel(data),
+  }
+}
+
+export function healthReportModel(data: AnyObject) {
+  return {
+    id: data?.healthAnalysisReportId ?? '',
+    reportId: data?.healthAnalysisReportId ?? '',
+    analysisId: data?.tonguefaceAnalysisReportId ?? '',
+    tongue: tongueAnalysisModel(data),
+    face: faceAnalysisModel(data),
+
+    __origin__: data,
+  }
+}
+
+/**
+ * 健康档案显示数据
+ * @param data
+ */
+export function healthRecord(data: ReturnType<typeof healthReportModel>) {
+  const fn = (label: string, value?: string, force = false) => value || force ? { label, value: value ?? '' } : void 0;
+
+  const conditProgram = data.__origin__.conditProgram;
+  if (Array.isArray(conditProgram?.types)) {
+    conditProgram.types = conditProgram.types.map((item: AnyObject) => ({ type: item.type }))
+  }
+
+  return {
+    reportId: data?.reportId,
+    analysisId: data?.analysisId,
+    condition: [fn('症状信息', data?.__origin__?.pickedSymptom)].filter(Boolean),
+    report: [
+      fn('结果显示您是', data?.__origin__?.willillStateName, true),
+      fn('程度', data?.__origin__?.willillDegreeName),
+      // fn('类型', data?.__origin__?.willillSocialName),
+      fn('表现', data?.__origin__?.willillFunctionName),
+      fn('体质', data?.__origin__?.constitutionGroupName, true),
+    ].filter(Boolean),
+    analysis: [
+      data?.tongue?.result ? { value: data.tongue.result, cover: data.tongue.cover } : void 0,
+    ].filter(Boolean),
+    conditProgram,
+  }
+}
+
+
+export function getHealthAnalysisExceptionGroup(exception: AnalysisException[]): { key: string; exception: AnalysisException[] }[] {
+  const group = groupBy<AnalysisException>(exception, (item) => item.cover ?? '');
+  return Object.entries(group).map(([key, exception]) => ({ key, exception }));
+}
+
+function tongueAnalysisModel(data: AnyObject): AnalysisModel {
+  const exception: AnalysisException[] = [];
+  const tongueException = analysisException(exception);
+  const c1 = data?.upImg;
+  const c2 = data?.downImg;
+  return {
+    table: {
+      columns: ['舌象维度', '检测结果', '标准值'],
+      data: [
+        tongueException(data?.tongueColor, '舌色'),
+        tongueException(data?.tongueCoatingColor, '苔色'),
+        tongueException(data?.tongueShape, '舌形'),
+        tongueException(data?.tongueCoating, '苔质'),
+        tongueException(data?.bodyFluid, '津液'),
+        tongueException(data?.sublingualVein, '舌下'),
+      ],
+    },
+    exception,
+    result: data?.tongueAnalysisResult ?? '',
+    cover: Object.assign([c1, c2].filter(Boolean), {
+      ['舌上']: c1,
+      ['舌下']: c2,
+    }),
+  }
+}
+
+function faceAnalysisModel(data: AnyObject): AnalysisModel {
+  const exception: AnalysisException[] = [];
+  const faceException = analysisException(exception, (label, value) => `${label}${value}`);
+  const c1 = data?.faceImg ?? data?.faceImgUrl;
+  const c2 = data?.faceLeft ?? data?.faceLeftImgUrl;
+  const c3 = data?.faceRight ?? data?.faceRightImgUrl;
+  return {
+    table: {
+      columns: ['面象维度', '检测结果', '标准值'],
+      data: [
+        faceException(data?.faceColor, '面色'),
+        faceException(data?.mainColor, '主色'),
+        faceException(data?.shine, '光泽'),
+        faceException(data?.leftBlackEye, '左黑眼圈'),
+        faceException(data?.rightBlackEye, '右黑眼圈'),
+        faceException(data?.lipColor, '唇色'),
+        faceException(data?.eyeContact, '眼神'),
+        faceException(data?.leftEyeColor, '左目色'),
+        faceException(data?.rightEyeColor, '右目色'),
+        faceException(data?.hecticCheek, '两颧红'),
+        faceException(data?.noseFold, '鼻褶'),
+        faceException(data?.cyanGlabella, '眉间/鼻柱青色'),
+        faceException(data?.faceSkinDefects, '面部皮损'),
+      ],
+    },
+    exception,
+    result: data?.faceAnalysisResult ?? data?.face ?? '',
+    cover: Object.assign([c1, c2, c3].filter(Boolean), {
+      ['正面']: c1,
+      ['左面']: c2,
+      ['右面']: c3,
+    }),
+  };
+}
+
+function analysisException(exception: AnalysisException[], $title = (label: string, value: string) => value,) {
+  return (data: { actualList?: AnyObject[]; standardValue?: string }, label: string) => {
+    let is = false;
+    let invalid = false;
+    const values = data?.actualList?.map((item) => {
+      let title: string = item?.actualValue ?? '';
+      const suffix = item?.contrast ?? 's';
+      if (title.endsWith('不符合检测要求')) {
+        invalid = true;
+      } else if (suffix !== 's') {
+        if (suffix !== 'r') title += ` (${suffix || ''}) `;
+        is = true;
+        exception.push({
+          key: title,
+          title: $title(label, title),
+          cover: item.splitImage,
+          descriptions: [
+            item.features ? { label: '【特征】', value: item.features } : null,
+            item.clinicalSignificance ? { label: '【临床意义】', value: item.clinicalSignificance } : null,
+          ].filter(Boolean) as any,
+          tags: item.attrs ?? [],
+        });
+      }
+      return title;
+    }) ?? [];
+    return Object.assign({
+      0: label,
+      1: values.join('<br>'),
+      2: data?.standardValue ?? ''
+    }, { exception: is, invalid });
+  }
+}

+ 0 - 1
miniprogram/module/health/pages/home/home.json

@@ -8,7 +8,6 @@
     "report-health-index": "../../components/report-health-index/report-health-index",
     "report-health-status": "../../components/report-health-status/report-health-status",
     "report-health-patient": "../../components/report-health-patient/report-health-patient",
-    "report-health-scheme": "../../components/report-health-scheme/report-health-scheme",
     "card-report": "../../components/card-report/card-report"
   }
 }

+ 3 - 83
miniprogram/module/health/pages/home/home.ts

@@ -1,39 +1,25 @@
 import PageContainerBehavior from "../../../../core/behavior/page-container.behavior";
-import { DraggableSheetBehavior, getDraggableSheetContext } from "../../../../core/behavior/draggableSheet.behavior";
 
 // module/health/pages/home/home.ts
-import { toPatientPage, toReportPage, toSchemePage } from "../../router";
-import { healthIndexMethod, healthPatientMethod, healthReportListMethod, healthReportMethod } from "../../request";
+import { toPatientPage } from "../../router";
+import { healthIndexMethod, healthPatientMethod, } from "../../request";
 import { healthIndex2Progress } from "../../tools/health-index";
-import { getTickleContext } from "../../../../core/behavior/tickle.behavior";
 
 Component({
   behaviors: [
     PageContainerBehavior,
-    DraggableSheetBehavior('.health-report-list'),
   ],
   lifetimes: {
     attached() {
       this.getHealthPatient();
-      this.getHealthReport();
       this.getHealthIndex();
     }
   },
-  pageLifetimes: {
-    hide() { this.hideDraggableSheet({}); }
-  },
   properties: {},
-  observers: {
-    'healthReport.data'(data) {
-      this.setData({ healthId: data?.healthAnalysisReportId })
-    }
-  },
   data: {
-    healthId: '',
+    // healthId: '',
     healthPatient: { data: null, loading: false, message: '' },
     healthIndex: { data: [], loading: false, message: '' },
-    healthReport: { data: null, loading: false, message: '' },
-    healthReportList: { data: [], loaded: false },
   },
   methods: {
     async getHealthPatient() {
@@ -52,22 +38,6 @@ Component({
         });
       }
     },
-    async getHealthReport(id?: string) {
-      this.setData({ 'healthReport.loading': true, })
-      try {
-        const data = await healthReportMethod({id, scene: void 0});
-        this.setData({
-          'healthReport.data': data,
-          'healthReport.loading': false,
-        });
-      } catch (error) {
-        this.setData({
-          'healthReport.data': null,
-          'healthReport.loading': false,
-          'healthReport.message': error.errMsg,
-        });
-      }
-    },
     async getHealthIndex(id?: string) {
       this.setData({ 'healthIndex.loading': true, })
       try {
@@ -84,59 +54,9 @@ Component({
         });
       }
     },
-    onDraggableSizeUpdate(e) {
-      'worklet'
-      if (e.pixels < 1) {
-        wx.worklet.runOnJS(this.hideDraggableSheet.bind(this))()
-      }
-    },
-    async showReportList() {
-      if (!this.data.healthReportList.loaded) {
-        wx.showLoading({ title: '加载中' })
-        try {
-          const data = await healthReportListMethod();
-          this.setData({
-            'healthReportList.data': data,
-            'healthReportList.loaded': true,
-          })
-        } catch (error) {
-          getTickleContext.call(this).showErrorMessage(error.errMsg);
-        }
-        wx.hideLoading();
-      }
-      if (this.data.healthReportList.data.length) {
-        getDraggableSheetContext.call(this).scrollTo({
-          size: 0.5,
-          pixels: 600,
-          animated: true,
-          duration: 300,
-          easingFunction: 'ease'
-        });
-        this.setData({ shade: 'shade' });
-      } else {
-        wx.showToast({ title: '暂无更新记录' })
-      }
-    },
-    hideDraggableSheet(e?: any) {
-      if (e) {
-        getDraggableSheetContext.call(this).scrollTo({
-          size: 0,
-          animated: true,
-          duration: 300,
-          easingFunction: 'ease'
-        });
-      }
-      this.setData({ shade: '' });
-    },
-
-    toSchemePage(event: WechatMiniprogram.TouchEvent) { toSchemePage(event.mark?.id); },
-    toReportPage(event: WechatMiniprogram.TouchEvent) { toReportPage(event.mark?.id); },
     toPatientPage: toPatientPage,
     toHealthIndexListPage() {
       wx.navigateTo({ url: `/module/charts/record-index/record-index` })
     },
-    toHealthStatusListPage() {
-      wx.navigateTo({ url: `/module/health/pages/status-record/status-record` })
-    },
   }
 })

+ 2 - 35
miniprogram/module/health/pages/home/home.wxml

@@ -7,19 +7,7 @@
       <t-icon t-class="icon" name="chevron-right-double-s" size="24px" />
     </view>
   </report-health-patient>
-
-
-  <report-health-status dataset="{{healthReport.data}}" loading="{{healthReport.loading}}" message="{{healthReport.message}}" mark:id="{{healthId}}" bind:info="toReportPage">
-    <view class="extra-warapper" slot="extra-status" catch:tap="toHealthStatusListPage">
-      <text>更新记录</text>
-      <t-icon t-class="icon" name="chevron-right-double-s" size="24px" />
-    </view>
-    <view class="extra-warapper" slot="extra-report" catch:tap="showReportList">
-      <text>更新记录</text>
-      <t-icon t-class="icon" name="chevron-right-double-s" size="24px" />
-    </view>
-  </report-health-status>
-  <report-health-scheme dataset="{{healthReport.data.conditProgram}}" mark:id="{{healthId}}" bind:tap="toSchemePage"></report-health-scheme>
+  <report-health-status></report-health-status>
   <report-health-index dataset="{{healthIndex.data}}" loading="{{healthIndex.loading}}" message="{{healthIndex.message}}">
     <view class="extra-warapper" slot="extra" catch:tap="toHealthIndexListPage">
       <text>更新记录</text>
@@ -28,25 +16,4 @@
   </report-health-index>
 </scroll-view>
 
-<t-message id="{{$messageId}}"></t-message>
-
-<view wx:if="{{shade}}" class="draggable-sheet-shade" catch:tap="hideDraggableSheet"></view>
-<draggable-sheet class="draggable-sheet-wrapper health-report-list" style="height: {{container.height}}px;" initial-child-size="0" min-child-size="0" max-child-size="0.8" snap="{{true}}" snap-sizes="{{[0.5]}}" worklet:onsizeupdate="onDraggableSizeUpdate">
-  <scroll-view class="scrollable draggable-sheet-container" type="custom" scroll-y associative-container="draggable-sheet" show-scrollbar="{{false}}" bounces="{{false}}">
-    <sticky-section>
-      <sticky-header>
-        <view class="draggable-sheet-bar">
-          <view class="indicator" />
-          <view class="title">健康分析报告记录</view>
-        </view>
-      </sticky-header>
-      <list-builder list="{{healthReportList.data}}" child-height="90">
-        <block slot:item slot:index>
-          <t-cell t-class="cell-border-gradient" title="{{item.reportTime}}" description="{{item.description}}" arrow mark:id="{{item.id}}" bind:tap="toReportPage">
-            <image slot="image" src="../../assets/image/health-report.png" style="width: 53px;height: 53px;"></image>
-          </t-cell>
-        </block>
-      </list-builder>
-    </sticky-section>
-  </scroll-view>
-</draggable-sheet>
+<t-message id="{{$messageId}}"></t-message>

+ 32 - 8
miniprogram/module/health/request.ts

@@ -1,7 +1,9 @@
 import { Get, Post } from "../../lib/request/method";
-import { createHealthIndex, transformHealthIndex2Chart } from "./tools/health-index";
+import { createHealthIndex } from "./tools/health-index";
 import dayjs from "dayjs";
 
+import { healthAnalysisModel, healthReportModel } from "./model/health.model";
+
 export function healthPatientMethod() {
   return Post(`/patientInfoManage/getPatientInfoDetail`, {}, { transform({ data }) { return data } });
 }
@@ -19,13 +21,8 @@ export function healthReportListMethod() {
   return Get(`/analysisManage/getHarsTid`, { transform })
 }
 
-export function healthReportMethod({ id, scene, ...query }: Record<'id' | 'scene', string | void>) {
-  const transform = ({ data }: AnyObject) => {
-    if (Array.isArray(data?.conditProgram?.types)) {
-      data.conditProgram.types = data.conditProgram.types.map((item: AnyObject) => (item.summary = item.summary?.replace(/null/g, '') || '', item))
-    }
-    return data;
-  };
+export function healthReportMethod({ id, scene, ...query }: Record<'id' | 'scene', string | void>): Promise<ReturnType<typeof healthReportModel>> {
+  const transform = ({ data }: AnyObject) => healthReportModel(data);
 
   let params = { ...query } as any;
   if (id) { params.healthAnalysisReportId = id; }
@@ -40,6 +37,33 @@ export function healthReportMethod({ id, scene, ...query }: Record<'id' | 'scene
     : Post(`/analysisManage/getLastHealRepDetail`, {}, { params, transform })
 }
 
+export function healthAnalysisMethod({ id, scene, ...query }: Record<'id' | 'scene', string | void>): Promise<ReturnType<typeof healthAnalysisModel>> {
+  const transform = ({ data }: AnyObject) => healthAnalysisModel(data);
+  let params = { ...query } as any;
+  if (id) { params.tonguefaceAnalysisReportId = id; }
+
+  if (scene) {
+    params.scene = decodeURIComponent(scene);
+    return Get(`/analysisManage/getTofRepDetailByScene`, { params, transform });
+  }
+  return id
+    ? Get(`/analysisManage/getTofRepDetailById`, { params, transform })
+    : Post(`/analysisManage/getLastTofRepDetail`, {}, { params, transform })
+}
+
+export function healthAnalysisListMethod() {
+  const transform = ({ data }: AnyObject) => {
+    return Array.isArray(data) ? data.map(item => {
+      return {
+        id: item.id,
+        reportTime: item.time3,
+        description: item.content || '',
+      }
+    }) : []
+  }
+  return Get(`/analysisManage/getTofsTid`, { transform })
+}
+
 /**
  * 获取指标信息
  * @param id 健康分析报告

+ 1 - 1
miniprogram/themes/card.scss

@@ -3,7 +3,7 @@
   // --td-cell-horizontal-padding: 12px;
 
   $gap: 12px;
-  margin: 3px var(--page-container-bleeding, 7px);
+  margin: 6px var(--page-container-bleeding, 7px);
   border-radius: $gap;
   box-shadow: inset 0px 0px $gap * 3 0px rgba(52, 167, 107, 0.38);
 

+ 10 - 0
miniprogram/utils/util.ts

@@ -17,3 +17,13 @@ const formatNumber = (n: number) => {
   const s = n.toString()
   return s[1] ? s : '0' + s
 }
+
+export function groupBy<T>(items: Iterable<T>, callbackFn: (element: T, index: number) => any): Record<string, T[]> {
+  const obj = Object.create(null);
+  let k = 0;
+  for (const value of items) {
+    const key = callbackFn(value, k++);
+    if (key in obj) { obj[key].push(value); } else { obj[key] = [value]; }
+  }
+  return obj;
+}