AnalysisReportWidget.vue 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. <script setup lang="ts">
  2. import type { ReportModel } from '@/model';
  3. import { indicatorByReportIdMethod, reportMethod } from '@/request/api/report.api';
  4. import { ArrowDownOutlined, ArrowUpOutlined } from '@ant-design/icons-vue';
  5. import { useWatcher } from 'alova/client';
  6. const props = defineProps<{ report?: ReportModel }>();
  7. const emits = defineEmits<{ loaded: [] }>();
  8. const reportId = inject('report-id', toRef(() => props.report?.id));
  9. const { data: report, loading: reportLoading } = useWatcher(
  10. () => reportMethod(reportId.value!),
  11. [ reportId ],
  12. { initialData: props.report, immediate: true },
  13. ).onComplete(() => { emits('loaded'); });
  14. const { data: indicator, loading: indicatorLoading } = useWatcher(
  15. () => indicatorByReportIdMethod(reportId.value!),
  16. [ reportId ],
  17. { initialData: [], immediate: true },
  18. );
  19. </script>
  20. <template>
  21. <div class="widget-wrapper">
  22. <a-card class="card no-bordered" size="small">
  23. <a-descriptions :column="3">
  24. <a-descriptions-item v-if="report.willillStateName" label="健康状态">
  25. {{ report.willillStateName }}
  26. </a-descriptions-item>
  27. <a-descriptions-item v-if="report.willillDegreeName" label="程度" :span="2">
  28. {{ report.willillDegreeName }}
  29. </a-descriptions-item>
  30. <a-descriptions-item v-if="report.willillFunctionName" label="表现">
  31. {{ report.willillFunctionName }}
  32. </a-descriptions-item>
  33. <a-descriptions-item v-if="report.constitutionGroupName" label="体质" :span="2">
  34. {{ report.constitutionGroupName }}
  35. </a-descriptions-item>
  36. </a-descriptions>
  37. </a-card>
  38. <a-card class="card" size="small">
  39. <p v-if="report.constitutionGroupDefinition">体质: {{ report.constitutionGroupDefinition }}</p>
  40. <a-descriptions :column="1" bordered>
  41. <a-descriptions-item v-if="report.constitutionGroupGeneralCharacteristics" label="总体特征">
  42. {{ report.constitutionGroupGeneralCharacteristics }}
  43. </a-descriptions-item>
  44. <a-descriptions-item v-if="report.constitutionGroupPhysicalCharacteristics" label="形体特征">
  45. {{ report.constitutionGroupPhysicalCharacteristics }}
  46. </a-descriptions-item>
  47. <a-descriptions-item v-if="report.constitutionGroupPsychicCharacteristics" label="精神特征">
  48. {{ report.constitutionGroupPsychicCharacteristics }}
  49. </a-descriptions-item>
  50. <a-descriptions-item v-if="report.constitutionGroupCommonManifestations" label="常见表现">
  51. {{ report.constitutionGroupCommonManifestations }}
  52. </a-descriptions-item>
  53. <a-descriptions-item v-if="report.constitutionGroupDiseaseTendency" label="发病倾向">
  54. {{ report.constitutionGroupDiseaseTendency }}
  55. </a-descriptions-item>
  56. <a-descriptions-item v-if="report.constitutionGroupAdaptability" label="环境适应能力">
  57. {{ report.constitutionGroupAdaptability }}
  58. </a-descriptions-item>
  59. </a-descriptions>
  60. </a-card>
  61. <a-card class="card" size="small" title="舌象分析">
  62. <a-descriptions :column="3">
  63. <a-descriptions-item>
  64. <a-image :width="200" :src="report.upImg" :preview="true" v-if="report.upImg" />
  65. </a-descriptions-item>
  66. <a-descriptions-item>
  67. <a-image :width="200" :src="report.downImg" :preview="true" v-if="report.downImg" />
  68. </a-descriptions-item>
  69. <a-descriptions-item></a-descriptions-item>
  70. </a-descriptions>
  71. <a-descriptions :column="3" bordered>
  72. <a-descriptions-item style="font-size: 16px;font-weight: 600;">舌象维度</a-descriptions-item>
  73. <a-descriptions-item style="font-size: 16px;font-weight: 600;">检测结果</a-descriptions-item>
  74. <a-descriptions-item style="font-size: 16px;font-weight: 600;">标准值</a-descriptions-item>
  75. <template v-if="report.tongueColor?.actualList">
  76. <a-descriptions-item>舌色</a-descriptions-item>
  77. <a-descriptions-item>
  78. <span class="tongue-value" v-for="item in report.tongueColor.actualList" :key="item?.actualValue">
  79. <span>{{ item.actualValue }}</span>
  80. <span v-if="item.contrast !== 's'">({{ item.contrast }})</span>
  81. </span>
  82. </a-descriptions-item>
  83. <a-descriptions-item>{{ report.tongueColor.standardValue }}</a-descriptions-item>
  84. </template>
  85. <template v-if="report.tongueCoatingColor?.actualList">
  86. <a-descriptions-item>苔色</a-descriptions-item>
  87. <a-descriptions-item>
  88. <span class="tongue-value" v-for="item in report.tongueCoatingColor.actualList" :key="item?.actualValue">
  89. <span>{{ item.actualValue }}</span>
  90. <span v-if="item.contrast !== 's'">({{ item.contrast }})</span>
  91. </span>
  92. </a-descriptions-item>
  93. <a-descriptions-item>{{ report.tongueCoatingColor.standardValue }}</a-descriptions-item>
  94. </template>
  95. <template v-if="report.tongueShape?.actualList">
  96. <a-descriptions-item>舌形</a-descriptions-item>
  97. <a-descriptions-item>
  98. <span class="tongue-value" v-for="item in report.tongueShape.actualList" :key="item?.actualValue">
  99. <span>{{ item.actualValue }}</span>
  100. <span v-if="item.contrast !== 's'">({{ item.contrast }})</span>
  101. </span>
  102. </a-descriptions-item>
  103. <a-descriptions-item>{{ report.tongueShape.standardValue }}</a-descriptions-item>
  104. </template>
  105. <template v-if="report.tongueCoating?.actualList">
  106. <a-descriptions-item>苔质</a-descriptions-item>
  107. <a-descriptions-item>
  108. <span class="tongue-value" v-for="item in report.tongueCoating.actualList" :key="item?.actualValue">
  109. <span>{{ item.actualValue }}</span>
  110. <span v-if="item.contrast !== 's'">({{ item.contrast }})</span>
  111. </span>
  112. </a-descriptions-item>
  113. <a-descriptions-item>{{ report.tongueCoating.standardValue }}</a-descriptions-item>
  114. </template>
  115. <template v-if="report.bodyFluid?.actualList">
  116. <a-descriptions-item>津液</a-descriptions-item>
  117. <a-descriptions-item>
  118. <span class="tongue-value" v-for="item in report.bodyFluid.actualList" :key="item?.actualValue">
  119. <span>{{ item.actualValue }}</span>
  120. <span v-if="item.contrast !== 's'">({{ item.contrast }})</span>
  121. </span>
  122. </a-descriptions-item>
  123. <a-descriptions-item>{{ report.bodyFluid.standardValue }}</a-descriptions-item>
  124. </template>
  125. <template v-if="report.sublingualVein?.actualList">
  126. <a-descriptions-item>舌下</a-descriptions-item>
  127. <a-descriptions-item>
  128. <span class="" v-for="item in report.sublingualVein.actualList" :key="item?.actualValue">
  129. <span>{{ item.actualValue }}</span>
  130. <span v-if="item.contrast !== 's'">({{ item.contrast }})</span>
  131. </span>
  132. </a-descriptions-item>
  133. <a-descriptions-item>{{ report.sublingualVein.standardValue }}</a-descriptions-item>
  134. </template>
  135. </a-descriptions>
  136. </a-card>
  137. <a-card class="card no-bordered" size="small" title="面象分析" v-if="report.faceAnalysisResult">
  138. <a-descriptions :column="3">
  139. <a-descriptions-item>
  140. <a-image :width="200" :src="report.faceImg" :preview="true" v-if="report.faceImg" />
  141. </a-descriptions-item>
  142. <a-descriptions-item :span="2">{{ report.faceAnalysisResult }}</a-descriptions-item>
  143. </a-descriptions>
  144. </a-card>
  145. <a-card class="card symptom-card" size="small" title="中医证素" v-if="report.factorItems?.length">
  146. <a-descriptions :column="1" bordered>
  147. <a-descriptions-item v-for="item in report.factorItems" :key="item.factorItemName"
  148. :label="item.factorItemName"
  149. >
  150. {{ item.factorItemDescription }}
  151. </a-descriptions-item>
  152. </a-descriptions>
  153. </a-card>
  154. <a-card class="card symptom-card" size="small" title="中医证型" v-if="report.diagnoseSyndromes?.length">
  155. <a-descriptions :column="1" bordered>
  156. <a-descriptions-item v-for="item in report.diagnoseSyndromes" :key="item.diagnoseSyndromeName"
  157. :label="item.diagnoseSyndromeName"
  158. >
  159. {{ item.diagnoseSyndromeAnalysis }}
  160. </a-descriptions-item>
  161. </a-descriptions>
  162. </a-card>
  163. <a-card class="card no-bordered" size="small" :loading="indicatorLoading" title="指标信息" v-if="indicator?.length">
  164. <a-descriptions :column="3">
  165. <a-descriptions-item v-for="item in indicator" :label="item?.name" :key="item?.quotaId">
  166. {{ item?.quotaVal }}
  167. {{ item.unit }}
  168. <ArrowUpOutlined class="icon" v-if="item?.abnormal === 1" />
  169. <ArrowDownOutlined class="icon" v-else-if="item?.abnormal === -1" />
  170. </a-descriptions-item>
  171. </a-descriptions>
  172. </a-card>
  173. </div>
  174. </template>
  175. <style scoped lang="scss">
  176. .card {
  177. margin-bottom: 12px;
  178. &.no-bordered {
  179. :deep(.ant-card-body) {
  180. padding-top: 16px;
  181. padding-bottom: 0;
  182. }
  183. }
  184. .tongue-value {
  185. margin: 0 4px;
  186. &:first-of-type {
  187. margin-left: 0;
  188. }
  189. &:last-of-type {
  190. margin-right: 0;
  191. }
  192. }
  193. }
  194. .symptom-card {
  195. :deep(.ant-descriptions-item-label) {
  196. padding: 8px 12px;
  197. width: 120px;
  198. text-align: center;
  199. }
  200. }
  201. .icon {
  202. margin-left: 4px;
  203. font-size: 18px;
  204. color: #b22222ff;
  205. transform: translateY(2px);
  206. }
  207. </style>