2 İşlemeler 2e40ec32de ... a67d5b305f

Yazar SHA1 Mesaj Tarih
  luyun a67d5b305f Merge branch 'master' of http://code.pacsonline.cn/zskk_bg/guochanhua 4 gün önce
  luyun 879daaa36c 增加医生端检查分享查看页面 4 gün önce

+ 4 - 2
jcjyhr/web/.env.development

@@ -17,5 +17,7 @@ VITE_BASE_PATH = './'
 # VITE_PROXY_URL = 'http://36.140.148.147:8001'
 # VITE_PROXY_URL = 'http://192.168.1.103:8000'
 # VITE_PROXY_URL = 'http://192.168.1.20:8000'
-VITE_PROXY_URL = 'http://localhost:812/'
-VITE_AXIOS_BASE_URL = 'http://localhost:812/'
+VITE_PROXY_URL = 'http://111.53.165.106:9605'
+VITE_AXIOS_BASE_URL = 'http://111.53.165.106:9605'
+# VITE_PROXY_URL = 'http://localhost:812/'
+# VITE_AXIOS_BASE_URL = 'http://localhost:812/'

+ 7 - 0
jcjyhr/web/src/api/backend/doctor.ts

@@ -24,6 +24,13 @@ export function getRecogViewDetail(params: object = {}) {
         method: 'post',
     })
 }
+export function getRecogViewHrDetail(params: object = {}) {
+    return createAxios({
+        url: '/zskk/hr/getRecogViewHrDetail',
+        data: params,
+        method: 'post',
+    })
+}
 
 
 //医生端 互认保存

+ 7 - 0
jcjyhr/web/src/router/static.ts

@@ -41,6 +41,13 @@ const staticRoutes: Array<RouteRecordRaw> = [
             title: pageTitle('recogView'),
         },
     },
+    {
+        path: '/ShareView',
+        component: () => import('/@/views/backend/ShareView/index.vue'),
+        meta: {
+            title: pageTitle('recogView'),
+        },
+    },
     // {
     //     // 会员登录页
     //     path: memberCenterBaseRoutePath + '/login',

+ 4 - 4
jcjyhr/web/src/views/backend/RecogView/components/table.vue

@@ -121,16 +121,16 @@
       <el-table-column prop="EXAM_ITEMNAME" label="项目名称" width="150" align="center" />
       <el-table-column prop="OBSERVATIONS_COMMENT" label="检查所见/影像所见" width="200" align="center">
         <template #default="{ row }">
-          <span v-if="!row.isCoExpanded && row.OBSERVATIONS_COMMENT.length > 40" v-html="(row.OBSERVATIONS_COMMENT.slice(0, 40) + '...')"></span>
+          <span v-if="!row.isCoExpanded && (row.OBSERVATIONS_COMMENT && row.OBSERVATIONS_COMMENT.length > 40)" v-html="(row.OBSERVATIONS_COMMENT.slice(0, 40) + '...')"></span>
           <span v-else v-html="row.OBSERVATIONS_COMMENT"></span>
-          <el-button v-if="!row.isCoExpanded && row.OBSERVATIONS_COMMENT.length > 40" type="text" @click="showFullContent(row, 'comment')">更多</el-button>
+          <el-button v-if="!row.isCoExpanded && (row.OBSERVATIONS_COMMENT && row.OBSERVATIONS_COMMENT.length > 40)" type="text" @click="showFullContent(row, 'comment')">更多</el-button>
         </template>
       </el-table-column>
       <el-table-column prop="OBSERVATIONS_RESULT" label="影像诊断/意见" width="200" align="center">
         <template #default="{ row }">
-          <span v-if="!row.isReExpanded && row.OBSERVATIONS_RESULT.length > 40" v-html="(row.OBSERVATIONS_RESULT.slice(0, 40) + '...')"></span>
+          <span v-if="!row.isReExpanded && (row.OBSERVATIONS_RESULT && row.OBSERVATIONS_RESULT.length > 40)" v-html="(row.OBSERVATIONS_RESULT.slice(0, 40) + '...')"></span>
           <span v-else v-html="row.OBSERVATIONS_RESULT"></span>
-          <el-button v-if="!row.isReExpanded && row.OBSERVATIONS_RESULT.length > 40" type="text" @click="showFullContent(row, 'result')">更多</el-button>
+          <el-button v-if="!row.isReExpanded && (row.OBSERVATIONS_RESULT && row.OBSERVATIONS_RESULT.length) > 40" type="text" @click="showFullContent(row, 'result')">更多</el-button>
         </template>
       </el-table-column>
       <el-table-column prop="HR_RANGE" label="互认范围" width="80" align="center" />

+ 111 - 0
jcjyhr/web/src/views/backend/ShareView/components/basein.vue

@@ -0,0 +1,111 @@
+<template>
+  <div class="basein-box">
+    <div class="row-bg" justify="space-between">
+      <div class="col-item">
+        <span class="label">主索引号:</span>
+        <span class="value">{{props.dataV.MPI}}</span>
+      </div>
+      <div class="col-item">
+        <span class="label">患者:</span>
+        <span class="value" style="color: var(--el-color-danger);font-weight: 800;font-size: 18px;">{{props.dataV.NAME}}</span>
+      </div>
+      <div class="col-item">
+        <span class="label">性别:</span>
+        <span class="value">{{props.dataV.GENDER}}</span>
+      </div>
+      <div class="col-item">
+        <span class="label">年龄:</span>
+        <span class="value">{{calculateAge(props.dataV.BIRTH_DATE)}}岁</span>
+      </div>
+      <div class="col-item">
+        <span class="label">身份证:</span>
+        <span class="value" style="color: var(--el-color-danger);font-weight: 800;font-size: 18px;">{{props.dataV.ID_CARDNUM}}</span>
+      </div>
+      <!-- <div class="col-item">
+        <span class="label">就诊时间:</span>
+        <span class="value">{{props.dataV.MEDICAL_INFORMATION?.ENCOUNTER_DATE}}</span>
+      </div>
+      <div class="col-item">
+        <span class="label">诊断:</span>
+        <span class="value">{{props.dataV.DIAGNOSES?.DIAGNOSENAME}}</span>
+      </div>
+      <div class="col-item">
+        <span class="label" style="width: 52px;">主诉:</span>
+        <span class="value">{{props.dataV.MEDICAL_INFORMATION?.CHIEFCOMPLAINT}}</span>
+      </div> -->
+      <slot></slot>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue'
+import { useI18n } from 'vue-i18n'
+const { t } = useI18n()
+interface Props {
+  dataV: any
+}
+const props = withDefaults(defineProps<Props>(), {
+    dataV: []
+})
+const calculateAge = (birthDate: string) => {
+    const birthday = new Date(birthDate);
+    const today = new Date();
+    let age = today.getFullYear() - birthday.getFullYear();
+    const m = today.getMonth() - birthday.getMonth();
+    if (m < 0 || (m === 0 && today.getDate() < birthday.getDate())) {
+        age--;
+    }
+    return age;
+}
+</script>
+
+<style scoped lang="scss">
+.basein-box  {
+    box-sizing: border-box;
+    width: 100%;
+    max-width: 100%;
+    background-color: var(--ba-bg-color-overlay);
+    border: 1px solid var(--ba-border-color);
+    border-bottom: none;
+    padding: 15px 15px 0;
+    font-size: 14px;
+    border-radius: 6px;
+    margin: 8px 0;
+    .row-bg {
+      display: flex;
+      flex-wrap: wrap;
+    }
+    .col-item {
+      width: 20%;
+      margin-bottom: 15px;
+      font-size: var(--el-font-size-medium);
+    }
+    .grid-content {
+      display: flex;
+      margin-bottom: 15px;
+      font-size: var(--el-font-size-medium);
+    }
+    .col-item {
+      display: flex;
+      align-items: center;
+    }
+    .label{
+      // width: 70px;
+      width: auto;
+      display: inline-block;
+      margin-right: 5px;
+    }
+    .value {
+      font-weight: 600;
+      white-space: nowrap; 
+      overflow: hidden; 
+      text-overflow: ellipsis;
+    }
+}
+// .basein-box {
+//   background-color: var(--ba-vars-color-tree);
+//   border: 1px solid var(--ba-vars-color-formlabel);
+//   padding: 30px 15px;
+// }
+</style>

+ 528 - 0
jcjyhr/web/src/views/backend/ShareView/components/table.vue

@@ -0,0 +1,528 @@
+<!-- eslint-disable vue/no-mutating-props -->
+<template>
+  <div class="ba-table-box">
+    <div class="table-header-operate">
+      <!-- <div style="flex: 1;">
+        <div class="ba-table-title">{{localData.tableData.LAB_ITEMNAME?timeFormat(localData.tableData.REPORTTIME, 'yyyy.mm.dd hh:MM') + ' ' + localData.tableData.LAB_ITEMNAME:'检查项目'}}</div>
+        <div v-if="localData.tableData.LAB_ITEMNAME_TYPE_CODE == '2'" >
+          <p>鉴定结果: {{localData.tableData.INSPECT_REPORT_ITEMS[0].LAB_ITEMDETAILINTERPRETATION}}</p>
+          <p>药敏结果:{{localData.tableData.INSPECT_REPORT_ITEMS[0].LAB_ITEMDETAILINTERPRETATION_BIA}}</p>
+        </div>
+      </div> -->
+      <div class="ba-table-title-box">
+        <div class="ba-table-title-top">
+          <el-tooltip
+            class="item"
+            effect="dark"
+            :content="localData.tableData.LAB_ITEMNAME?timeFormat(localData.tableData.REPORTTIME, 'yyyy.mm.dd hh:MM') + ' ' + localData.tableData.LAB_ITEMNAME:'检查项目'"
+            placement="top-start"
+            >
+            <div class="ba-table-title">{{localData.tableData.LAB_ITEMNAME?timeFormat(localData.tableData.REPORTTIME, 'yyyy.mm.dd hh:MM') + ' ' + localData.tableData.LAB_ITEMNAME:'检查项目'}}</div>
+          </el-tooltip>
+          <el-tag v-if="localData.tableData.INSPECT_REPORT_ITEMS" :key="localData.tableData.HR_RANGE" type="success" effect="dark">{{localData.tableData.HR_RANGE}}</el-tag>
+        </div>
+        <div v-if="localData.tableData.LAB_ITEMNAME_TYPE_CODE == '2'" >
+          <p>鉴定结果: {{localData.tableData.INSPECT_REPORT_ITEMS[0].LAB_ITEMDETAILINTERPRETATION}}</p>
+          <p>药敏结果:{{localData.tableData.INSPECT_REPORT_ITEMS[0].LAB_ITEMDETAILINTERPRETATION_BIA}}</p>
+        </div>
+      </div>
+      <div class="table-right-button table-header">
+        <!-- LAB_ITEMNAME_TYPE_CODE == '1'是检验项目  2是检验项目-微生物 === 大项 互认项目编码存在 或者 微生物-->
+        <el-tooltip
+          class="item"
+          effect="dark"
+          :content="localData.tableData.BHR_REASON?localData.tableData.BHR_REASON:initCascaderContent(localData.tableData.HR_STATUS)"
+          placement="top-start"
+          v-if="(localData.tableData.LAB_ITEMNAME_TYPE_CODE == '1' && localData.tableData.LAB_HR_ITEMLNAME_CODE) || localData.tableData.LAB_ITEMNAME_TYPE_CODE == '2'"
+        >
+          <!-- <el-button>1212</el-button> -->
+           <div class="hr-select-box">
+            <el-cascader v-model="localData.tableData.cascaderValue" :options="cascaderOptions" @change="onChangeField(localData.tableData, 0, 2)" />
+           </div>
+        </el-tooltip>
+        <!-- <el-button v-if="localData.tableData.LAB_ITEMNAME_TYPE_CODE !== '2'" type="primary" :color="'var(--ba-vars-color-main-primary)'" @click="handleCopy">复制</el-button> -->
+        <el-button v-if="localData.tableData.INSPECT_REPORT_ITEMS" type="primary" :color="'var(--ba-vars-color-main-primary)'" @click="handleReportView">查看报告</el-button>
+        <el-button v-if="localData.tableData.INSPECT_REPORT_ITEMS" type="primary" :color="'var(--ba-vars-color-main-primary)'" @click="handleDownload">下载报告</el-button>
+      </div>
+    </div>
+    <el-table
+        class="ba-data-table w100"
+        v-if="localData.tableData.LAB_ITEMNAME_TYPE_CODE == '1'" 
+        :data="localData.tableData.INSPECT_REPORT_ITEMS" 
+        header-cell-class-name="table-header-cell" 
+        stripe
+        style="width: 100%"
+        @selection-change="onSelectionChange"
+    >
+      <!-- <el-table-column type="selection" width="55" /> -->
+      <el-table-column type="index" label="序号" width="70" align="center" />
+      <el-table-column prop="LAB_ITEMDETAILNAME_EN" label="代号" width="90" align="center" />
+      <el-table-column prop="LAB_ITEMDETAILNAME" label="项目名称" width="180" align="center" />
+      <el-table-column prop="LAB_ITEMDETAILVALUE" label="测量值" width="180" align="center">
+        <template #default="scope">
+          <span :class="[scope.row.LAB_ITEMDETAILINTERPRETATION?'ba-table-row-light':'']">{{scope.row.LAB_ITEMDETAILVALUE}}</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="LAB_ITEMDETAILINTERPRETATION" label="结果" width="180" align="center">
+        <template #default="scope">
+          <span :class="[scope.row.LAB_ITEMDETAILINTERPRETATION?'ba-table-row-light':'']">{{scope.row.LAB_ITEMDETAILINTERPRETATION}}</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="LAB_ITEMDETAILRANGE" label="参考值范围" align="center" />
+      <el-table-column prop="LAB_ITEMDETAILSPEC" label="结果计量单位" align="center" />
+      <el-table-column prop="RECOG_STATUS" label="互认标识" align="center" />
+      <!-- <el-table-column v-if="checkData()" prop="LAB_ITEMDETAILNAME_CODE" label="互认结果" width="180" showOverflowTooltip align="center">
+        <template #default="scope">
+          <el-tooltip
+            class="item"
+            effect="dark"
+            :content="scope.row.BHR_REASON?scope.row.BHR_REASON:initCascaderContent(scope.row.HR_STATUS)"
+            placement="top-start"
+          >
+            <div class="hr-select-box"> 
+              <el-cascader v-model="scope.row.cascaderValue" :options="cascaderOptions" @change="onChangeField(scope.row, scope.$index, 2)" />
+            </div>
+          </el-tooltip>
+        </template>
+      </el-table-column> -->
+      
+    </el-table>
+    <div v-if="localData.tableData.LAB_ITEMNAME_TYPE_CODE == '2'">
+      <el-table
+        class="ba-data-table w100"
+        :data="localData.tableData.INSPECT_REPORT_ITEMS" 
+        header-cell-class-name="table-header-cell" 
+        stripe
+        style="width: 100%"
+      >
+        <el-table-column type="index" label="序号" width="70" align="center" />
+        <el-table-column prop="LAB_ITEMDETAILNAME_EN" label="代号" width="90" align="center" />
+        <el-table-column prop="LAB_ITEMDETAILNAME" label="抗生素" width="180" align="center" />
+        <el-table-column prop="LAB_ITEMDETAILNAME_EN" label="英文名" align="center" />
+        <el-table-column prop="KB" label="KB*" align="center" />
+        <el-table-column prop="MIC" label="MIC*" align="center" />
+        <el-table-column prop="LAB_ITEMDETAILINTERPRE" label="敏感度" align="center" />
+      </el-table>
+      <p style="padding: 12px;font-weight: 600;color: var(--el-text-color-primary);">评语:{{localData.tableData.REPORT_COMMENT}}</p>
+    </div>
+    
+    <el-table 
+      class="ba-data-table w100"
+      v-if="localData.examTableData.length" 
+      :data="localData.examTableData" 
+      header-cell-class-name="table-header-cell" 
+      stripe 
+      style="width: 100%"
+      @selection-change="onExamSelectionChange"
+      >
+      <!-- <el-table-column type="selection" width="55" /> -->
+      <el-table-column type="index" label="序号" width="70" align="center" />
+      <el-table-column prop="STUDYTIME" label="检查时间" width="100" align="center" />
+      <el-table-column prop="EXAM_ITEMNAME" label="项目名称" width="150" align="center" />
+      <el-table-column prop="OBSERVATIONS_COMMENT" label="检查所见/影像所见" width="200" align="center">
+        <template #default="{ row }">
+          <span v-if="!row.isCoExpanded && (row.OBSERVATIONS_COMMENT && row.OBSERVATIONS_COMMENT.length > 40)" v-html="(row.OBSERVATIONS_COMMENT.slice(0, 40) + '...')"></span>
+          <span v-else v-html="row.OBSERVATIONS_COMMENT"></span>
+          <el-button v-if="!row.isCoExpanded && (row.OBSERVATIONS_COMMENT && row.OBSERVATIONS_COMMENT.length > 40)" type="text" @click="showFullContent(row, 'comment')">更多</el-button>
+        </template>
+      </el-table-column>
+      <el-table-column prop="OBSERVATIONS_RESULT" label="影像诊断/意见" width="200" align="center">
+        <template #default="{ row }">
+          <span v-if="!row.isReExpanded && (row.OBSERVATIONS_RESULT && row.OBSERVATIONS_RESULT.length > 40)" v-html="(row.OBSERVATIONS_RESULT.slice(0, 40) + '...')"></span>
+          <span v-else v-html="row.OBSERVATIONS_RESULT"></span>
+          <el-button v-if="!row.isReExpanded && (row.OBSERVATIONS_RESULT && row.OBSERVATIONS_RESULT.length > 40)" type="text" @click="showFullContent(row, 'result')">更多</el-button>
+        </template>
+      </el-table-column>
+      <el-table-column prop="HR_RANGE" label="互认范围" width="80" align="center" />
+      <el-table-column prop="LAB_ITEMDETAILSPEC" label="检查结果类别" align="center" />
+      <!-- <el-table-column v-if="props.from != 'patientTable'" prop="EXAM_ITEMNAME_CODE" label="互认结果" width="180" showOverflowTooltip align="center">
+        <template #default="scope">
+          <el-tooltip
+            class="item"
+            effect="dark"
+            :content="scope.row.BHR_REASON?scope.row.BHR_REASON:initCascaderContent(scope.row.HR_STATUS)"
+            placement="top-start"
+          >
+            <div class="hr-select-box"> 
+              <el-cascader v-model="scope.row.cascaderValue" :options="cascaderOptions" @change="onChangeFieldExam(scope.row, scope.$index, 1)" />
+            </div>
+          </el-tooltip>
+        </template>
+      </el-table-column> -->
+      <el-table-column label="检查报告/影像图片" min-width="120" align="center">
+        <template #default="scope">
+          <el-button link type="primary" size="small" @click="handleReportView(scope.row)">
+            报告查看
+          </el-button>
+          <el-button link type="primary" size="small" @click="goImageView">影像查看</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, reactive, inject, toRaw, onMounted} from 'vue'
+import { getAttachment } from '/@/api/backend/institution'
+import { useI18n } from 'vue-i18n'
+import { timeFormat } from '/@/utils/common'
+import { Session } from '/@/utils/storage'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import examReport from '/@/assets/examreport.png'
+const { t } = useI18n()
+const dialogVisible:any = inject('dialogVisible')
+let HR_RECORDS = ref<any>([])
+defineOptions({
+    name: 'hospital/detail',
+})
+interface Props {
+  tableData?: any
+  examTableData?: any
+  hrrecords: any
+  from: string
+  medicalInformation: any
+  patientCode: string
+}
+const props = withDefaults(defineProps<Props>(), {
+    tableData: {},
+    examTableData: [],
+    hrrecords: [],
+    from: '',
+    medicalInformation: {},
+    patientCode: ''
+})
+const cascaderOptions = [
+    {
+        value: '0',
+        label: '请互认符合的项目',
+    },
+    {
+        value: '1',
+        label: '互认',
+    },
+    {
+        value: '2',
+        label: '不互认',
+        children: Session.get('noHrReasonList')
+    }
+]
+// 互认结果 鼠标悬浮内容
+const initCascaderContent = (code = '0') => {
+    const itemWithValue2 = cascaderOptions.find((item) => item.value == code )
+    return itemWithValue2?.label
+}
+const getChangeCascaderContent = (value:any, options:any, arr = []) => {
+    options.forEach((item: any) => {
+        value.forEach((val:any) => {
+            if (item.value === val) {
+                arr.push(item.label);
+                if (item.children) {
+                    getChangeCascaderContent(value, item.children, arr);
+                }
+            }
+        });
+    });
+    return arr.join('/');
+}
+const checkData = () => {  //检验细项 是否展示互认结果列 (大项不存在互认项目编码)
+    const hasCode = localData.tableData.INSPECT_REPORT_ITEMS.some((item: any) => !localData.tableData.LAB_HR_ITEMLNAME_CODE && item.LAB_HR_ITEMDETAILNAME_CODE);
+    return hasCode
+}
+// 查询不互认原因字典
+const noHrReasonList = Session.get('noHrReasonList')
+const findNoHrReasonList = (code: string) => {
+    const result = noHrReasonList?.find((item: any) => item.value === code);
+    if (result) {
+        return result.label
+    } else {
+        return ''
+        console.log('No match found');
+    }
+}
+// 重新初始化 检查检验 初始数据
+const localData = reactive<{
+  tableData: any;
+  examTableData: []
+}>({
+    tableData: props.tableData,
+    examTableData: props.examTableData
+});
+const formatTableData = () => {
+    if(localData.tableData && localData.tableData.LAB_ITEMNAME_TYPE_CODE == '2' && props.hrrecords){ //微生物
+        const findMatchingItem = props.hrrecords.find((it: { ITEMNAMECODE: string; }) => it.ITEMNAMECODE === localData.tableData.LAB_HR_ITEMLNAME_CODE);
+        localData.tableData = {
+            ...localData.tableData,
+            HR_STATUS: findMatchingItem?(findMatchingItem.HR_STATUS?findMatchingItem.HR_STATUS:'0'):'0',
+            BHR_REASON: findMatchingItem?(findMatchingItem.BHR_REASON ? findMatchingItem.BHR_REASON: initCascaderContent(findMatchingItem?.HR_STATUS)): initCascaderContent(findMatchingItem?.HR_STATUS),
+            cascaderValue: findMatchingItem?(findMatchingItem.BHR_CODE ? [findMatchingItem.HR_STATUS,findMatchingItem.BHR_CODE]:[findMatchingItem.HR_STATUS]):['0']
+        }
+    }else if(localData.tableData && localData.tableData.LAB_ITEMNAME_TYPE_CODE == '1' && props.hrrecords){
+        const INSPECTREPORTITEMS = localData.tableData.INSPECT_REPORT_ITEMS.map((item: any) => {
+            const findMatchingItem = props.hrrecords.find((it: { ITEMNAMECODE: string; }) => it.ITEMNAMECODE === item.LAB_ITEMDETAILNAME_CODE);
+            return {
+                ...item,
+                HR_STATUS: findMatchingItem?(findMatchingItem.HR_STATUS?findMatchingItem.HR_STATUS:'0'):'0',
+                BHR_REASON: findMatchingItem?(findMatchingItem.BHR_REASON ? findMatchingItem.BHR_REASON: initCascaderContent(findMatchingItem?.HR_STATUS)): initCascaderContent(findMatchingItem?.HR_STATUS),
+                cascaderValue: findMatchingItem?(findMatchingItem.BHR_CODE ? [findMatchingItem.HR_STATUS,findMatchingItem.BHR_CODE]:[findMatchingItem.HR_STATUS]):['0']
+            }
+        })
+        localData.tableData = {
+            ...localData.tableData,
+            INSPECT_REPORT_ITEMS: INSPECTREPORTITEMS
+        }
+    }
+}
+const formatExamTableData = () => {
+    localData.examTableData = props.examTableData.map((item: any) => {
+        const findMatchingItem = props.hrrecords.find((it: { ITEMNAMECODE: string; }) => it.ITEMNAMECODE === item.EXAM_ITEMNAME_CODE);
+        return {
+            ...item,
+            HR_STATUS: findMatchingItem?(findMatchingItem.HR_STATUS?findMatchingItem.HR_STATUS:'0'):'0',
+            BHR_REASON: findMatchingItem?(findMatchingItem.BHR_REASON ? findMatchingItem.BHR_REASON:initCascaderContent(findMatchingItem?.HR_STATUS)): initCascaderContent(findMatchingItem?.HR_STATUS),
+            cascaderValue: findMatchingItem?(findMatchingItem.BHR_CODE ? [findMatchingItem.HR_STATUS,findMatchingItem.BHR_CODE]:[findMatchingItem.HR_STATUS]):['0']
+        }
+    })
+}
+onMounted(()=> {
+    formatTableData()
+    formatExamTableData()
+})
+
+// 前端存储 检查检验互认记录项
+const currentIndex = ref(-1) // 检验 当前操作细项索引
+const currentIndexExam = ref(-1) // 检查 当前操作细项索引
+const clickOragin = ref(1) // 操作来源 1检查 2检验微生物
+const currentRow = ref({}) // 当前细项行数据
+const DEFAULT_HR_RECORDS = {
+    ORGCODE: props.medicalInformation.ORGCODE,
+    ORGNAME: props.medicalInformation.ORGNAME,
+}
+const onChangeField = (row: TableRow[], index: any, oragin: number) => { // 检验 互认结果下拉 更改项
+    currentIndex.value = index
+    clickOragin.value = oragin
+    currentRow.value = row
+    // LAB_ITEMNAME_TYPE_CODE == '1'是检验项目  2是检验项目-微生物
+    if((localData.tableData.LAB_ITEMNAME_TYPE_CODE == '1' && localData.tableData.LAB_HR_ITEMLNAME_CODE) || localData.tableData.LAB_ITEMNAME_TYPE_CODE == '2'){// 大项 检验项目编码存在 或者 微生物
+        const hrRecords = Session.get('HR_RECORDS')
+        const isNameCode = hrRecords && hrRecords.some((item:any) => item.ITEMNAMECODE == localData.tableData.LAB_ITEMNAME_CODE)
+        if(hrRecords && isNameCode){
+            hrRecords.forEach((item:any) => {
+                if(clickOragin.value == 2 && item.ITEMNAMECODE == localData.tableData.INSPECT_REPORT_ITEMS[currentIndex.value].LAB_ITEMDETAILNAME_CODE){//对比项目编码  一致 更改互认记录数据
+                    item.HR_STATUS = localData.tableData.cascaderValue[0],//互认状态
+                    item.BHR_CODE = localData.tableData.cascaderValue[1], //不互认原因编码
+                    item.BHR_REASON =  findNoHrReasonList(localData.tableData.cascaderValue[1]) //不互认原因
+                   
+                }
+            }) 
+            Session.set('HR_RECORDS', hrRecords)
+            return
+        }
+        saveHrRecords(localData.tableData.cascaderValue[0], localData.tableData.cascaderValue[1])
+    }else {
+        // eslint-disable-next-line vue/no-mutating-props
+        // eslint-disable-next-line vue/no-mutating-props
+        localData.tableData.INSPECT_REPORT_ITEMS[currentIndex.value].BHR_REASON = getChangeCascaderContent(localData.tableData.INSPECT_REPORT_ITEMS[currentIndex.value].cascaderValue, cascaderOptions);
+        initHrRecords(localData.tableData.INSPECT_REPORT_ITEMS[currentIndex.value].LAB_ITEMDETAILNAME_CODE)
+    }
+}
+ 
+const initHrRecords = ( nameCode: string) => {
+    const hrRecords = Session.get('HR_RECORDS')
+    const isNameCode = hrRecords && hrRecords.some((item:any) => item.ITEMNAMECODE == nameCode)
+    if(hrRecords && isNameCode){
+        hrRecords.forEach((item:any) => {
+            if(clickOragin.value == 2 && item.ITEMNAMECODE == localData.tableData.INSPECT_REPORT_ITEMS[currentIndex.value].LAB_ITEMDETAILNAME_CODE){//对比项目编码  一致 更改互认记录数据
+                // hrRecords[index]
+                item.HR_STATUS = localData.tableData.INSPECT_REPORT_ITEMS[currentIndex.value].cascaderValue[0],//互认状态
+                item.BHR_CODE = localData.tableData.INSPECT_REPORT_ITEMS[currentIndex.value].cascaderValue[0] == '2' ?localData.tableData.INSPECT_REPORT_ITEMS[currentIndex.value].cascaderValue[1] : '', //不互认原因编码
+                item.BHR_REASON = localData.tableData.INSPECT_REPORT_ITEMS[currentIndex.value].cascaderValue[0] == '2' ? findNoHrReasonList(localData.tableData.INSPECT_REPORT_ITEMS[currentIndex.value].cascaderValue[1]) : '' //不互认原因
+            }else if(clickOragin.value == 1 && item.ITEMNAMECODE == localData.examTableData[currentIndexExam.value].EXAM_ITEMNAME_CODE){
+                item.HR_STATUS = localData.examTableData[currentIndexExam.value].cascaderValue[0],//互认状态
+                item.BHR_CODE = localData.examTableData[currentIndexExam.value].cascaderValue[0] =='2'?localData.examTableData[currentIndexExam.value].cascaderValue[1]:'', //不互认原因编码
+                item.BHR_REASON = localData.examTableData[currentIndexExam.value].cascaderValue[0] =='2'?findNoHrReasonList(localData.examTableData[currentIndexExam.value].cascaderValue[1]): '' //不互认原因
+            }
+        }) 
+        Session.set('HR_RECORDS', hrRecords)
+        return
+    }
+    saveHrRecords(clickOragin.value == 2?localData.tableData.INSPECT_REPORT_ITEMS[currentIndex.value].cascaderValue[0]:localData.examTableData[currentIndexExam.value].cascaderValue[0])
+}
+const saveHrRecords = (status: string, code?: any) => { 
+    HR_RECORDS.value = Session.get('HR_RECORDS')||[]
+    HR_RECORDS.value.push({
+        PATIENT_CODE: props.medicalInformation.PATIENT_CODE,
+        // PATIENT_CODE:props.patientCode,
+        ...DEFAULT_HR_RECORDS,
+        REPORTID:clickOragin.value == 1 ? localData.examTableData[currentIndexExam.value].REPORTID: localData.tableData.REPORTID,// 报告id
+        ITEMNAMECODE: clickOragin.value == 1 ? localData.examTableData[currentIndexExam.value].EXAM_ITEMNAME_CODE: localData.tableData.INSPECT_REPORT_ITEMS[currentIndex.value].LAB_ITEMDETAILNAME_CODE,//项目编码
+        ITEMNAME: clickOragin.value == 1 ? localData.examTableData[currentIndexExam.value].EXAM_ITEMNAME : localData.tableData.INSPECT_REPORT_ITEMS[currentIndex.value].LAB_ITEMDETAILNAME, //项目名称
+        // REPORT_CODE: clickOragin.value == 1 ? localData.examTableData[currentIndexExam.value].EXAM_REPORT_CODE : localData.tableData.INSPECT_REPORT_CODE, //报告名称
+        DOCTOR_NAME: clickOragin.value == 1 ? localData.examTableData[currentIndexExam.value].PRACTITIONERNAME : localData.tableData.PRACTITIONERNAME,
+        HR_STATUS: status,//互认状态
+        BHR_CODE: getBhrCode(status, code), //不互认原因编码
+        ITEMNAMETYPE: clickOragin.value, //项目类型
+        BHR_REASON:  getBhrReason(status, code)//不互认原因
+    })
+    Session.set('HR_RECORDS', HR_RECORDS.value)
+}
+const getBhrCode = (status: string, code: string) => {
+    if(status != '2') {
+        return ''
+    }else{
+        return clickOragin.value == 1?localData.examTableData[currentIndexExam.value].cascaderValue[1]:(code?code:localData.tableData.INSPECT_REPORT_ITEMS[currentIndex.value].cascaderValue[1])
+    }
+} 
+const getBhrReason = (status: string, code: string) => {
+    if(status != '2') {
+        return ''
+    }else{
+        return clickOragin.value == 1?findNoHrReasonList(localData.examTableData[currentIndexExam.value].cascaderValue[1]):(code?findNoHrReasonList(code):findNoHrReasonList(localData.tableData.INSPECT_REPORT_ITEMS[currentIndex.value].cascaderValue[1]))
+    }
+}
+const onChangeFieldExam = (row: TableRow[], index: any, origin: number) => { //检查 互认结果下拉 更改项
+    currentIndexExam.value = index
+    clickOragin.value = origin
+    currentRow.value = row
+    // eslint-disable-next-line vue/no-mutating-props
+    // eslint-disable-next-line vue/no-mutating-props
+    localData.examTableData[currentIndexExam.value].BHR_REASON = getChangeCascaderContent(localData.examTableData[currentIndexExam.value].cascaderValue, cascaderOptions);
+    initHrRecords(localData.examTableData[currentIndexExam.value].EXAM_ITEMNAME_CODE)
+}
+
+// 复制功能 --------
+const copyMessage = ref('') //项目名称
+// 检验
+const onSelectionChange = (selection: TableRow[]) => { 
+    const currentSelect = toRaw(selection)
+    copyMessage.value = currentSelect.map((item: any) => item.LAB_ITEMDETAILNAME).join(',');
+}
+// 检查
+const onExamSelectionChange = (selection: TableRow[]) => {
+    const currentSelect = toRaw(selection)
+    copyMessage.value = currentSelect.map((item: any) => item.EXAM_ITEMNAME).join(',');
+}
+const handleCopy = async () => {
+    if(!copyMessage.value){
+        ElMessage({
+            message: '请先选择要复制的内容!',
+            type: 'error',
+        })
+        return
+    }
+    try {
+        const input = document.createElement('input');
+        input.setAttribute('value', copyMessage.value);
+        document.body.appendChild(input);
+        input.select();
+        document.execCommand('copy');
+        document.body.removeChild(input);
+        ElMessage({
+            message: '复制成功:' + copyMessage.value,
+            type: 'success',
+        });
+    } catch (e) {
+        console.error('复制失败:', e);
+    }
+};
+
+// 报告查看
+const handleReportView = (row: TableRow) => {
+    fetchGetAttachment(row.EXAM_REPORT_CODE)
+}
+const fetchGetAttachment = (code: string) => {
+    // getAttachment({report_code: code}).then(res => {
+    //     res.data && dialogVisible(res.data)
+    // })
+    dialogVisible(examReport)
+}
+const goImageView = () => { //影像查看
+    window.open('http://aipacsview.pacsonline.cn/#/pc?studyurl=https%3A%2F%2Fquery.pacsonline.cn%2Fquery%2F%3Faddress%3D&study_id=600162858d43dfc92c107759ecdb030b&node_type=1&node_type=1&version=V4.0.0.0')
+}
+// 下载报告
+const handleDownload = () => {
+    ElMessageBox.alert('To do...', '', {
+        confirmButtonText: '确定',
+    })
+}
+const showFullContent = (row:any, type: string) => {
+    if(type == 'comment') {
+        row.isCoExpanded = !row.isCoExpanded;
+    }else {
+        row.isReExpanded = !row.isReExpanded;
+    }
+}
+</script>
+
+<style scoped lang="scss">
+.ba-data-table :deep(.el-button + .el-button) {
+    margin-left: 6px;
+}
+.ba-data-table :deep(.table-header-cell) .cell {
+    color: var(--el-text-color-primary);
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+}
+.ba-table-box {
+  background-color: var(--ba-bg-color-overlay);
+  margin-top: var(--ba-main-space);
+}
+.ba-table-title {
+  width: 18%;
+  padding: 10px;
+  border-top-left-radius: 20px;
+  color: var(--el-bg-color);
+  background-color: var(--ba-vars-color-main-primary);
+  font-size: var(--el-font-size-base);
+  // display: flex;
+  // align-items: center;
+  // justify-content: center;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  text-align: center;
+  margin-right: 12px;
+}
+.ba-table-row-light {
+  color: var(--el-color-danger);
+}
+.table-header-operate {
+  display: flex;
+  justify-content: space-between;
+  align-items: flex-end;
+  .ba-table-title-box {
+      display: flex;
+      flex-direction: column;
+      width: 70%;
+
+    .ba-table-title-top {
+      display: flex;
+      flex-direction: row;
+      align-items: center;
+    }
+    p {
+      line-height: 24px;
+      font-weight: 600; 
+      color: var(--el-text-color-primary);
+      padding-left: 2px;
+    }
+  }
+  // p {
+  //   // padding: 12px; 
+  //   line-height: 24px;
+  //   font-weight: 600; 
+  //   color: var(--el-text-color-primary);
+  //   padding-left: 2px;
+  // }
+}
+.el-cascader {
+  max-width: 250px; /* 根据需要调整宽度 */
+}
+.hr-select-box {
+  display: inline-block;
+  margin-right: 12px;
+}
+.table-right-button {
+  margin-bottom: 8px;
+}
+</style>

+ 321 - 0
jcjyhr/web/src/views/backend/ShareView/index.vue

@@ -0,0 +1,321 @@
+<template>
+  <el-container class="layout-container">
+    <el-container class="content-wrapper">
+      <el-main class="layout-main">
+        <el-scrollbar class="layout-main-scrollbar" :style="layoutMainScrollbarStyle" ref="layoutMainScrollbarRef" @scroll="handleScroll">
+          <div class="default-main ba-table-box main-scroll" v-loading="loading">
+            <Basein :dataV="patientData" />
+            <div class="doctor-tabs-box">
+              <div class="institution-name">就诊信息</div>
+              <el-tabs type="card" class="demo-tabs">
+                <el-tab-pane v-for="(i, index) in resData" :key="index">
+                  <template #label>
+                    <div class="custom-tabs-label">
+                      <span class="time">{{i.MEDICAL_INFORMATION.ENCOUNTER_DATE}}</span>
+                      <span class="name">&nbsp;&nbsp;{{i.MEDICAL_INFORMATION.ORGNAME}}</span>
+                      <div>
+                        <span class="label">诊 断:</span>
+                        <span>{{i.MEDICAL_INFORMATION.DIAGNOSENAME}}</span>
+                      </div>
+                      <div>
+                        <span class="label">主 诉:</span>
+                        <span>{{i.MEDICAL_INFORMATION.CHIEFCOMPLAINT}}</span>
+                      </div>
+                      <div>
+                        <span class="label">就诊科室:</span>
+                        <span>{{i.MEDICAL_INFORMATION.DEPTNAME}}</span>
+                      </div>
+                      <div style="display: flex;">
+                        <span class="label">检查项目:</span>
+                        <!-- <span class="content">{{i.EXAM_REPORTS[index].EXAM_ITEMNAME}}</span> -->
+                        <span class="content" >{{i.EXAM_REPORTS.map((item: any) => item.EXAM_ITEMNAME).join(',')}}</span>
+                      </div>
+                      <div style="display: flex;">
+                        <span class="label">检验项目:</span>
+                        <!-- <span class="content">{{i.INSPECT_REPORTS.map((item: any) => item.INSPECT_REPORT_ITEMS).join(',')}}</span> -->
+                        <span class="content">{{stringProject(i.INSPECT_REPORTS)}}</span>
+                      </div>
+                    </div>
+                  </template>
+                  <!-- 检验 -->
+                  <div :class="['anchor-box', scrollTop >= 270 ? 'fixed' : '']">
+                    <div :class="{ active: index === activeIndex, 'anchor-item': true }" v-for="(item, index) in i.INSPECT_REPORTS" :key="index" @click="scrollToSection(index)">{{item.LAB_ITEMNAME}}</div>
+                  </div>
+                  <template v-for="(item, index1) in i.INSPECT_REPORTS" :key="index1">
+                    <Table :tableData="item" :hrrecords="i.HR_RECORDS" :medicalInformation="i.MEDICAL_INFORMATION" :patientCode="patientData.PATIENT_CODE" from="hrMyTable" :id="`anchor${index}`"/>
+                  </template>
+                  <Table :examTableData="i.EXAM_REPORTS" :hrrecords="i.HR_RECORDS" :medicalInformation="i.MEDICAL_INFORMATION" :patientCode="patientData.PATIENT_CODE" from="hrMyTable" />
+                </el-tab-pane>
+              </el-tabs>
+            </div>
+            
+            <el-dialog
+              class="ba-operate-dialog"
+              :close-on-click-modal="false"
+              :model-value="dialogVisible"
+              @close="dialogVisible = false"
+              width="50%"
+            >
+              <el-scrollbar v-loading="!dialogVisible" class="ba-table-form-scrollbar">
+                  <div>
+                    <el-image
+                      v-if="fileType === 'image'"
+                      :src="reportSrc"
+                      fit="cover"
+                      :style="{ width: '100%', height: 'auto' }"
+                    ></el-image>
+                    <embed
+                      v-else-if="fileType === 'pdf'"
+                      :src="reportSrc"
+                      type="application/pdf"
+                      width="100%"
+                      height="auto"
+                    />
+                  </div>
+              </el-scrollbar>
+          </el-dialog>
+        </div>
+        </el-scrollbar>
+        <!-- <div style="text-align: center;">
+          <el-button type="primary" :color="'var(--ba-vars-color-main-primary)'" @click="saveHr">保存互认</el-button>
+        </div> -->
+      </el-main>
+    </el-container>
+  </el-container>
+</template>
+
+<script setup lang="ts">
+import { ref, onMounted, onUnmounted, nextTick, watch } from 'vue'
+import Basein from './components/basein.vue';
+import Table from './components/table.vue';
+import { getRecogViewHrDetail, saveRecogViewDetail, getNoHrReasonList } from '/@/api/backend/doctor'
+import { provide } from 'vue';
+import { getFileType } from '/@/utils/common'
+import { useRoute } from 'vue-router'
+import { layoutMainScrollbarRef, layoutMainScrollbarStyle } from '/@/stores/refs'
+import { useSiteConfig } from '/@/stores/siteConfig'
+import { ElMessage } from 'element-plus'
+import { Session } from '/@/utils/storage'
+const reportSrc = ref('')
+const fileType = ref('image')
+const loading = ref(true)
+const siteConfig = useSiteConfig()
+const route = useRoute()
+defineOptions({
+    name: 'hospital/detail',
+})
+const resData = ref<any>({})
+const patientData = ref<any>({})
+const dialogVisible = ref(false)
+const activeIndex = ref(-1); 
+const dialogVisibleFn = (IMAGES: string) => {
+    fileType.value = IMAGES && getFileType(IMAGES)
+    reportSrc.value = IMAGES
+    dialogVisible.value = !dialogVisible.value
+}
+provide('dialogVisible', dialogVisibleFn)
+const tableData = () => {
+    const token = (route.query.token ?? '') as string
+    getRecogViewHrDetail({
+        TOKEN: token
+    }).then((res)=> {
+        console.log(res)
+        resData.value = res.data.data
+        patientData.value = res.data.patient
+        loading.value = false
+    })
+}
+const getNoHrReasonListFn = () => {
+    getNoHrReasonList().then((res) => {
+        const list = res.data.list
+        let transformedData = list.map((item: { code: any; name: any; }) => {
+            return {
+                value: item.code,
+                label: item.name
+            };
+        })
+        Session.set('noHrReasonList', transformedData)
+        tableData()
+    })
+}
+
+
+const saveHr = () => {
+    const HR_RECORDS = Session.get('HR_RECORDS')
+    if(!HR_RECORDS) {
+        ElMessage({
+            message: '暂无更改的互认记录!',
+            type: 'error',
+        })
+        return
+    }
+    const params = {
+        TOKEN: (route.query.token ?? '') as string,
+        HR_RECORDS
+    }
+    console.log(params, '保存参数')
+    saveRecogViewDetail(params).then((res) => {
+        console.log(res)
+        Session.remove('HR_RECORDS')
+        ElMessage({
+            message: '保存成功!',
+            type: 'success',
+        })
+    })
+}
+const stringProject = (INSPECT_REPORTS:any) => {
+    const LAB_ITEMDETAILNAME = INSPECT_REPORTS.map((item:any)=> item.INSPECT_REPORT_ITEMS.map((subItem: any) => subItem.LAB_ITEMDETAILNAME))
+    return LAB_ITEMDETAILNAME.flat().join(',');
+}
+const scrollToSection = (index: any) => {
+    activeIndex.value = index;
+    nextTick(() => {
+        const anchorElement = document.getElementById('anchor'+index);
+        if (anchorElement) {
+            anchorElement.scrollIntoView({ behavior: 'smooth' });
+        }
+    });
+};
+const scrollTop = ref(0)
+const handleScroll = (top: any) => {
+    // const bottom = top + window.innerHeight;
+    scrollTop.value = top.scrollTop
+    let newIndex = -1;
+    resData.value.INSPECT_REPORTS?.forEach((item:object, index:number) => {
+        const elementId = `anchor${index}`;
+        const element = document.getElementById(elementId);
+        if (element) {
+            const elementTop = element.offsetTop;
+            if (elementTop <= top && elementTop + element.offsetHeight > top) {
+                newIndex = index;
+                return;
+            }
+        }
+    });
+
+    if (newIndex !== activeIndex.value) {
+        activeIndex.value = newIndex;
+    }
+};
+watch(
+    () => siteConfig.mainScrollTop,
+    (newVal) => {
+        console.log(newVal, '最新滚动数据')
+        handleScroll(newVal)
+    },
+    {
+        deep:true
+    }
+)
+const beforeUnloadHandler = (event: { returnValue: string; }) => {
+    const message = '您有未保存的信息,确定要离开吗?';
+    event.returnValue = message; // 用于兼容旧浏览器
+    return message;
+};
+onMounted(() => {
+    const aa = layoutMainScrollbarRef.value
+    console.log(aa?.update(), '---------')
+    const token = (route.query.token ?? '') as string
+    // const token = adminInfo.getToken()
+    const noHrReasonList = Session.get('noHrReasonList')
+    if(token){
+        console.log(noHrReasonList, 'huhuhuh')
+        if(!noHrReasonList){
+            getNoHrReasonListFn()
+        }else{
+            tableData()
+        }
+    }
+    window.addEventListener('beforeunload', beforeUnloadHandler);
+    if(Session.get('HR_RECORDS')){
+        Session.remove('HR_RECORDS')
+    }
+})
+onUnmounted(() => {
+    window.removeEventListener('beforeunload', beforeUnloadHandler);
+});
+</script>
+
+<style scoped lang="scss">
+.layout-container .layout-main {
+    padding: 0 !important;
+    overflow: hidden;
+    width: 100%;
+    height: 100%;
+}
+.layout-main-scrollbar {
+    width: 100%;
+    position: relative;
+    overflow: hidden;
+}
+.anchor-box {
+  display: flex;
+  background: var(--ba-bg-color-overlay);
+  padding: 15px;
+  font-weight: 800;
+  color: var(--ba-vars-color-main-primary);
+  .active {
+    color: var(--el-color-danger);
+    position: relative;
+  }
+  .active::after {
+    content: '';
+    display: block;
+    height: 2px;
+    width: 48px;
+    position: absolute;
+    bottom: -6px;
+    transition: left .25s ease-in-out,opacity .25s,width .25s;
+    background: var(--el-color-danger);
+  }
+  .anchor-item {
+    margin-right: 16px;
+    cursor: pointer;
+  }
+  .anchor-item:hover {
+    color: var(--ba-vars-color-main-primary);
+  }
+}
+.fixed {
+  width: 100%;
+  position: fixed;
+  top: 0px;
+  z-index: 99;
+  background: var(--ba-vars-color-tree);
+}
+.doctor-tabs-box {
+  background: var(--ba-bg-color-overlay);
+  .institution-name {
+    width: 120px;
+    padding: 15px;
+    color: var(--ba-vars-color-main-primary);
+    font-weight: 600;
+    font-size: var(--el-font-size-medium);
+    border-bottom: 2px solid var(--ba-vars-color-main-primary);
+  }
+  .custom-tabs-label {
+    font-weight: 400;
+  }
+  .custom-tabs-label .time {
+    color: var(--el-color-error);
+    font-weight: 600;
+  }
+  .custom-tabs-label .name {
+    color: var(--el-color-main-primary-light);
+    font-weight: 600;
+  }
+  .custom-tabs-label .label {
+    font-weight: 800;
+  }
+  .content {
+    color: var(--el-color-error);
+    font-weight: 600;
+    display: block;
+    width: 300px;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+  }
+}
+
+</style>

Dosya farkı çok büyük olduğundan ihmal edildi
+ 852 - 537
jcjyhr/web/yarn.lock


Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor