| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- <script setup lang="ts">
- import type { PatientModel, ReportModel, ReportSchemeModel } from '@/model';
- import { indicatorByReportIdMethod, reportMethod, reportSchemeMethod, reportsMethod } from '@/request/api/report.api';
- import ReportCardWidget
- from '@/widgets/ReportCardWidget.vue';
- import ReportSchemeCardWidget
- from '@/widgets/ReportSchemeCardWidget.vue';
- import { ArrowDownOutlined, ArrowUpOutlined } from '@ant-design/icons-vue';
- import { useWatcher } from 'alova/client';
- const props = defineProps<{
- patient?: Partial<PatientModel>;
- report?: Partial<ReportModel>;
- scheme?: Partial<ReportSchemeModel>;
- }>();
- const emits = defineEmits<{
- destroy: [];
- }>();
- const patientId = defineModel<string>('patientId', { default: void 0 });;
- const reportId = defineModel<string>('reportId', { default: void 0 });
- const showType = defineModel<'analysis' | 'scheme'>('type', { default: 'analysis' });
- const { data: report, loading: reportLoading } = useWatcher(
- () => reportMethod(reportId.value!),
- [ reportId, showType ],
- {
- initialData: { ...props.report }, immediate: true,
- middleware: (_, next) => { if ( reportId.value && showType.value === 'analysis' ) next(); },
- },
- ).onSuccess(({data}) => {
- scrollIntoView();
- patientId.value ??= data.patientId;
- });
- const { data: indicator, loading: indicatorLoading } = useWatcher(
- () => indicatorByReportIdMethod(reportId.value!),
- [ reportId, showType ],
- {
- initialData: [], immediate: true,
- middleware: (_, next) => { if ( reportId.value && showType.value === 'analysis' ) next(); },
- },
- );
- const { data: reports, loading: reportsLoading } = useWatcher(
- () => reportsMethod(patientId.value!),
- [ patientId, showType ],
- {
- initialData: [], immediate: true,
- middleware: (_, next) => { if ( patientId.value && showType.value === 'analysis' ) next(); },
- },
- );
- const { data: scheme, loading: schemeLoading } = useWatcher(
- () => reportSchemeMethod(reportId.value!),
- [ reportId, showType ],
- {
- initialData: { ...props.scheme }, immediate: true,
- middleware: (_, next) => { if ( reportId.value && showType.value === 'scheme' ) next(); },
- },
- ).onSuccess(() => scrollIntoView());
- onBeforeMount(() => {
- reportId.value ??= props.report?.id!;
- patientId.value ??= props.patient?.id!;
- });
- const schemeKeys = ref([]);
- const collapsed = ref(false);
- const expandAll = (value: boolean) => {
- collapsed.value = value;
- schemeKeys.value = value ? scheme.value.children.map(child => child.id) : [] as string[];
- };
- const containerRef = ref<HTMLElement & { elementTarget: HTMLElement }>();
- function scrollIntoView() {
- const el = unref(containerRef.value?.elementTarget) ?? containerRef.value;
- el?.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'nearest' });
- }
- </script>
- <template>
- <div id="page-container-scroller" class="page-container flex flex-col">
- <template v-if="showType === 'analysis'">
- <ReportCardWidget ref="containerRef" :dataset="report" :loading="reportLoading" :collapsible="false" hide-title>
- <template #select>
- <a-select
- v-model:value="reportId" :loading="reportsLoading"
- :options="reports" :field-names="{label: 'time', value: 'id'}"
- style="min-width: 120px;"
- ></a-select>
- </template>
- <a-card class="card background no-bordered-8" size="small" title="指标信息" :loading="indicatorLoading">
- <a-descriptions v-if="indicator?.length" :column="3" size="small">
- <a-descriptions-item v-for="item in indicator" :key="item.id" :label="item.name">
- <div v-if="item.value">
- <span>{{ item.value }}</span>
- <span v-if="item.unit">{{ item.unit }}</span>
- <ArrowUpOutlined class="icon" v-if="item.records?.[0]?.abnormal === 1" />
- <ArrowDownOutlined class="icon" v-if="item.records?.[0]?.abnormal === -1" />
- </div>
- <span v-else>-</span>
- </a-descriptions-item>
- </a-descriptions>
- <div v-else style="padding-bottom: 8px;">暂无数据</div>
- </a-card>
- </ReportCardWidget>
- </template>
- <template v-else-if="showType === 'scheme'">
- <div class="card report-card" ref="containerRef">
- <div class="card__content" style="padding-bottom: 0;">
- <a-card class="card no-bordered background" size="small" :loading="schemeLoading">
- <a-descriptions :column="3">
- <a-descriptions-item v-if="scheme.time" label="方案日期" :span="3">
- <span>{{ scheme.time }}</span>
- </a-descriptions-item>
- <a-descriptions-item v-if="scheme.process" label="方案进程" :span="3">
- <span style="margin-right: 8px;">{{ scheme.process }}</span>
- </a-descriptions-item>
- </a-descriptions>
- </a-card>
- </div>
- </div>
- <ReportSchemeCardWidget :dataset="scheme" :loading="schemeLoading" hide-title />
- </template>
- </div>
- </template>
- <style scoped lang="scss">
- @import "@/themes/report-card";
- .scheme-dataset-collapse-2 {
- .header + .header,
- .description + .description {
- &::before {
- content: ":";
- margin: 0 4px 0 2px;
- color: #333;
- }
- }
- :deep(.preview-wrapper) {
- padding: 0;
- .ant-descriptions-item-label {
- width: 120px;
- text-align: center;
- }
- .ant-carousel {
- transform: translateY(-12px)
- }
- }
- }
- </style>
|