| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- <script setup lang="ts">
- import { ArrowDownOutlined, ArrowUpOutlined, CaretRightOutlined } from '@ant-design/icons-vue';
- import { h, ref } from 'vue';
- import { useRequest } from 'alova/client';
- import { getPatientHealthIndicatorRecordsMethod } from '@/request/api/report.api';
- import type { HealthIndicatorItemVO, HealthIndicatorVO } from '@/model/health-report.model';
- import dayjs from 'dayjs';
- const props = defineProps<{ patient: { id: string } }>();
- const indicators = shallowRef<HealthIndicatorVO[]>([]);
- const activeKey = ref<string[]>([]);
- const { loading } = useRequest(() => getPatientHealthIndicatorRecordsMethod(props.patient.id)).onSuccess(({ data }) => {
- indicators.value = conversionGrouping(data);
- activeKey.value = indicators.value.map((item) => item.name);
- });
- function conversionGrouping(data: HealthIndicatorVO[]): HealthIndicatorVO[] {
- const gather = new Map<number, HealthIndicatorVO>();
- const indicators = data.flatMap((indicator) => indicator.items);
- for (const indicator of indicators) {
- const key = dayjs(indicator.date).toDate().valueOf();
- const value = gather.has(key)
- ? gather.get(key)!
- : (gather.set(key, {
- id: indicator.date,
- name: indicator.date,
- items: [],
- }),
- gather.get(key)!);
- value.items.push(indicator);
- }
- return Array.from(gather.keys())
- .sort((a, b) => b - a)
- .map((title) => ({ title, ...gather.get(title)! }));
- }
- </script>
- <template>
- <a-spin :spinning="loading">
- <a-collapse v-if="indicators.length" class="physical-sign-records-wrapper" v-model:activeKey="activeKey" :bordered="false">
- <a-collapse-panel v-for="indicator in indicators" :key="indicator.name" :header="indicator.name">
- <div class="flex flex-wrap">
- <div class="text-center w-260px row" v-for="item in indicator.items" :key="item.name">
- <div class="flex justify-center">
- <span><label>{{ item.name }}</label>{{ item.value }}{{ item.unit }}</span>
- <div class="inline-block ml-2 size-24px">
- <a-button v-if="item.trend > 0" :icon="h(ArrowUpOutlined)" shape="circle" size="small" class="trend-up" />
- <a-button v-else-if="item.trend < 0" :icon="h(ArrowDownOutlined)" shape="circle" size="small" class="trend-down" />
- </div>
- </div>
- </div>
- </div>
- </a-collapse-panel>
- </a-collapse>
- <a-empty v-else description="暂无数据"></a-empty>
- </a-spin>
- </template>
- <style scoped lang="scss">
- .physical-sign-records-wrapper {
- background-color: transparent;
- :deep(.ant-collapse-item) {
- margin-bottom: 12px;
- border-bottom: none;
- }
- .row {
- padding: 12px 0;
- span > label {
- color: rgba(0, 0, 0, 0.45);
- }
- label::after {
- margin-left: 2px;
- margin-right: 8px;
- content: ':';
- }
- > header::before {
- $size: 10px;
- content: '';
- display: inline-block;
- margin-right: 12px;
- width: $size;
- height: $size;
- border: 2px solid #1d6ff6;
- border-radius: 50%;
- }
- > main {
- margin-left: 18px * 2;
- }
- }
- }
- .trend-up {
- color: #ff4d4f;
- border-color: #ff4d4f;
- }
- .trend-down {
- color: #87d068;
- border-color: #87d068;
- }
- </style>
|