index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. <template>
  2. <el-container class="layout-container">
  3. <el-container class="content-wrapper">
  4. <el-main class="layout-main">
  5. <el-scrollbar class="layout-main-scrollbar" :style="layoutMainScrollbarStyle" ref="layoutMainScrollbarRef" @scroll="handleScroll">
  6. <div class="default-main ba-table-box main-scroll" v-loading="loading">
  7. <Basein :dataV="patientData" />
  8. <div class="doctor-tabs-box">
  9. <div class="institution-name">就诊信息</div>
  10. <el-tabs type="card" class="demo-tabs">
  11. <el-tab-pane v-for="(i, index) in resData" :key="index">
  12. <template #label>
  13. <div class="custom-tabs-label">
  14. <span class="time">{{i.MEDICAL_INFORMATION.ENCOUNTER_DATE}}</span>
  15. <span class="name">&nbsp;&nbsp;{{i.MEDICAL_INFORMATION.ORGNAME}}</span>
  16. <div>
  17. <span class="label">诊 断:</span>
  18. <span>{{i.MEDICAL_INFORMATION.DIAGNOSENAME}}</span>
  19. </div>
  20. <div>
  21. <span class="label">主 诉:</span>
  22. <span>{{i.MEDICAL_INFORMATION.CHIEFCOMPLAINT}}</span>
  23. </div>
  24. <div>
  25. <span class="label">就诊科室:</span>
  26. <span>{{i.MEDICAL_INFORMATION.DEPTNAME}}</span>
  27. </div>
  28. <div style="display: flex;">
  29. <span class="label">检查项目:</span>
  30. <!-- <span class="content">{{i.EXAM_REPORTS[index].EXAM_ITEMNAME}}</span> -->
  31. <span class="content" >{{i.EXAM_REPORTS.map((item: any) => item.EXAM_ITEMNAME).filter((itemName:any) => itemName && itemName.trim() !== '').join(',')}}</span>
  32. </div>
  33. <div style="display: flex;">
  34. <span class="label">检验项目:</span>
  35. <!-- <span class="content">{{i.INSPECT_REPORTS.map((item: any) => item.INSPECT_REPORT_ITEMS).join(',')}}</span> -->
  36. <span class="content">{{stringProject(i.INSPECT_REPORTS)}}</span>
  37. </div>
  38. </div>
  39. </template>
  40. <!-- 检验 -->
  41. <div :class="['anchor-box', scrollTop >= 270 ? 'fixed' : '']">
  42. <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>
  43. </div>
  44. <template v-for="(item, index1) in i.INSPECT_REPORTS" :key="index1">
  45. <Table :tableData="item" :hrrecords="i.HR_RECORDS" :medicalInformation="i.MEDICAL_INFORMATION" :patientCode="patientData.PATIENT_CODE" from="hrMyTable" :id="`anchor${index}`"/>
  46. </template>
  47. <Table :examTableData="i.EXAM_REPORTS" :hrrecords="i.HR_RECORDS" :medicalInformation="i.MEDICAL_INFORMATION" :patientCode="patientData.PATIENT_CODE" from="hrMyTable" />
  48. </el-tab-pane>
  49. </el-tabs>
  50. </div>
  51. <el-dialog
  52. class="ba-operate-dialog"
  53. :close-on-click-modal="false"
  54. :model-value="dialogVisible"
  55. @close="dialogVisible = false"
  56. width="50%"
  57. >
  58. <el-scrollbar v-loading="!dialogVisible" class="ba-table-form-scrollbar">
  59. <div>
  60. <el-image
  61. v-if="fileType === 'image'"
  62. :src="reportSrc"
  63. fit="cover"
  64. :style="{ width: '100%', height: 'auto' }"
  65. ></el-image>
  66. <embed
  67. v-else-if="fileType === 'pdf'"
  68. :src="reportSrc"
  69. type="application/pdf"
  70. width="100%"
  71. height="auto"
  72. />
  73. </div>
  74. </el-scrollbar>
  75. </el-dialog>
  76. </div>
  77. </el-scrollbar>
  78. <!-- <div style="text-align: center;padding-top: 15px;">
  79. <el-button type="primary" :color="'var(--ba-vars-color-main-primary)'" @click="saveHr">保存互认</el-button>
  80. </div> -->
  81. </el-main>
  82. </el-container>
  83. </el-container>
  84. </template>
  85. <script setup lang="ts">
  86. import { ref, onMounted, onUnmounted, nextTick, watch } from 'vue'
  87. import Basein from './components/basein.vue';
  88. import Table from './components/table.vue';
  89. import { getRecogViewHrDetail, saveRecogViewDetail, getNoHrReasonList } from '/@/api/backend/doctor'
  90. import { provide } from 'vue';
  91. import { getFileType } from '/@/utils/common'
  92. import { useRoute } from 'vue-router'
  93. import { layoutMainScrollbarRef, layoutMainScrollbarStyle } from '/@/stores/refs'
  94. import { useSiteConfig } from '/@/stores/siteConfig'
  95. import { ElMessage } from 'element-plus'
  96. import { Session } from '/@/utils/storage'
  97. const reportSrc = ref('')
  98. const fileType = ref('image')
  99. const loading = ref(true)
  100. const siteConfig = useSiteConfig()
  101. const route = useRoute()
  102. defineOptions({
  103. name: 'hospital/detail',
  104. })
  105. const resData = ref<any>({})
  106. const patientData = ref<any>({})
  107. const dialogVisible = ref(false)
  108. const activeIndex = ref(-1);
  109. const dialogVisibleFn = (IMAGES: string) => {
  110. fileType.value = IMAGES && getFileType(IMAGES)
  111. reportSrc.value = IMAGES
  112. dialogVisible.value = !dialogVisible.value
  113. }
  114. provide('dialogVisible', dialogVisibleFn)
  115. const tableData = () => {
  116. const token = (route.query.token ?? '') as string
  117. getRecogViewHrDetail({
  118. TOKEN: token
  119. }).then((res)=> {
  120. console.log(res)
  121. resData.value = res.data.data
  122. patientData.value = res.data.patient
  123. loading.value = false
  124. })
  125. }
  126. const getNoHrReasonListFn = () => {
  127. getNoHrReasonList().then((res) => {
  128. const list = res.data.list
  129. let transformedData = list.map((item: { code: any; name: any; }) => {
  130. return {
  131. value: item.code,
  132. label: item.name
  133. };
  134. })
  135. Session.set('noHrReasonList', transformedData)
  136. tableData()
  137. })
  138. }
  139. const saveHr = () => {
  140. const HR_RECORDS = Session.get('HR_RECORDS')
  141. if(!HR_RECORDS) {
  142. ElMessage({
  143. message: '暂无更改的互认记录!',
  144. type: 'error',
  145. })
  146. return
  147. }
  148. const params = {
  149. TOKEN: (route.query.token ?? '') as string,
  150. HR_RECORDS
  151. }
  152. console.log(params, '保存参数')
  153. saveRecogViewDetail(params).then((res) => {
  154. console.log(res)
  155. Session.remove('HR_RECORDS')
  156. ElMessage({
  157. message: '保存成功!',
  158. type: 'success',
  159. })
  160. })
  161. }
  162. const stringProject = (INSPECT_REPORTS:any) => {
  163. const LAB_ITEMDETAILNAME = INSPECT_REPORTS.map((item:any)=> item.INSPECT_REPORT_ITEMS.map((subItem: any) => subItem.LAB_ITEMDETAILNAME))
  164. return LAB_ITEMDETAILNAME.flat().join(',');
  165. }
  166. const scrollToSection = (index: any) => {
  167. activeIndex.value = index;
  168. nextTick(() => {
  169. const anchorElement = document.getElementById('anchor'+index);
  170. if (anchorElement) {
  171. anchorElement.scrollIntoView({ behavior: 'smooth' });
  172. }
  173. });
  174. };
  175. const scrollTop = ref(0)
  176. const handleScroll = (top: any) => {
  177. // const bottom = top + window.innerHeight;
  178. scrollTop.value = top.scrollTop
  179. let newIndex = -1;
  180. resData.value.INSPECT_REPORTS?.forEach((item:object, index:number) => {
  181. const elementId = `anchor${index}`;
  182. const element = document.getElementById(elementId);
  183. if (element) {
  184. const elementTop = element.offsetTop;
  185. if (elementTop <= top && elementTop + element.offsetHeight > top) {
  186. newIndex = index;
  187. return;
  188. }
  189. }
  190. });
  191. if (newIndex !== activeIndex.value) {
  192. activeIndex.value = newIndex;
  193. }
  194. };
  195. watch(
  196. () => siteConfig.mainScrollTop,
  197. (newVal) => {
  198. console.log(newVal, '最新滚动数据')
  199. handleScroll(newVal)
  200. },
  201. {
  202. deep:true
  203. }
  204. )
  205. const beforeUnloadHandler = (event: { returnValue: string; }) => {
  206. const message = '您有未保存的信息,确定要离开吗?';
  207. event.returnValue = message; // 用于兼容旧浏览器
  208. return message;
  209. };
  210. onMounted(() => {
  211. const aa = layoutMainScrollbarRef.value
  212. console.log(aa?.update(), '---------')
  213. const token = (route.query.token ?? '') as string
  214. // const token = adminInfo.getToken()
  215. const noHrReasonList = Session.get('noHrReasonList')
  216. if(token){
  217. console.log(noHrReasonList, 'huhuhuh')
  218. if(!noHrReasonList){
  219. getNoHrReasonListFn()
  220. }else{
  221. tableData()
  222. }
  223. }
  224. window.addEventListener('beforeunload', beforeUnloadHandler);
  225. if(Session.get('HR_RECORDS')){
  226. Session.remove('HR_RECORDS')
  227. }
  228. })
  229. onUnmounted(() => {
  230. window.removeEventListener('beforeunload', beforeUnloadHandler);
  231. });
  232. </script>
  233. <style scoped lang="scss">
  234. .layout-container .layout-main {
  235. padding: 0 !important;
  236. overflow: hidden;
  237. width: 100%;
  238. height: 100%;
  239. }
  240. .layout-main-scrollbar {
  241. width: 100%;
  242. position: relative;
  243. overflow: hidden;
  244. }
  245. .anchor-box {
  246. display: flex;
  247. background: var(--ba-bg-color-overlay);
  248. padding: 15px;
  249. font-weight: 800;
  250. color: var(--ba-vars-color-main-primary);
  251. .active {
  252. color: var(--el-color-danger);
  253. position: relative;
  254. }
  255. .active::after {
  256. content: '';
  257. display: block;
  258. height: 2px;
  259. width: 48px;
  260. position: absolute;
  261. bottom: -6px;
  262. transition: left .25s ease-in-out,opacity .25s,width .25s;
  263. background: var(--el-color-danger);
  264. }
  265. .anchor-item {
  266. margin-right: 16px;
  267. cursor: pointer;
  268. }
  269. .anchor-item:hover {
  270. color: var(--ba-vars-color-main-primary);
  271. }
  272. }
  273. .fixed {
  274. width: 100%;
  275. position: fixed;
  276. top: 0px;
  277. z-index: 99;
  278. background: var(--ba-vars-color-tree);
  279. }
  280. .doctor-tabs-box {
  281. background: var(--ba-bg-color-overlay);
  282. .institution-name {
  283. width: 120px;
  284. padding: 15px;
  285. color: var(--ba-vars-color-main-primary);
  286. font-weight: 600;
  287. font-size: var(--el-font-size-medium);
  288. border-bottom: 2px solid var(--ba-vars-color-main-primary);
  289. }
  290. .custom-tabs-label {
  291. font-weight: 400;
  292. }
  293. .custom-tabs-label .time {
  294. color: var(--el-color-error);
  295. font-weight: 600;
  296. }
  297. .custom-tabs-label .name {
  298. color: var(--el-color-main-primary-light);
  299. font-weight: 600;
  300. }
  301. .custom-tabs-label .label {
  302. font-weight: 800;
  303. }
  304. .content {
  305. color: var(--el-color-error);
  306. font-weight: 600;
  307. display: block;
  308. width: 300px;
  309. white-space: nowrap;
  310. overflow: hidden;
  311. text-overflow: ellipsis;
  312. }
  313. }
  314. </style>