280 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
			
		
		
	
	
			280 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
<template>
 | 
						|
  <div ref="preview-wrapper">
 | 
						|
    <div class="viewerContainer">
 | 
						|
      <div class="viewerContentWrapper" style="padding-top:25px;">
 | 
						|
        <div class="viewerLeftSidePanel">
 | 
						|
          <div id="listWrapper" class="sidePanelBody">
 | 
						|
            <div class="sidePanelThumbs">
 | 
						|
              <!-- <div class="studyDesc" style="border-bottom:1px solid #9e9e9e;" @click="closeDialog()">
 | 
						|
              <span style="font-size:14px;color:#d0d0d0;margin:5px 0px;line-height: 25px;">返回列表</span>
 | 
						|
            </div> -->
 | 
						|
              <div class="studyDesc" style="line-height: 10px;">
 | 
						|
                {{ studyTitle }}
 | 
						|
              </div>
 | 
						|
              <div class="studyDesc" style="line-height: 10px">
 | 
						|
                {{ seriesCount }} Series
 | 
						|
              </div>
 | 
						|
              <div class="viewerSidethumbs ps" style="position: relative;">
 | 
						|
                <div class="viewerSidethumbinner">
 | 
						|
                  <div
 | 
						|
                    v-for="(item, index) in seriesList"
 | 
						|
                    :key="index"
 | 
						|
                    :class="{'viewerSideActive': index==currentSeriesIndex}"
 | 
						|
                    class="viewernavigatorwrapper"
 | 
						|
                    @click="showSeriesImage(index)"
 | 
						|
                  >
 | 
						|
                    <dicomPreview
 | 
						|
                      :image-id="item.previewImageId"
 | 
						|
                      class="image-preview"
 | 
						|
                      style="height:72px;width:72px;display: inline-block"
 | 
						|
                    />
 | 
						|
                    <!-- <span class="viewernavitextwrapper" title>
 | 
						|
                    <span class="viewernavitexttxt">
 | 
						|
                      <span>{{ item.seriesTitle }}</span>
 | 
						|
                    </span>
 | 
						|
                    <span class="viewernavitextnum">
 | 
						|
                      {{ item.instanceCount }} image
 | 
						|
 | 
						|
                    </span>
 | 
						|
                  </span>-->
 | 
						|
                    <div class="viewernavitextwrapper">
 | 
						|
                      <div style="padding: 1px;">#{{ item.seriesTitle }}</div>
 | 
						|
                      <div
 | 
						|
                        v-show="item.instanceCount"
 | 
						|
                        style="padding: 1px;"
 | 
						|
                      >{{ item.instanceCount }} image</div>
 | 
						|
                    </div>
 | 
						|
                  </div>
 | 
						|
                </div>
 | 
						|
              </div>
 | 
						|
            </div>
 | 
						|
          </div>
 | 
						|
        </div>
 | 
						|
        <div class="viewerContent">
 | 
						|
          <dicom-viewer id="dicomViewer" ref="dicomViewer" style="height:100%" />
 | 
						|
        </div>
 | 
						|
      </div>
 | 
						|
    </div>
 | 
						|
  </div>
 | 
						|
</template>
 | 
						|
 | 
						|
<script>
 | 
						|
import * as dicomParser from 'dicom-parser'
 | 
						|
import * as cornerstone from 'cornerstone-core'
 | 
						|
import * as cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader'
 | 
						|
import dicomStore from '@/utils/dicom-store.js'
 | 
						|
import dicomViewer from '@/components/Dicom/DicomViewer'
 | 
						|
import dicomPreview from '@/components/Dicom/DicomPreview'
 | 
						|
 | 
						|
cornerstoneWADOImageLoader.external.dicomParser = dicomParser
 | 
						|
cornerstoneWADOImageLoader.external.cornerstone = cornerstone
 | 
						|
// cornerstoneWADOImageLoader.webWorkerManager.initialize({
 | 
						|
//   webWorkerPath: './webWorker.js',
 | 
						|
//   taskConfiguration: {
 | 
						|
//     decodeTask: {
 | 
						|
//       codecsPath: './dicomCodecs.js'
 | 
						|
//     }
 | 
						|
//   }
 | 
						|
// })
 | 
						|
export default {
 | 
						|
  components: {
 | 
						|
    dicomViewer,
 | 
						|
    dicomPreview
 | 
						|
  },
 | 
						|
  props: {
 | 
						|
    uid: {
 | 
						|
      type: String,
 | 
						|
      default: ''
 | 
						|
    }
 | 
						|
  },
 | 
						|
 | 
						|
  data() {
 | 
						|
    return {
 | 
						|
      studyTitle: '',
 | 
						|
      seriesCount: 0,
 | 
						|
      seriesList: [],
 | 
						|
      currentSeriesIndex: -1
 | 
						|
    }
 | 
						|
  },
 | 
						|
 | 
						|
  mounted() {
 | 
						|
    var totalHeight = window.innerHeight || document.body.clientHeight
 | 
						|
    var wrapper = this.$refs['preview-wrapper']
 | 
						|
    wrapper.style.height = (totalHeight - 70) + 'px'
 | 
						|
    if (!dicomStore.studyList || !this.uid) return
 | 
						|
    this.loadStudy()
 | 
						|
  },
 | 
						|
 | 
						|
  methods: {
 | 
						|
    loadStudy() {
 | 
						|
      var studyList = dicomStore.studyList
 | 
						|
      var studyUid = this.uid
 | 
						|
      var studyItem = studyList.find(function(item) {
 | 
						|
        return item.dicomInfo.studyUid === studyUid
 | 
						|
      })
 | 
						|
      if (!studyItem) return
 | 
						|
 | 
						|
      this.studyTitle =
 | 
						|
        studyItem.dicomInfo.patientName || studyItem.dicomInfo.description
 | 
						|
      this.seriesCount = studyItem.seriesList.length
 | 
						|
      var scope = this
 | 
						|
 | 
						|
      studyItem.seriesList.forEach(function(series) {
 | 
						|
        series.instanceList.sort(function(item1, item2) {
 | 
						|
          return item1.instanceNumber - item2.instanceNumber
 | 
						|
        })
 | 
						|
 | 
						|
        var imageIds = []
 | 
						|
        series.instanceList.forEach(function(instance) {
 | 
						|
          var fileId = cornerstoneWADOImageLoader.wadouri.fileManager.add(
 | 
						|
            instance.file
 | 
						|
          )
 | 
						|
          if (instance.frameCount > 1) {
 | 
						|
            for (var i = 0; i < instance.frameCount; ++i) {
 | 
						|
              imageIds.push(`${fileId}?frame=${i}`)
 | 
						|
            }
 | 
						|
          } else imageIds.push(fileId)
 | 
						|
        })
 | 
						|
 | 
						|
        scope.seriesList.push({
 | 
						|
          seriesNumber: series.seriesNumber,
 | 
						|
          seriesTitle: series.description || series.modality || '(Anonymous)',
 | 
						|
          instanceCount: series.instanceList.length,
 | 
						|
          imageIds: imageIds,
 | 
						|
          previewImageId: imageIds[0]
 | 
						|
        })
 | 
						|
      })
 | 
						|
 | 
						|
      this.showSeriesImage(0)
 | 
						|
    },
 | 
						|
 | 
						|
    showSeriesImage(seriesIndex) {
 | 
						|
      // if (seriesIndex === this.currentSeriesIndex) return;
 | 
						|
      this.currentSeriesIndex = seriesIndex
 | 
						|
      this.$refs.dicomViewer.loadImageStack(this.seriesList[seriesIndex])
 | 
						|
    },
 | 
						|
    closeDialog() {
 | 
						|
      this.$emit('closeInnerDialog')
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
</script>
 | 
						|
 | 
						|
<style scoped>
 | 
						|
::-webkit-scrollbar {
 | 
						|
  width: 7px;
 | 
						|
  height: 7px;
 | 
						|
}
 | 
						|
::-webkit-scrollbar-thumb {
 | 
						|
  border-radius: 10px;
 | 
						|
  background: #d0d0d0;
 | 
						|
}
 | 
						|
.viewerContainer {
 | 
						|
  display: block;
 | 
						|
    height: 100%;
 | 
						|
     margin-top: 20px;
 | 
						|
    margin-left: auto;
 | 
						|
    margin-right: auto;
 | 
						|
    background-color: #444;
 | 
						|
    overflow: hidden;
 | 
						|
}
 | 
						|
.viewerBanner {
 | 
						|
   background: linear-gradient(0,#444,#222);
 | 
						|
    min-height: 28px;
 | 
						|
    font-size: 16px;
 | 
						|
    margin: 0;
 | 
						|
    height: 30px;
 | 
						|
    padding-top: 0;
 | 
						|
    padding-left: 5px;
 | 
						|
    padding-right: 5px;
 | 
						|
    font-weight: bold;
 | 
						|
}
 | 
						|
.viewerContentWrapper {
 | 
						|
  display: flex;
 | 
						|
  flex-direction: row;
 | 
						|
  width: 100%;
 | 
						|
  padding: 5px;
 | 
						|
  height: 99%;
 | 
						|
  /* height: 95%; */
 | 
						|
  overflow: hidden;
 | 
						|
  text-overflow: clip;
 | 
						|
  white-space: nowrap;
 | 
						|
}
 | 
						|
.viewerContentWrapper > div {
 | 
						|
  display: inline-block;
 | 
						|
  white-space: normal;
 | 
						|
}
 | 
						|
.viewerLeftSidePanel {
 | 
						|
  width: 200px;
 | 
						|
  background-color: #323232;
 | 
						|
  box-sizing: border-box;
 | 
						|
  margin: 0;
 | 
						|
  padding: 0;
 | 
						|
  margin-right: 2px;
 | 
						|
  color: #d0d0d0;
 | 
						|
  overflow-y: auto;
 | 
						|
}
 | 
						|
.viewerContentWrapper > div > .sidePanelBody {
 | 
						|
  background: rgba(50, 50, 50, 1);
 | 
						|
  word-break: break-all;
 | 
						|
  display: table;
 | 
						|
  width: 100%;
 | 
						|
  border: 1px solid #3e3f3a;
 | 
						|
}
 | 
						|
.viewerContentWrapper > div > div.sidePanelBody > div {
 | 
						|
  width: 100%;
 | 
						|
  height: 100%;
 | 
						|
}
 | 
						|
.studyDesc {
 | 
						|
  font-weight: bold;
 | 
						|
  font-size: 13px;
 | 
						|
  text-align: center;
 | 
						|
  background: rgb(88 84 83);
 | 
						|
  color: #d0d0d0;
 | 
						|
  padding: 2px;
 | 
						|
}
 | 
						|
.ps {
 | 
						|
  overflow: hidden !important;
 | 
						|
  overflow-anchor: none;
 | 
						|
  -ms-overflow-style: none;
 | 
						|
  touch-action: auto;
 | 
						|
  -ms-touch-action: auto;
 | 
						|
}
 | 
						|
.viewerLeftSidePanel .viewernavigatorwrapper {
 | 
						|
  display: flex;
 | 
						|
  width: 196px;
 | 
						|
  height: 84px;
 | 
						|
  padding: 1px 2px 1px 8px;
 | 
						|
  margin: 6px 0 6px 1px;
 | 
						|
  border-radius: 2px;
 | 
						|
  border: 1px solid #404040;
 | 
						|
}
 | 
						|
.ui-draggable-handle {
 | 
						|
  -ms-touch-action: none;
 | 
						|
  touch-action: none;
 | 
						|
}
 | 
						|
.viewerLeftSidePanel .image-preview {
 | 
						|
  border: 2px solid #252525;
 | 
						|
  cursor: pointer;
 | 
						|
}
 | 
						|
.viewerLeftSidePanel .viewernavitextwrapper {
 | 
						|
  flex: 1;
 | 
						|
  padding: 3px 1px 3px 4px;
 | 
						|
  vertical-align: top;
 | 
						|
  font-size: 12px;
 | 
						|
}
 | 
						|
.viewerSideActive {
 | 
						|
  background: #16477b;
 | 
						|
  background: #16477b80;
 | 
						|
  border: 1px solid #23527b;
 | 
						|
}
 | 
						|
.viewerContent {
 | 
						|
  flex: 1;
 | 
						|
  height: 100%;
 | 
						|
  display: block;
 | 
						|
  background-color: black;
 | 
						|
  color: #d0d0d0;
 | 
						|
  font-size: 13px;
 | 
						|
}
 | 
						|
</style>
 |