health-report.model.ts 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. import {
  2. analysisPictureStrategy,
  3. type HealthReportAnalysisCategory,
  4. HealthReportAnalysisItemConfig,
  5. type HealthReportAnalysisKey,
  6. type HealthReportAnalysisSubcategory,
  7. HealthReportSymptomItemConfig,
  8. } from '@/model/health-report-analysis.config';
  9. export interface HealthReportAnalysisItemDTO {
  10. standardValue: string;
  11. actualList: {
  12. splitImage: string;
  13. actualValue: string;
  14. contrast: string;
  15. attrs: string[];
  16. features: string;
  17. clinicalSignificance?: string;
  18. mechanismAnalyze?: string;
  19. }[];
  20. }
  21. export interface HealthReportDTO extends Record<HealthReportAnalysisKey, HealthReportAnalysisItemDTO>, Record<`${HealthReportAnalysisCategory}AnalysisResult`, string> {
  22. tonguefaceAnalysisReportId: string;
  23. healthAnalysisReportId: string;
  24. reportTime: string;
  25. time4: string;
  26. pickedSymptomList?: { id: string; name: string; value: string; score: number }[];
  27. pickedSymptom?: string;
  28. duration?: string;
  29. influenceDegree?: string;
  30. willillStateName: string;
  31. willillDegreeName: string;
  32. willillFunctionName: string;
  33. willillSocialName: string;
  34. constitutionGroupName: string;
  35. constitutionGroupDefinition: string;
  36. factorItemSummary: string;
  37. diagnoseSyndromeSummary: string;
  38. }
  39. export interface HealthReportAnalysisItemVO {
  40. category: HealthReportAnalysisCategory;
  41. subcategory: HealthReportAnalysisSubcategory;
  42. standardValue: string;
  43. resultValue: string;
  44. values: {
  45. cover?: string;
  46. contrast: string;
  47. actualValue: string;
  48. resultValue: string;
  49. tags: string[];
  50. /**
  51. * 特征
  52. */
  53. feature: string;
  54. /**
  55. * 意义
  56. * @description
  57. * - tongue 临床意义
  58. * - face 病理意义
  59. */
  60. significance: string;
  61. /**
  62. * 机理分析
  63. */
  64. analysis?: string;
  65. }[];
  66. }
  67. export interface HealthReportAnalysisVO
  68. extends Record<
  69. HealthReportAnalysisCategory,
  70. {
  71. result: string;
  72. analysis: HealthReportAnalysisItemVO[];
  73. pictures: string[];
  74. }
  75. > {
  76. id?: string;
  77. }
  78. export interface HealthReportSymptomItemVo {
  79. /**
  80. * 症状ID
  81. */
  82. id: string;
  83. /**
  84. * 症状名称
  85. */
  86. name: string;
  87. /**
  88. * 症状描述
  89. */
  90. label: string;
  91. /**
  92. * 症状得分
  93. */
  94. value: number;
  95. }
  96. export interface HealthReportSymptomVo {
  97. items: HealthReportSymptomItemVo[];
  98. value?: string;
  99. duration?: string;
  100. influence?: string;
  101. }
  102. export interface HealthReportVO {
  103. id: string;
  104. date: string;
  105. analysis: HealthReportAnalysisVO;
  106. symptom: HealthReportSymptomVo;
  107. result: {
  108. status?: string;
  109. level?: string;
  110. description?: string;
  111. category: string;
  112. };
  113. physique: {
  114. label: string;
  115. description: string;
  116. };
  117. syndrome: {
  118. label: string;
  119. };
  120. syndromeElement: {
  121. label: string;
  122. };
  123. }
  124. export function fromHealthReport(data: HealthReportDTO): HealthReportVO {
  125. return {
  126. id: data.healthAnalysisReportId,
  127. date: data.reportTime ?? data.time4,
  128. analysis: fromHealthReportAnalysis(data),
  129. symptom: fromHealthReportSymptom(data),
  130. result: {
  131. status: data.willillStateName,
  132. level: data.willillDegreeName,
  133. description: data.willillFunctionName,
  134. category: data.willillSocialName,
  135. },
  136. physique: {
  137. label: data.constitutionGroupName,
  138. description: data.constitutionGroupDefinition,
  139. },
  140. syndromeElement: {
  141. label: data.factorItemSummary,
  142. },
  143. syndrome: {
  144. label: data.diagnoseSyndromeSummary,
  145. },
  146. };
  147. }
  148. export function fromHealthReportAnalysis(data: Partial<HealthReportDTO>, config = HealthReportAnalysisItemConfig): HealthReportAnalysisVO {
  149. const result = { id: data.tonguefaceAnalysisReportId } as HealthReportAnalysisVO;
  150. for (const { key, category, subcategory } of config) {
  151. const { analysis } =
  152. result[category] ??
  153. (result[category] = {
  154. analysis: [],
  155. result: data[`${category}AnalysisResult`] ?? '',
  156. pictures: analysisPictureStrategy[category]?.(data) ?? [],
  157. });
  158. if (!data[key]) continue;
  159. const { standardValue, actualList } = data[key]!;
  160. const values: HealthReportAnalysisItemVO['values'] = [];
  161. for (const { actualValue, splitImage: cover, ...item } of actualList) {
  162. const contrast = item.contrast === 's' ? '' : (item.contrast ?? '');
  163. const [_, features = _, significance = item.clinicalSignificance] = item.features?.match?.(
  164. new RegExp(`【(?:${actualValue}|正常${subcategory}|正常面色)】([^<]*)<?[\\s\\S]*?【病理意义】([^<]*)`)
  165. ) ?? item.features?.match?.(
  166. new RegExp(`([^<]*)<?[\\s\\S]*?【病理意义】([^<]*)`)
  167. ) ?? [item.features];
  168. values.push({
  169. cover: contrast ? cover : void 0,
  170. actualValue,
  171. // resultValue: contrast && contrast !=='r' ? `${actualValue} (${contrast})` : actualValue,
  172. resultValue: contrast ? `${actualValue} (${contrast})` : actualValue,
  173. contrast,
  174. feature: features ?? '',
  175. significance: significance ?? '',
  176. tags: item.attrs ?? [],
  177. analysis: item.mechanismAnalyze ?? '',
  178. });
  179. }
  180. analysis.push({
  181. category,
  182. subcategory,
  183. standardValue,
  184. resultValue: values.map((item) => item.resultValue).join('、'),
  185. values,
  186. });
  187. }
  188. return result;
  189. }
  190. export function fromHealthReportSymptom(data: Partial<HealthReportDTO>, config = HealthReportSymptomItemConfig): HealthReportSymptomVo {
  191. const result: HealthReportSymptomVo = {
  192. value: data.pickedSymptom,
  193. items:
  194. data.pickedSymptomList?.map(({ id, name, ...item }) => ({
  195. id,
  196. name,
  197. label: item.value,
  198. value: +item.score,
  199. })) ?? [],
  200. duration: data.duration,
  201. influence: data.influenceDegree,
  202. };
  203. if (!result.items?.length && result.value) {
  204. const matches = result.value?.matchAll(/([^,(]+)(([^)]+))/g) ?? [];
  205. for (const [_, name, label] of matches) {
  206. // @ts-ignore
  207. const value = config[label] ?? 0;
  208. result.items.push({ id: name, name, label, value });
  209. }
  210. }
  211. return result;
  212. }
  213. export interface HealthIndicatorVO {
  214. items: HealthIndicatorItemVO[];
  215. id: string;
  216. name: string;
  217. }
  218. export interface HealthIndicatorItemVO {
  219. id: string;
  220. name: string;
  221. value: number;
  222. unit: string;
  223. trend: 0 | -1 | 1;
  224. date: string;
  225. }
  226. export function fromHealthIndicator(data: Record<string, any>): HealthIndicatorVO {
  227. return {
  228. id: data.quotaId,
  229. name: data.name,
  230. items: data.patientQuotaRecordDTOS?.map?.((item: any) => fromHealthIndicatorItem(Object.assign(item, data))) ?? [],
  231. };
  232. }
  233. export function fromHealthIndicatorItem(data: Record<string, any>): HealthIndicatorItemVO {
  234. const getTrend = (value: string) => {
  235. if (value?.includes('高')) return 1 as const;
  236. if (value?.includes('低')) return -1 as const;
  237. return 0 as const;
  238. };
  239. return {
  240. id: data.quotaId,
  241. name: data.name,
  242. unit: data.unit,
  243. value: data.quotaVal,
  244. trend: data.abnormal ? getTrend(data.abnormalDesc) : 0,
  245. date: data.time4 || data.time2,
  246. };
  247. }