Przeglądaj źródła

开立调养方案 添加 健康档案、健康分析报告 & 方案 入口

cc12458 10 miesięcy temu
rodzic
commit
db41a023a1

+ 2 - 1
src/model/health-report.model.ts

@@ -25,6 +25,7 @@ export interface HealthReportDTO extends Record<HealthReportAnalysisKey, HealthR
 
   healthAnalysisReportId: string;
   reportTime: string;
+  time4: string;
 
   pickedSymptomList?: { id: string; name: string; value: string; score: number }[];
   pickedSymptom?: string;
@@ -139,7 +140,7 @@ export interface HealthReportVO {
 export function fromHealthReport(data: HealthReportDTO): HealthReportVO {
   return {
     id: data.healthAnalysisReportId,
-    date: data.reportTime,
+    date: data.reportTime ?? data.time4,
     analysis: fromHealthReportAnalysis(data),
     symptom: fromHealthReportSymptom(data),
 

+ 166 - 29
src/pages/index/care/issueService.vue

@@ -1,7 +1,7 @@
 <script setup lang="ts">
 import { useRoute } from 'vue-router';
 import { ref, computed, nextTick, h, watch, onMounted } from 'vue';
-import { MinusCircleOutlined, EyeOutlined } from '@ant-design/icons-vue';
+import { MinusCircleOutlined, EyeOutlined, EditOutlined } from '@ant-design/icons-vue';
 import { notification } from 'ant-design-vue';
 import { message } from 'ant-design-vue';
 import type { OpenConditioningSchemeModel, SystemCwModel } from '@/model/care.model';
@@ -20,12 +20,16 @@ import {
   getAreaMethod,
   getAvailableCwMethod,
 } from '@/request/api/care.api';
-import { patientMethod, patientTags } from '@/request/api/patient.api';
+import { patientMethod, getPatientTagsMethod } from '@/request/api/patient.api';
 import { useRequest, usePagination } from 'alova/client';
 import ServicePackageDetail from '@/service/ServicePackageDetail.vue';
 import { VxeUI } from 'vxe-pc-ui';
-import type { PatientTagModel } from '@/model/patient.model';
+import type { HealthReportVO } from '@/model/health-report.model';
+import type { PatientTagVO } from '@/model/patient.model';
 import dayjs from 'dayjs';
+
+import { getPatientHealthRecordsMethod } from '@/request/api/report.api';
+
 type FollowModel = Partial<OpenConditioningSchemeModel>;
 // const props = defineProps<{ data: FollowModel }>();
 
@@ -98,6 +102,7 @@ export interface PatientModel {
   patientAge: number;
   diagnosis: string;
   symptom: string;
+  healthAnalysisReportId: string;
   healthAnalysisReport: {
     willillStateName: string;
     willillDegreeName: string;
@@ -115,7 +120,7 @@ interface CpDetail {
   cardno?: string;
 }
 
-let cpDetail = ref<CpDetail>({});
+let cpDetail = ref<CpDetail & Partial<PatientModel>>({});
 async function getCpDetail(id: string) {
   await patientMethod(id).then((res2) => {
     cpDetail.value = res2;
@@ -127,6 +132,16 @@ interface PatientRecord {
   estimatedEndDate: string;
 }
 
+// 患者健康分析报告记录
+const patientHealthRecords = ref<HealthReportVO[]>([]);
+async function loadHealthRecords(patientId?: string) {
+  try {
+    const { data } = await getPatientHealthRecordsMethod(1, 100, { patientId: patientId ?? currentPatient.value?.patientId! });
+    patientHealthRecords.value = data
+  } catch (err) {
+    patientHealthRecords.value = []
+  }
+}
 const patientRecord = ref<PatientRecord[]>([]);
 // 获取患者调养记录
 function getPatientRecord(id: any) {
@@ -154,11 +169,12 @@ async function getCpRecordDetail(id: string) {
     form.healthAnalysisReport = res.healthAnalysisReport;
   });
 }
-async function getPatientList(id: string) {
+function getPatientList(id: string) {
   // console.log(id, '切换');
   if (id) {
     getCpDetail(id);
     loadTags(id);
+    loadHealthRecords(id);
     getPatientRecord(id);
   }
 }
@@ -191,10 +207,10 @@ onMounted(async () => {
 
 });
 // 患者标签
-const tags = ref<PatientTagModel>({ id: '', tags: [] });
+const patientTags = ref<PatientTagVO[]>([]);
 function loadTags(patientId: string) {
-  patientTags(patientId).then((res) => {
-    tags.value = res;
+  getPatientTagsMethod(patientId).then((res) => {
+    patientTags.value = res;
   });
 }
 
@@ -800,6 +816,103 @@ watch(showProjectPopover, (val) => {
     projectSearch.value = '';
   }
 });
+
+function openPatientTagEdit(event: MouseEvent) {
+  const width = 500;
+  const offset = 32;
+  const component = defineAsyncComponent(() => import('@/components/PatientTagEdit.vue'));
+  const id = `PatientTagEdit`;
+  VxeUI.modal.open({
+    id,
+    title: '标签',
+    type: 'modal',
+    position: {
+      top: event.pageY + offset,
+      left: event.pageX - width,
+    },
+    escClosable: true,
+    resize: true,
+    width,
+    minWidth: width,
+    mask: false,
+    slots: {
+      default() {
+        return h(component, {
+          id: currentPatient.value?.patientId!,
+          tags: patientTags.value,
+          onDestroy(values?: PatientTagVO[]) {
+            if (values) { patientTags.value = values; }
+            VxeUI.modal.close(id);
+          },
+        });
+      },
+    },
+  });
+}
+
+function openHistoryPreviewHandle() {
+  const data = currentPatient.value
+  const patient = { id: data?.patientId }
+  const report = { id: data?.healthAnalysisReportId }
+
+  const component = defineAsyncComponent(() => import('@/components/PatientHealthRecordPreview.vue'));
+  const id = `drawer:report-history:preview`;
+  const onDestroy = () => {
+    VxeUI.drawer.close(id);
+  };
+  onDestroy();
+  VxeUI.drawer.open({
+    id,
+    title: `健康档案`,
+    maskClosable: true,
+    escClosable: true,
+    padding: false,
+    width: window.innerWidth - 256,
+    slots: {
+      default() {
+        return h(component, {
+          patient,
+          report,
+          onDestroy,
+          onRefresh() {
+
+          },
+        });
+      },
+    },
+    onHide() {
+      VxeUI.modal.close();
+    },
+  });
+}
+
+function openPatientHealthRecord(row: { id: string }, showType: 'analysis' | 'scheme' = 'analysis') {
+  const component = defineAsyncComponent(() => import('@/components/ReportPreview.vue'));
+  const id = `drawer:report:preview`;
+  const onDestroy = () => {
+    VxeUI.drawer.close(id);
+  };
+  onDestroy();
+  VxeUI.drawer.open({
+    id,
+    mask: true,
+    lockView: false,
+    padding: false,
+    width: window.innerWidth - 256,
+    escClosable: true,
+    maskClosable: true,
+    title: {analysis: `健康分析报告`, scheme: `调理方案`}[showType],
+    slots: {
+      default() {
+        return h(component, {
+          reportId: row.id.toString(),
+          type: showType,
+          onDestroy,
+        });
+      },
+    },
+  });
+}
 </script>
 
 <template>
@@ -1079,30 +1192,43 @@ watch(showProjectPopover, (val) => {
       <a-result class="area" v-else style="background-color: #fff" status="warning" title="暂无数据" />
     </div>
     <!-- 右侧调养记录 -->
-    <div class="right-panel">
-      <PatientTagWidget style="min-height: 112px; flex: none" :dataset="tags" editable @refresh="loadTags(currentPatient?.patientId)" :data="currentPatient" />
-      <!-- <a-button
-        type="primary"
-        size="small"
-        :disabled="!reportId"
-        :loading="reportLoading || historyReportPreviewOpening"
-        @click="
-          historyReportPreviewOpening = true;
-          openHistoryPreviewHandle();
-        "
-      >
-        健康档案
-      </a-button> -->
+    <div class="right-panel flex flex-col overflow-hidden">
+      <section style="flex: 0 0 auto; max-height: 270px; overflow-y: auto;">
+        <div style="margin-top: -6px; padding-right: 8px;">
+          <label>标签:</label>
+          <a-tag v-for="tag in patientTags" :key="tag.id" :color="tag.color">{{ tag.name }}</a-tag>
+          <a-button type="link" @click="openPatientTagEdit($event)">
+            <template #icon>
+              <EditOutlined />
+            </template>
+          </a-button>
+        </div>
+      </section>
+      <section style="margin: 8px;">
+        <a-button type="primary" block @click="openHistoryPreviewHandle()">健康档案</a-button>
+      </section>
+      <div class="record-title">报告记录</div>
+      <section class="overflow-auto" style="flex: 4 4 auto; min-height: 240px;">
+        <div class="record-list">
+          <div class="record-item flex justify-between" v-for="item in patientHealthRecords" :key="item.id" @click="openPatientHealthRecord(item, 'analysis')">
+            {{ item.date }}
+            <a @click.stop="openPatientHealthRecord(item, 'scheme')">方案</a>
+          </div>
+          <div v-if="!patientRecord.length" style="padding-bottom: 8px; text-align: center; margin-top: 40px">暂无数据</div>
+        </div>
+      </section>
       <div class="record-title">调养记录</div>
-      <div class="record-list" v-if="patientRecord.length > 0">
-        <div class="record-item" v-for="item in patientRecord" :key="item.id" @click="openRecord(item)">{{ item.estimatedStartDate }}~{{ item.estimatedEndDate }}</div>
-      </div>
-      <div v-else style="padding-bottom: 8px; text-align: center; margin-top: 40px">暂无数据</div>
+      <section class="overflow-auto" style="flex: 4 4 auto; min-height: 240px;">
+        <div class="record-list">
+          <div class="record-item" v-for="item in patientRecord" :key="item.id" @click="openRecord(item)">{{ item.estimatedStartDate }}~{{ item.estimatedEndDate }}</div>
+          <div v-if="!patientRecord.length" style="padding-bottom: 8px; text-align: center; margin-top: 40px">暂无数据</div>
+        </div>
+      </section>
     </div>
   </div>
 </template>
 
-<style scoped>
+<style scoped lang="scss">
 .issue-service-page {
   display: flex;
   flex-direction: row;
@@ -1178,20 +1304,28 @@ watch(showProjectPopover, (val) => {
   flex: none;
   width: 190px;
   border-left: 1px solid #eee;
-  padding: 16px 8px 0 8px;
+  //padding: 16px 8px;
   background: #fafbfc;
   /* min-height: 100vh; */
   box-sizing: border-box;
+  > section {
+    margin: 16px 0;
+    padding-left: 8px;
+
+    .ant-tag {
+      margin-top: 6px;
+    }
+  }
 }
 .record-title {
   font-weight: bold;
-  margin-bottom: 8px;
   text-align: center;
 }
 .record-list {
   display: flex;
   flex-direction: column;
   gap: 8px;
+  padding-right: 8px;
 }
 .record-item {
   background: #fff;
@@ -1202,6 +1336,9 @@ watch(showProjectPopover, (val) => {
   font-size: 12px;
   font-weight: bold;
   cursor: pointer;
+  &:hover {
+    color: #1890ff;
+  }
 }
 .suggest-cw {
   color: #1890ff;

+ 1 - 1
src/request/api/patient.api.ts

@@ -64,7 +64,7 @@ export function patientMethod(id: string) {
  * @param id
  */
 export function patientTags(id: string) {
-  return request.Get<PatientTagModel, any[]>(`/fdhb-pc/patientInfoManage/getPatientTag`, {
+  return request.Get<PatientTagModel, any[]>(`/fdhb-pc/patientInfoManage/getPatientTag?old`, {
     hitSource: 'update-tags',
     params: { patientId: id },
     transform(data, headers) {

+ 1 - 1
src/request/api/report.api.ts

@@ -28,7 +28,7 @@ export function reportsMethod(patientId: string) {
       return data?.map(item => {
         return {
           ...item,
-          id: item.healthAnalysisReportId,
+          id: item.healthAnalysisReportId.toString(),
           time: item.time2,
         };
       }) ?? [];

+ 1 - 1
src/widgets/PatientHealthRecordsWidget.vue

@@ -32,7 +32,7 @@ interface Model extends SymptomItemVo {
 const grid = ref<VxeGridInstance>();
 const { loading, page, isLastPage } = usePagination((page, size) => getPatientHealthRecordsMethod(page, size, { patientId: props.patient.id }), {
   initialData: { total: 0, data: [] },
-  initialPage: 0,
+  initialPage: 1,
   initialPageSize: 100,
   append: true,
   watchingStates: [() => props.patient.id],