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

健康报告舌面象数据解析

cc12458 пре 1 година
родитељ
комит
65bf783cd9
2 измењених фајлова са 162 додато и 0 уклоњено
  1. 52 0
      src/model/health-report-analysis.config.ts
  2. 110 0
      src/model/health-report.model.ts

+ 52 - 0
src/model/health-report-analysis.config.ts

@@ -0,0 +1,52 @@
+export const HealthReportAnalysisItemConfig = [
+  { category: 'tongue', key: 'tongueColor', subcategory: '舌色' },
+  { category: 'tongue', key: 'tongueCoatingColor', subcategory: '苔色' },
+  { category: 'tongue', key: 'tongueShape', subcategory: '舌形' },
+  { category: 'tongue', key: 'tongueCoating', subcategory: '苔质' },
+  { category: 'tongue', key: 'bodyFluid', subcategory: '津液' },
+  { category: 'tongue', key: 'sublingualVein', subcategory: '舌下' },
+
+  { category: 'face', key: 'faceColor', subcategory: '面色' },
+  { category: 'face', key: 'mainColor', subcategory: '主色' },
+  { category: 'face', key: 'shine', subcategory: '光泽' },
+  { category: 'face', key: 'leftBlackEye', subcategory: '左黑眼圈' },
+  { category: 'face', key: 'rightBlackEye', subcategory: '右黑眼圈' },
+  { category: 'face', key: 'lipColor', subcategory: '唇色' },
+  { category: 'face', key: 'eyeContact', subcategory: '眼神' },
+  { category: 'face', key: 'leftEyeColor', subcategory: '左目色' },
+  { category: 'face', key: 'rightEyeColor', subcategory: '右目色' },
+  { category: 'face', key: 'hecticCheek', subcategory: '两颧红' },
+  { category: 'face', key: 'noseFold', subcategory: '鼻褶' },
+  { category: 'face', key: 'cyanGlabella', subcategory: '眉间/鼻柱青色' },
+  { category: 'face', key: 'faceSkinDefects', subcategory: '面部皮损' },
+] as const;
+
+type HealthReportAnalysisItem = (typeof HealthReportAnalysisItemConfig)[number];
+
+export type HealthReportAnalysisKey = HealthReportAnalysisItem['key'];
+export type HealthReportAnalysisCategory = HealthReportAnalysisItem['category'];
+export type HealthReportAnalysisSubcategory = HealthReportAnalysisItem['subcategory'];
+
+export const analysisPictureStrategy: Record<
+  HealthReportAnalysisCategory,
+  (data: any) => string[]
+> = {
+  face(data: any): string[] {
+    const p1 = data.faceImg || data.faceImgUrl;
+    const p2 = data.faceLeft || data.faceLeftImgUrl;
+    const p3 = data.faceRight || data.faceRightImgUrl;
+    return Object.assign([p1, p2, p3].filter(Boolean), {
+      ['正面']: p1,
+      ['左面']: p2,
+      ['右面']: p3,
+    });
+  },
+  tongue(data: any): string[] {
+    const p1 = data.upImg || data.tongueImgUrl;
+    const p2 = data.downImg || data.tongueBackImgUrl;
+    return Object.assign([p1, p2].filter(Boolean), {
+      ['舌上']: p1,
+      ['舌下']: p2,
+    });
+  },
+};

+ 110 - 0
src/model/health-report.model.ts

@@ -0,0 +1,110 @@
+import {
+  analysisPictureStrategy,
+  type HealthReportAnalysisCategory,
+  HealthReportAnalysisItemConfig,
+  type HealthReportAnalysisKey,
+  type HealthReportAnalysisSubcategory,
+} from '@/model/health-report-analysis.config';
+
+export interface HealthReportAnalysisItemDTO {
+  standardValue: string;
+  actualList: {
+    splitImage: string;
+    actualValue: string;
+    contrast: string;
+    attrs: string[];
+    features: string;
+    clinicalSignificance?: string;
+    mechanismAnalyze?: string;
+  }[];
+}
+
+export interface HealthReportDTO extends Record<HealthReportAnalysisKey, HealthReportAnalysisItemDTO>, Record<`${HealthReportAnalysisCategory}AnalysisResult`, string> {
+  tonguefaceAnalysisReportId: string;
+
+  healthAnalysisReportId: string;
+  reportTime: string;
+
+  pickedSymptomList?: { id: string; name: string; value: string; score: number }[];
+  pickedSymptom?: string;
+  duration?: string;
+  influenceDegree?: string;
+}
+
+export interface HealthReportAnalysisItemVO {
+  category: HealthReportAnalysisCategory;
+  subcategory: HealthReportAnalysisSubcategory;
+  standardValue: string;
+  resultValue: string;
+  values: {
+    cover?: string;
+    contrast: string;
+    actualValue: string;
+    resultValue: string;
+    tags: string[];
+    feature: string;
+    /**
+     * 意义
+     * @description
+     *  - tongue  临床意义
+     *  - face    病理意义
+     */
+    significance: string;
+    /**
+     * 机理分析
+     */
+    analysis?: string;
+  }[];
+}
+
+export interface HealthReportAnalysisVO
+  extends Record<
+    HealthReportAnalysisCategory,
+    {
+      result: string;
+      analysis: HealthReportAnalysisItemVO[];
+      pictures: string[];
+    }
+  > {
+  id?: string;
+}
+
+export function fromHealthReportAnalysis(data: Partial<HealthReportDTO>, config = HealthReportAnalysisItemConfig): HealthReportAnalysisVO {
+  const result = { id: data.tonguefaceAnalysisReportId } as HealthReportAnalysisVO;
+  for (const { key, category, subcategory } of config) {
+    const { analysis } =
+      result[category] ??
+      (result[category] = {
+        analysis: [],
+        result: data[`${category}AnalysisResult`] ?? '',
+        pictures: analysisPictureStrategy[category]?.(data) ?? [],
+      });
+    if (!data[key]) continue;
+    const { standardValue, actualList } = data[key]!;
+    const values: HealthReportAnalysisItemVO['values'] = [];
+    for (const { actualValue, splitImage: cover, ...item } of actualList) {
+      const contrast = item.contrast === 's' ? '' : (item.contrast ?? '');
+      const [_, features = _, significance = item.clinicalSignificance] = item.features?.match?.(
+        new RegExp(`【(?:${actualValue}|正常${subcategory}|正常面色)】([^<]*)<?[\\s\\S]*?【病理意义】([^<]*)`)
+      ) ?? [item.features];
+      values.push({
+        cover: contrast ? cover : void 0,
+        actualValue,
+        resultValue: contrast ? `${actualValue} (${contrast})` : actualValue,
+        contrast,
+        feature: features ?? '',
+        significance: significance ?? '',
+        tags: item.attrs ?? [],
+        analysis: item.mechanismAnalyze ?? '',
+      });
+    }
+    analysis.push({
+      category,
+      subcategory,
+      standardValue,
+      resultValue: values.map((item) => item.resultValue).join('、'),
+      values,
+    });
+  }
+  return result;
+}