<template>
  <div>
    <div class="top">
      <span>{{ $t('upload:dicom:title') }}</span>
      <div class="btnBox">
        <form id="inputForm" ref="uploadForm" enctype="multipart/form-data">
          <div class="form-group">
            <div id="directoryInputWrapper" class="btn btn-link file-input">
              <el-button
                type="primary"
                :disabled="btnLoading"
                :loading="btnLoading"
                size="mini"
              >
                {{ $t('upload:dicom:button:upload') }}
              </el-button>
              <input
                type="file"
                name="file"
                ref="pathClear"
                :disabled="btnLoading"
                webkitdirectory
                multiple
                title=""
                @change="beginScanFiles($event)"
              />
            </div>
          </div>
        </form>
      </div>
    </div>
    <!--检查列表-->
    <el-table :data="list" style="width: 100%" height="300" :loading="loading">
      <!--受试者-->
      <el-table-column
        prop="SubjectCode"
        :label="$t('upload:dicom:table:subjectCode')"
      />
      <!--任务名称-->
      <el-table-column
        prop="TaskBlindName"
        :label="$t('upload:dicom:table:taskBlindName')"
      />
      <!--原始检查数-->
      <el-table-column
        prop="OrginalStudyList"
        :label="$t('upload:dicom:table:orginalStudyListNum')"
      >
        <template slot-scope="scope">
          <el-button
            v-if="
              scope.row.OrginalStudyList &&
              scope.row.OrginalStudyList.length >= 1
            "
            type="text"
            @click="handleOpenDialog(scope.row, 'OrginalStudyList')"
          >
            <span>{{ scope.row.OrginalStudyList.length }}</span>
          </el-button>
          <span v-else>0</span>
        </template>
      </el-table-column>
      <!--后处理检查数-->
      <el-table-column
        prop="UploadStudyList"
        :label="$t('upload:dicom:table:uploadStudyListNum')"
      >
        <template slot-scope="scope">{{
          scope.row.UploadStudyList && Array.isArray(scope.row.UploadStudyList)
            ? scope.row.UploadStudyList.length
            : 0
        }}</template>
      </el-table-column>
      <el-table-column
        :label="$t('common:action:action')"
        fixed="right"
        width="180"
      >
        <template slot-scope="scope">
          <div class="btnBox">
            <!--上传--->
            <form
              id="inputForm"
              :ref="`uploadForm_${scope.row.Id}`"
              enctype="multipart/form-data"
            >
              <div class="form-group" style="margin-right: 10px">
                <div
                  :id="`directoryInputWrapper_${scope.row.Id}`"
                  class="btn btn-link file-input"
                >
                  <el-button
                    circle
                    icon="el-icon-upload2"
                    :disabled="btnLoading"
                    :loading="btnLoading"
                    :title="$t('upload:dicom:button:upload')"
                  />
                  <input
                    type="file"
                    :name="`file_${scope.row.Id}`"
                    :ref="`pathClear_${scope.row.Id}`"
                    :disabled="btnLoading"
                    webkitdirectory
                    multiple
                    title=""
                    @change="
                      ($event) => beginScanFiles($event, scope.row.VisitTaskId)
                    "
                  />
                </div>
              </div>
            </form>
            <!--预览--->
            <el-button
              circle
              icon="el-icon-view"
              :disabled="
                !scope.row.UploadStudyList ||
                scope.row.UploadStudyList.length <= 0
              "
              @click.stop="handleViewReadingImages(scope.row)"
              :title="$t('upload:dicom:button:preview')"
            />
            <!--删除--->
            <el-button
              circle
              :disabled="
                !scope.row.UploadStudyList ||
                scope.row.UploadStudyList.length <= 0
              "
              icon="el-icon-delete"
              :title="$t('upload:dicom:button:delete')"
              @click.stop="remove(scope.row)"
            />
          </div>
        </template>
      </el-table-column>
    </el-table>
    <div style="margin: 10px 0">
      <span>{{ $t('upload:dicom:uploadTitle') }}</span>
      <span style="margin-left: 10px">{{ $store.state.trials.uploadTip }}</span>
    </div>
    <!--上传列表-->
    <el-table
      ref="dicomFilesTable"
      v-adaptive="{ bottomOffset: 80 }"
      height="100"
      :data="uploadQueues"
      class="dicomFiles-table"
      @selection-change="handleSelectionChange"
    >
      <el-table-column type="index" width="40" />
      <el-table-column min-width="200" show-overflow-tooltip>
        <template slot="header">
          <el-tooltip placement="top">
            <div slot="content">
              {{ $t('trials:uploadDicomList:table:studyDetail1') }}<br />
              {{ $t('trials:uploadDicomList:table:studyDetail2') }}<br />
              {{ $t('trials:uploadedDicoms:table:studyDate') }}
            </div>
            <span>{{ $t('trials:uploadDicomList:table:studyInfo') }}</span>
          </el-tooltip>
        </template>
        <template slot-scope="scope">
          <div style="line-height: 15px">
            <div>
              <div>
                <span v-if="scope.row.dicomInfo.accNumber"
                  ><span style="font-weight: 500">Acc:</span>
                  {{ scope.row.dicomInfo.accNumber }}</span
                >
                <span v-else style="color: #f44336">N/A</span>
              </div>
              <div style="display: inline-block; margin-right: 2px">
                <span v-if="scope.row.dicomInfo.modality.length > 0">
                  {{ scope.row.dicomInfo.modality.join('、') }},</span
                >
                <span v-else style="color: #f44336">N/A,</span>
              </div>
              <div style="display: inline-block; margin-right: 2px">
                <span v-if="scope.row.seriesList.length"
                  >{{ scope.row.seriesList.length }} Series,</span
                >
                <span v-else style="color: #f44336">N/A,</span>
              </div>
              <div style="display: inline-block">
                <span v-if="scope.row.fileList.length"
                  >{{ scope.row.fileList.length }} Instances</span
                >
                <span v-else style="color: #f44336">N/A</span>
              </div>
            </div>

            <div>
              <div style="display: inline-block; margin-right: 2px">
                <span v-if="scope.row.dicomInfo.bodyPart">
                  {{ scope.row.dicomInfo.bodyPart }},
                </span>
                <span v-else style="color: #f44336">N/A, </span>
              </div>
              <div style="display: inline-block">
                <span v-if="scope.row.dicomInfo.description">
                  {{ scope.row.dicomInfo.description }}</span
                >
                <span v-else style="color: #f44336">N/A</span>
              </div>
            </div>
            <div>
              {{ scope.row.dicomInfo.studyTime }}
            </div>
          </div>
        </template>
      </el-table-column>
      <el-table-column min-width="130" show-overflow-tooltip>
        <template slot="header">
          <el-tooltip placement="top">
            <div slot="content">
              {{ $t('trials:uploadDicomList:table:pId') }}<br />
              {{ $t('trials:uploadDicomList:table:patientName') }}<br />
              {{ $t('trials:uploadDicomList:table:pInfo') }}
            </div>
            <span>{{ $t('trials:uploadDicomList:table:patientInfo') }}</span>
          </el-tooltip>
        </template>
        <template slot-scope="scope">
          <div style="line-height: 15px">
            <div>
              <span v-if="scope.row.dicomInfo.patientId"
                ><span style="font-weight: 500">PID: </span
                >{{ scope.row.dicomInfo.patientId }}</span
              >
              <span v-else style="color: #f44336">N/A</span>
            </div>
            <div>
              <span
                :class="[scope.row.dicomInfo.patientName ? '' : 'colorOfRed']"
              >
                {{
                  scope.row.dicomInfo.patientName
                    ? scope.row.dicomInfo.patientName
                    : 'N/A'
                }}
              </span>
            </div>
            <div>
              <span
                :class="[scope.row.dicomInfo.patientSex ? '' : 'colorOfRed']"
              >
                {{
                  scope.row.dicomInfo.patientSex
                    ? scope.row.dicomInfo.patientSex
                    : 'N/A'
                }},
              </span>

              <span
                :class="[scope.row.dicomInfo.patientAge ? '' : 'colorOfRed']"
              >
                {{
                  scope.row.dicomInfo.patientAge
                    ? scope.row.dicomInfo.patientAge
                    : 'N/A'
                }},
              </span>

              <span
                :class="[
                  scope.row.dicomInfo.patientBirthDate ? '' : 'colorOfRed',
                ]"
              >
                {{
                  scope.row.dicomInfo.patientBirthDate
                    ? scope.row.dicomInfo.patientBirthDate
                    : 'N/A'
                }}
              </span>
            </div>
          </div>
        </template>
      </el-table-column>
      <el-table-column
        :label="$t('trials:uploadDicomList:table:failedFileCount')"
        min-width="150"
        show-overflow-tooltip
      >
        <template slot-scope="scope">
          <el-progress
            color="#409eff"
            :percentage="
              (
                (scope.row.dicomInfo.uploadFileSize * 100) /
                scope.row.dicomInfo.fileSize
              ).toFixed(2) * 1
            "
          />
          <span>
            {{ $t('trials:uploadDicomList:table:uploadNow')
            }}{{ scope.row.dicomInfo.failedFileCount }} /
            {{ scope.row.dicomInfo.fileCount }}: [{{
              (scope.row.dicomInfo.uploadFileSize / 1024 / 1024).toFixed(2)
            }}MB/{{
              (scope.row.dicomInfo.fileSize / 1024 / 1024).toFixed(2)
            }}MB]
          </span>
        </template>
      </el-table-column>

      <el-table-column
        :label="$t('trials:uploadDicomList:table:status')"
        min-width="140"
        show-overflow-tooltip
      >
        <template slot-scope="scope">
          <span
            v-if="
              !scope.row.dicomInfo.failedFileCount &&
              !scope.row.dicomInfo.isInit
            "
          >
            {{ $t('trials:uploadDicomList:table:status1') }}</span
          >
          <span
            style="color: #409eff"
            v-else-if="
              !scope.row.dicomInfo.failedFileCount &&
              scope.row.dicomInfo.isInit &&
              btnLoading
            "
            >{{ $t('trials:uploadDicomList:table:status2') }}</span
          >
          <span
            style="color: #409eff"
            v-else-if="
              scope.row.dicomInfo.failedFileCount <
                scope.row.dicomInfo.fileCount && !scope.row.uploadState.record
            "
            >{{ $t('trials:uploadDicomList:table:status2') }}</span
          >
          <span
            style="color: #2cc368"
            v-else-if="
              scope.row.dicomInfo.failedFileCount ===
              scope.row.dicomInfo.fileCount
            "
            >{{ $t('trials:uploadDicomList:table:status3') }}</span
          >
          <span
            style="color: #f66"
            v-else-if="
              scope.row.uploadState.record &&
              scope.row.uploadState.record.fileCount === 0
            "
            >{{ $t('trials:uploadDicomList:table:status5') }}</span
          >
          <span style="color: #f66" v-else>{{
            $t('trials:uploadDicomList:table:Failed')
          }}</span>
        </template>
      </el-table-column>
      <el-table-column
        :label="$t('trials:uploadDicomList:table:record')"
        min-width="140"
        show-overflow-tooltip
      >
        <template slot-scope="scope">
          <el-tooltip placement="top" v-if="scope.row.uploadState.record">
            <div slot="content">
              <div style="max-height: 500px; overflow-y: auto">
                {{ $t('trials:uploadDicomList:table:Existed') }}:
                <div v-if="scope.row.uploadState.record.Existed.length">
                  <div
                    v-for="item of scope.row.uploadState.record.Existed"
                    :key="item"
                    style="font-size: 12px; color: #baa72a"
                  >
                    {{ item }}
                  </div>
                </div>
                <div v-else>&nbsp;</div>
                {{ $t('trials:uploadDicomList:table:Uploaded') }}:
                <div v-if="scope.row.uploadState.record.Uploaded.length">
                  <div
                    v-for="item of scope.row.uploadState.record.Uploaded"
                    :key="item"
                    style="font-size: 12px; color: #24b837"
                  >
                    {{ item }}
                  </div>
                </div>
                <div v-else>&nbsp;</div>
                <br />
                {{ $t('trials:uploadDicomList:table:Failed') }}:
                <div v-if="scope.row.uploadState.record.Failed.length">
                  <div
                    v-for="item of scope.row.uploadState.record.Failed"
                    :key="item"
                    style="font-size: 12px; color: #f66"
                  >
                    {{ item }}
                  </div>
                </div>
                <div v-else>&nbsp;</div>
              </div>
            </div>
            <el-button size="mini" style="cursor: pointer">
              <span style="font-size: 12px; color: #baa72a">{{
                scope.row.uploadState.record.Existed.length
              }}</span>
              /
              <span style="font-size: 12px; color: #24b837">{{
                scope.row.uploadState.record.Uploaded.length
              }}</span>
              /
              <span style="font-size: 12px; color: #f66">{{
                scope.row.uploadState.record.Failed.length
              }}</span>
            </el-button>
          </el-tooltip>
        </template>
      </el-table-column>
    </el-table>
    <study-view
      v-if="model_cfg.visible"
      :model_cfg="model_cfg"
      :IsDicom="true"
      :modelList="modelList"
    />
  </div>
</template>
<script>
import { dicomUploadInProgress } from '@/api/trials'
import {
  preArchiveDicomStudy,
  addOrUpdateArchiveTaskStudy,
} from '@/api/load.js'
import studyView from './study-view.vue'
import {
  getSubjectImageUploadList,
  deleteTaskStudy,
  verifyIRStudyAllowUpload,
} from '@/api/load.js'
import * as dicomParser from 'dicom-parser'
import * as cornerstone from 'cornerstone-core'
import * as cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader'
var config = {
  maxWebWorkers: 4,
  startWebWorkersOnDemand: true,
  taskConfiguration: {
    decodeTask: {
      initializeCodecsOnStartup: false,
    },
  },
}
cornerstoneWADOImageLoader.webWorkerManager.initialize(config)
cornerstoneWADOImageLoader.external.dicomParser = dicomParser
cornerstoneWADOImageLoader.external.cornerstone = cornerstone
import { convertBytes } from '@/utils/dicom-character-set'
import { parseDicom } from '@/utils/parseDicom.js'
import { dcmUpload } from '@/utils/dcmUpload/dcmUpload'
import store from '@/store'
import { getToken } from '@/utils/auth'
export default {
  name: 'dicomFile',
  props: {
    SubjectId: {
      type: String,
      default: '',
    },
    SubjectCode: {
      type: String,
      default: '',
    },
    Criterion: {
      type: Object,
      default: () => {
        return {}
      },
    },
  },
  components: {
    'study-view': studyView,
  },
  data() {
    return {
      list: [],
      StudyInstanceUidList: [],
      SopInstanceUidList: [],
      UploadStudyList: [],
      // 检查数弹框
      model_cfg: {
        visible: false,
        showClose: true,
        width: '1000px',
        title: '',
        appendToBody: true,
      },
      modelList: [],

      VisitTaskId: null,
      hasOtherStudy: false,

      scanState: '', // 当前上传队列上传状态
      form: {
        SiteName: '',
        SubjectName: '',
        VisitName: '',
        SubjectId: '',
        VisitNum: null,
      },
      isScan: false,
      uploadQueues: [], // 上传队列
      studyErrorList: [],
      warningArr: [],
      selectArr: [],
      btnLoading: false,
      myInterval: [],
      isClose: false,
      trialId: null,
      subjectVisitId: null,
      errStudyUidList: [],
      open: null,
    }
  },
  created() {
    this.getList()
  },
  async mounted() {
    this.trialId = this.$route.query.trialId
    this.uploadQueues = []
    this.OSSclient.close()
  },
  beforeDestroy() {
    this.myInterval.forEach((v) => {
      clearInterval(v)
    })
    this.myInterval = []
    store.dispatch('trials/setUnLock', false)
    this.isClose = true
    this.OSSclient.close()
  },
  methods: {
    // 获取列表
    async getList() {
      try {
        let params = {
          SubjectId: this.SubjectId,
          TrialReadingCriterionId: this.Criterion.TrialReadingCriterionId,
          SubjectCode: this.SubjectCode,
        }
        this.loading = true
        let res = await getSubjectImageUploadList(params)
        this.loading = false
        if (res.IsSuccess) {
          this.StudyInstanceUidList = []
          this.SopInstanceUidList = []
          this.UploadStudyList = []
          this.list = res.Result
          res.Result.forEach((item) => {
            if (item.OrginalStudyList && Array.isArray(item.OrginalStudyList)) {
              item.OrginalStudyList.forEach((data) => {
                data.SubjectId = item.SubejctId
                data.VisitTaskId = item.VisitTaskId
                data.SourceSubjectVisitId = item.SourceSubjectVisitId
                this.subjectVisitId = item.SourceSubjectVisitId
                this.StudyInstanceUidList.push(data)
              })
            }
            if (item.UploadStudyList && Array.isArray(item.UploadStudyList)) {
              item.UploadStudyList.forEach((data) => {
                data.SopInstanceUidList &&
                  this.SopInstanceUidList.push(...data.SopInstanceUidList)
                data.VisitTaskId = item.VisitTaskId
                this.UploadStudyList.push(data)
              })
            }
          })
        }
      } catch (err) {
        console.log(err)
        this.loading = false
      }
    },
    // 删除
    async remove(item) {
      try {
        let confirm = await this.$confirm(
          this.$t('trials:uploadImage:confirm:delMessage'),
          {
            type: 'warning',
            distinguishCancelAndClose: true,
            confirmButtonText: this.$t('common:button:confirm'),
            cancelButtonText: this.$t('common:button:cancel'),
          }
        )
        if (confirm !== 'confirm') return
        let params = {
          VisitTaskId: item.VisitTaskId,
          IsDicom: true,
        }
        let res = await deleteTaskStudy(params)
        if (res.IsSuccess) {
          this.getList()
          this.$message.success(
            this.$t('trials:uploadImage:message:delSuccess')
          )
        }
      } catch (err) {
        console.log(err)
      }
    },
    // 当选择项发生变化时收集待上传文件数据
    handleSelectionChange(selection) {
      selection.sort((n1, n2) => {
        return n1.studyIndex - n2.studyIndex
      })
      this.selectArr = selection
    },
    // 根据是否上传状态决定CheckBox 是否可以勾选
    handleSelectable(row) {
      if (row.uploadState.selected || this.btnLoading) {
        return false
      } else {
        return true
      }
    },
    // 打开弹窗
    handleOpenDialog(item, list) {
      this.model_cfg.title = `${item.SubjectCode || ''} > ${item.TaskBlindName}`
      this.modelList = item[list]
      this.model_cfg.visible = true
    },
    // 校验上传数据
    async verifyIRStudyAllowUpload(list) {
      try {
        let data = {
          StudyInstanceUidList: list || [],
          TrialId: this.$route.query.trialId,
          SubjectCode: this.SubjectCode,
          SubjectId: this.SubjectId,
        }
        let res = await verifyIRStudyAllowUpload(data)
        if (res.IsSuccess) {
          return res.Result
        }
        return false
      } catch (err) {
        console.log(err)
        return false
      }
    },
    // 扫描待上传文件
    async beginScanFiles(e, id = null) {
      this.VisitTaskId = id
      this.hasOtherStudy = false
      var files = e.target.files
      if (files.length > 0) {
        var checkFiles = [...files]
        let max = checkFiles.some((item) => item.size > 20 * 1024 * 1024 * 1024)
        if (max)
          return this.$message.warning(
            this.$t('trials:uploadDicomList:message:maxFileSize')
          )
        let StudyInstanceUidList = []
        for (let i = 0; i < checkFiles.length; i++) {
          let item = checkFiles[i]
          var dicom = await parseDicom(item, 'StudyInstanceUid')
          let has = true,
            has2 = false,
            has3 = false
          if (!this.VisitTaskId) {
            has = this.StudyInstanceUidList.some(
              (item) => item.StudyInstanceUid === dicom.StudyInstanceUid
            )
          } else {
            has2 = this.StudyInstanceUidList.some((item) => {
              return (
                item.StudyInstanceUid === dicom.StudyInstanceUid &&
                item.VisitTaskId !== this.VisitTaskId
              )
            })
            has3 = this.UploadStudyList.some((item) => {
              return (
                item.StudyInstanceUid === dicom.StudyInstanceUid &&
                item.VisitTaskId !== this.VisitTaskId
              )
            })
          }

          if (!has || has2 || has3) {
            this.hasOtherStudy = true
            checkFiles.splice(i, 1)
            i--
          } else {
            if (!~StudyInstanceUidList.indexOf(dicom.StudyInstanceUid)) {
              StudyInstanceUidList.push(dicom.StudyInstanceUid)
            }
          }
        }
        this.errStudyUidList = []
        let res = await this.verifyIRStudyAllowUpload(StudyInstanceUidList)
        if (res) {
          res.forEach((item) => {
            if (!item.IsAllowUpload && !item.IsAllowReUpload) {
              this.errStudyUidList.push(item.StudyInstanceUid)
            }
          })
        }
        if (this.errStudyUidList && this.errStudyUidList.length > 0) {
          for (let i = 0; i < checkFiles.length; i++) {
            let item = checkFiles[i]
            var dicom = await parseDicom(item, 'StudyInstanceUid')
            if (!!~this.errStudyUidList.indexOf(dicom.StudyInstanceUid)) {
              this.hasOtherStudy = true
              checkFiles.splice(i, 1)
              i--
            }
          }
        }
        if (this.hasOtherStudy) {
          this.$confirm(this.$t('upload:dicom:confirmMessage:hasNotStudyUid'), {
            type: 'warning',
            distinguishCancelAndClose: true,
            confirmButtonText: this.$t('common:button:confirm'),
            cancelButtonText: this.$t('common:button:cancel'),
          })
        }

        var scope = this
        scope.scanState = ''
        scope.isScan = false
        var p = new Promise(function (resolve) {
          resolve()
        })
        var validFilesCount = 0
        for (var i = 0; i < checkFiles.length; ++i) {
          ;(function (index) {
            p = p.then(function () {
              if (
                checkFiles[index].name.toUpperCase().indexOf('DICOMDIR') === -1
              ) {
                validFilesCount = validFilesCount + 1
                return scope.parseDicomFile(checkFiles[index])
              }
            })
          })(i)
        }
        p.then(function (result) {
          scope.uploadQueues.forEach((v, i) => {
            scope.$refs.dicomFilesTable.toggleRowSelection(v, true)
          })
          scope.scanState = 'finished'
          scope.isScan = true
          scope.beginUploadQueues()
        })
      }
    },
    // 按序列UUID本地归档
    parseDicomFile(file) {
      var scope = this
      return new Promise(function (resolve, reject) {
        if (scope.scanState === 'cancelling') {
          resolve()
          return
        }
        var reader = new FileReader()
        reader.onload = function (e) {
          try {
            var data = dicomParser.parseDicom(new Uint8Array(e.target.result))
            var instanceUid = data.string('x00080018')
            if (!instanceUid) return resolve()
            var modality = data.string('x00080060') || ''
            var studyUid = data.string('x0020000d')
            if (!studyUid) return resolve()
            var pixelDataElement = data.elements.x7fe00010
            var studyIndex = 0
            while (
              studyIndex < scope.uploadQueues.length &&
              scope.uploadQueues[studyIndex].dicomInfo.studyUid !== studyUid &&
              (pixelDataElement || modality === 'SR') &&
              modality != ''
            ) {
              ++studyIndex
            }
            if (studyIndex >= scope.uploadQueues.length) {
              var date = data.string('x00080020')
              var time = data.string('x00080030')
              var studyTime = ''
              if (date) {
                date = `${date.substring(0, 4)}-${date.substring(
                  4,
                  6
                )}-${date.substring(6, 8)}`
              }
              if (time) {
                time = `${time.substring(0, 2)}:${time.substring(
                  2,
                  4
                )}:${time.substring(4, 6)}`
              }
              if (date) {
                studyTime = time ? `${date} ${time}` : `${date} 00:00:00`
              }
              const patientNameElement = data.elements.x00100010
              const patientNameBytes = new Uint8Array(
                data.byteArray.buffer,
                patientNameElement ? patientNameElement.dataOffset : 0,
                patientNameElement ? patientNameElement.length : 0
              )
              const patientNameStr = convertBytes(
                data.string('x00080005'),
                patientNameBytes
              )
              scope.uploadQueues.push({
                studyIndex: studyIndex,
                seriesList: [],
                fileList: [],
                dicomInfo: {
                  studyId: data.string('x00200010'),
                  studyUid: studyUid,
                  patientId: data.string('x00100020'),
                  patientName: patientNameStr,
                  patientAge: data.string('x00101010')
                    ? data.string('x00101010')
                    : '',
                  patientSex: data.string('x00100040')
                    ? data.string('x00100040')
                    : '',
                  patientBirthDate: data.string('x00100030'),
                  hospitalName: data.string('x00080080'),
                  accNumber: data.string('x00080050'),
                  bodyPart: data.string('x00180015') || '',
                  modality: [],
                  institutionName: data.string('x00080080'),
                  description: data.string('x00081030'),
                  //0008,0032
                  acquisitionTime: data.string('x00080032'),
                  acquisitionNumber: data.string('x00200012'),
                  triggerTime: data.string('x00181060'),
                  studyTime: studyTime,
                  VisitInfo: {},
                  SubjectInfo: {},
                  failedFileCount: 0,
                  uploadFileSize: 0,
                  fileSize: 0,
                  fileCount: 0,
                  isInit: false,
                  visitTaskId:
                    scope.VisitTaskId ||
                    scope.StudyInstanceUidList.find(
                      (item) => item.studyInstanceUid === studyUid
                    ).VisitTaskId,
                },

                uploadState: {
                  selected: false,
                  stateCode: '',
                  beginUploadTime: {},
                  progressValue: 0,
                },
              })
            }
            var modality = scope.uploadQueues[studyIndex].dicomInfo.modality
            var currentModality = data.string('x00080060')
            if (!(modality.indexOf(currentModality) > -1)) {
              modality.push(currentModality)
            }
            var fileList = scope.uploadQueues[studyIndex].fileList
            var instanceUid = data.string('x00080018')
            var instanceIndex = 0
            while (
              instanceIndex < fileList.length &&
              fileList[instanceIndex].instanceUid !== instanceUid &&
              (pixelDataElement || modality === 'SR')
            ) {
              ++instanceIndex
            }
            if (instanceIndex >= fileList.length) {
              fileList.push({
                instanceUid: instanceUid,
                file: file,
              })
            }
            scope.uploadQueues[studyIndex].dicomInfo.fileCount = fileList.length
            scope.uploadQueues[studyIndex].dicomInfo.fileSize = fileList.reduce(
              (prev, next) => {
                return prev + next.file.size
              },
              0
            )

            var seriesUid = data.string('x0020000e')
            var seriesList = scope.uploadQueues[studyIndex].seriesList
            var seriesItem = seriesList.find(function (item) {
              return item.seriesUid === seriesUid
            })
            if (!seriesItem && (pixelDataElement || modality === 'SR')) {
              var date = data.string('x00080021')
              var time = data.string('x00080031')
              var seriesTime = ''
              if (date) {
                date = `${date.substring(0, 4)}-${date.substring(
                  4,
                  6
                )}-${date.substring(6, 8)}`
              }
              if (time) {
                time = `${time.substring(0, 2)}:${time.substring(
                  2,
                  4
                )}:${time.substring(4, 6)}`
              }
              if (date) {
                seriesTime = time ? `${date} ${time}` : `${date} 00:00:00`
              }
              const seriesDescriptionElement = data.elements.x0008103e
              const seriesDescriptionBytes = new Uint8Array(
                data.byteArray.buffer,
                seriesDescriptionElement
                  ? seriesDescriptionElement.dataOffset
                  : 0,
                seriesDescriptionElement ? seriesDescriptionElement.length : 0
              )
              const seriesDescriptionStr = convertBytes(
                data.string('x00080005'),
                seriesDescriptionBytes
              )
              seriesItem = {
                seriesUid: seriesUid,
                seriesNumber: data.intString('x00200011') || 1,
                modality: data.string('x00080060') || '',
                description: seriesDescriptionStr,
                seriesTime: seriesTime,
                sliceThickness: data.string('x00180050') || '',
                imagePositionPatient: data.string('x00200032') || '',
                imageOrientationPatient: data.string('x00200037') || '',
                sequenceName: data.string('x00180024') || '',
                protocolName: data.string('x00181030') || '',
                imagerPixelSpacing: data.string('x00181164') || '',
                instanceList: [],
              }
              seriesList.push(seriesItem)
            }
            var instanceList = seriesItem.instanceList
            var instanceItem = instanceList.find(function (item) {
              return item.instanceUid === instanceUid
            })
            if (!instanceItem) {
              var date = data.string('x00080023')
              var time = data.string('x00080033')
              var instanceTime = ''
              if (date) {
                date = `${date.substring(0, 4)}-${date.substring(
                  4,
                  6
                )}-${date.substring(6, 8)}`
              }
              if (time) {
                time = `${time.substring(0, 2)}:${time.substring(
                  2,
                  4
                )}:${time.substring(4, 6)}`
              }
              if (date) {
                instanceTime = time ? `${date} ${time}` : `${date} 00:00:00`
              }
              instanceItem = {
                instanceUid: instanceUid,
                instanceNumber: data.intString('x00200013') || 1,
                frameCount: data.intString('x00280008') || 1,
                instanceTime: instanceTime,
                imageRows: data.uint16('x00280010') || 0,
                imageColumns: data.uint16('x00280011') || 0,
                sliceLocation: data.intString('x00201041') || 0,
                sliceThickness: data.string('x00180050') || '',
                numberOfFrames: data.intString('x00280008') || 0,
                pixelSpacing: data.string('x00280030') || '',
                imagerPixelSpacing: data.string('x00181164') || '',
                frameOfReferenceUID: data.string('x00200052') || '',
                windowCenter: data.string('x00281050') || '',
                windowWidth: data.string('x00281051') || '',
                modality: data.string('x00080060') || '',
                file: file,
                FileSize: file.size,
              }
              instanceList.push(instanceItem)
            }
            resolve()
          } catch (error) {
            console.log(error)
            resolve()
          }
        }
        reader.onerror = function (e) {
          resolve()
        }
        reader.readAsArrayBuffer(file)
      })
    },
    // 上传之前校验基本信息及检查是否已上传
    beginUploadQueues() {
      this.scanState = 'uploading'
      this.studyErrorList = []
      // console.log(this.uploadQueues, this.selectArr)
      this.warningArr = []
      for (let i = 0; i < this.selectArr.length; ++i) {
        const index = this.selectArr[i].studyIndex
        this.uploadQueues[index].uploadState.stateCode = 'uploading'
        this.verifyBasicInfos(index)
      }
      if (this.warningArr.length) {
        this.warning_cfg.visible = true
        this.btnLoading = false
      } else {
        this.verifyStudy()
      }
    },
    // 校验影像中检查时间、性别是否与受试者匹配
    verifyBasicInfos(index) {
      var warnings = []
      if (
        this.uploadQueues[index].dicomInfo.patientSex &&
        this.form.SubjectSex
      ) {
        if (
          this.uploadQueues[index].dicomInfo.patientSex.substr(0, 1) !==
          this.form.SubjectSex.substr(0, 1)
        ) {
          warnings.push(
            this.$t('trials:uploadDicomList:message:genderConsistent')
          )
        }
      }
      if (warnings.length > 0) {
        this.warningArr.push({
          index: this.uploadQueues[index].studyIndex + 1,
          accNumber: this.uploadQueues[index].dicomInfo.accNumber,
          warnings: warnings,
        })
      }
    },
    // 校验该检查是否上传过
    async verifyStudy() {
      this.btnLoading = true
      var studyList = []
      this.selectArr.forEach((item) => {
        if (!item.uploadState.selected) {
          studyList.push({
            studyInstanceUid: item.dicomInfo.studyUid,
            studyDate: item.dicomInfo.studyTime,
          })
        }
      })
      this.uploadCount = this.selectArr.length
      this.uploadedCount = 0
      for (let i = 0; i < this.selectArr.length; i++) {
        const index = this.selectArr[i].studyIndex
        if (!this.uploadQueues[index].uploadState.selected) {
          await this.archiveStudy(index)
        }
      }
      this.$set(this, 'uploadQueues', [
        ...this.uploadQueues.filter((v) => {
          return (
            !v.uploadState.record ||
            (v.uploadState.record && !!v.uploadState.record.Failed.length)
          )
        }),
      ])
      this.$nextTick(() => {
        this.selectArr = []
        this.uploadQueues.forEach((v, i) => {
          if (v.uploadState.record) {
            v.uploadState.selected = false
            this.$refs.dicomFilesTable.toggleRowSelection(v, true)
          }
          v.studyIndex = i
        })
        this.$refs.pathClear.value = ''
        this.list.forEach((item) => {
          this.$refs[`pathClear_${item.Id}`].value = ''
        })
        this.btnLoading = false
        if (this.studyErrorList.length > 0) {
          let msg = this.$t('trials:uploadDicomFiles2:message:studyErrorList')
          msg = msg.replaceAll('xxx', this.studyErrorList.join('、'))
          this.$confirm(msg, this.$t('trials:hotkeys:message:tip'), {
            confirmButtonText: this.$t(
              'trials:uploadDicomFiles2:button:reupload'
            ),
          }).then(() => {
            this.beginUploadQueues()
          })
        }
      })
    },
    // 上传影像并归档
    archiveStudy(index, config) {
      var scope = this
      return new Promise(function (resolve, reject) {
        try {
          preArchiveDicomStudy({
            trialId: scope.trialId,
            subjectId: scope.SubjectId,
            subjectVisitId: scope.subjectVisitId,
            fileSize: scope.uploadQueues[index].dicomInfo.fileSize,
            fileCount: scope.uploadQueues[index].dicomInfo.fileCount,
            IsDicomReUpload:
              scope.uploadQueues[index].uploadState.AllowReUpload,
          })
            .then(async (res) => {
              scope.uploadQueues[index].dicomInfo.failedFileCount = 0
              scope.$set(scope.uploadQueues[index].dicomInfo, 'isInit', true)
              let dicomInfo = scope.uploadQueues[index].dicomInfo
              let seriesNum = scope.uploadQueues[index].seriesList.length
              let fileNum = scope.uploadQueues[index].fileList.length
              let seriesList = scope.uploadQueues[index].seriesList
              dicomInfo.seriesNum = seriesNum
              dicomInfo.fileNum = fileNum
              dicomInfo.subjectId = scope.SubjectId
              dicomInfo.subjectVisitId = scope.subjectVisitId
              let t = setInterval(() => {
                dicomUploadInProgress({
                  trialId: scope.trialId,
                  studyInstanceUid: dicomInfo.studyUid,
                }).then((res) => {})
              }, 5000)
              scope.myInterval.push(t)
              let Record = {
                Failed: [],
                Existed: [],
                Uploaded: [],
                FileCount: 0,
              }
              let params = {
                trialId: scope.trialId,
                subjectId: scope.SubjectId,
                subjectVisitId: scope.subjectVisitId,
                studyMonitorId: res.Result,
                failedFileCount: 0,
                RecordPath: null,
                study: {
                  studyId: dicomInfo.studyId,
                  studyInstanceUid: dicomInfo.studyUid,
                  studyTime: dicomInfo.studyTime,
                  description: dicomInfo.description,
                  seriesCount: dicomInfo.seriesNum,
                  instanceCount: dicomInfo.fileNum,
                  institutionName: dicomInfo.institutionName,
                  patientId: dicomInfo.patientId,
                  patientName: '',
                  patientAge: '',
                  patientSex: dicomInfo.patientSex,
                  accessionNumber: dicomInfo.accNumber,
                  patientBirthDate: '',
                  acquisitionTime: dicomInfo.acquisitionTime,
                  acquisitionNumber: dicomInfo.acquisitionNumber,
                  triggerTime: dicomInfo.triggerTime,
                  bodyPartExamined: '',
                  seriesList: [],
                },
              }
              let arr = []
              for (let i = 0; i < seriesList.length; i++) {
                let v = seriesList[i]
                let instanceList = []
                let ImageResizePath
                for (let ii = 0; ii < v.instanceList.length; ii++) {
                  arr.push(
                    (function () {
                      return new Promise(async (resolve1) => {
                        try {
                          let o = v.instanceList[ii]
                          let name = `${v.instanceList[ii].file.webkitRelativePath}_${v.instanceList[ii].instanceUid}`
                          if (o.isReUpload) {
                            dicomInfo.failedFileCount++
                            dicomInfo.uploadFileSize += o.file.size
                            Record.Existed.push(name)
                            Record.FileCount++
                          } else if (o.myPath) {
                            instanceList.push({
                              studyInstanceUid: dicomInfo.studyUid,
                              seriesInstanceUid: v.seriesUid,
                              sopInstanceUid: o.instanceUid,
                              instanceNumber: o.instanceNumber,
                              instanceTime: o.instanceTime,
                              imageRows: o.imageRows,
                              imageColumns: o.imageColumns,
                              sliceLocation: o.sliceLocation,
                              sliceThickness: o.sliceThickness,
                              numberOfFrames: o.numberOfFrames,
                              pixelSpacing: o.pixelSpacing,
                              imagerPixelSpacing: o.imagerPixelSpacing,
                              frameOfReferenceUID: o.frameOfReferenceUID,
                              windowCenter: o.windowCenter,
                              windowWidth: o.windowWidth,
                              path: o.myPath,
                              FileSize: o.FileSize,
                            })
                            Record.Uploaded.push(name)
                            dicomInfo.failedFileCount++
                            Record.FileCount++
                          } else {
                            let path = `/${params.trialId}/Image/${
                              params.subjectId
                            }/${params.subjectVisitId}/${
                              dicomInfo.visitTaskId
                            }/${scope.getGuid(
                              dicomInfo.studyUid +
                                v.seriesUid +
                                o.instanceUid +
                                params.trialId
                            )}`
                            if (scope.isClose) return
                            let res = await dcmUpload(
                              {
                                path: path,
                                file: o.file,
                                speed: true,
                              },
                              null,
                              (percentage, checkpoint, lastPer) => {
                                dicomInfo.uploadFileSize +=
                                  checkpoint.size * (percentage - lastPer)
                                if (
                                  dicomInfo.uploadFileSize > dicomInfo.fileSize
                                ) {
                                  dicomInfo.uploadFileSize = dicomInfo.fileSize
                                }
                              }
                            )
                            if (!res || !res.url) {
                              params.failedFileCount++
                            } else {
                              if (ii === 0 && o.modality !== 'SR') {
                                try {
                                  let fileId =
                                    cornerstoneWADOImageLoader.wadouri.fileManager.add(
                                      o.file
                                    )
                                  let blob = await scope.dicomToPng(
                                    fileId,
                                    o.imageColumns,
                                    o.imageRows
                                  )
                                  let thumbnailPath = `/${params.trialId}/Image/${params.subjectId}/${params.subjectVisitId}/${dicomInfo.visitTaskId}/${dicomInfo.studyUid}/${v.seriesUid}.png`
                                  let OSSclient = scope.OSSclient
                                  let seriesRes = await OSSclient.put(
                                    thumbnailPath,
                                    blob
                                  )
                                  if (seriesRes && seriesRes.url) {
                                    ImageResizePath = scope.$getObjectName(
                                      seriesRes.url
                                    )
                                  }
                                } catch (e) {
                                  console.log(e)
                                }
                              }
                            }
                            if (res && res.url) {
                              instanceList.push({
                                studyInstanceUid: dicomInfo.studyUid,
                                seriesInstanceUid: v.seriesUid,
                                sopInstanceUid: o.instanceUid,
                                instanceNumber: o.instanceNumber,
                                instanceTime: o.instanceTime,
                                imageRows: o.imageRows,
                                imageColumns: o.imageColumns,
                                sliceLocation: o.sliceLocation,
                                sliceThickness: o.sliceThickness,
                                numberOfFrames: o.numberOfFrames,
                                pixelSpacing: o.pixelSpacing,
                                imagerPixelSpacing: o.imagerPixelSpacing,
                                frameOfReferenceUID: o.frameOfReferenceUID,
                                windowCenter: o.windowCenter,
                                windowWidth: o.windowWidth,
                                path: scope.$getObjectName(res.url),
                                FileSize: o.FileSize,
                              })
                              o.myPath = scope.$getObjectName(res.url)
                              Record.Uploaded.push(name)
                              dicomInfo.failedFileCount++
                              Record.FileCount++
                            } else {
                              Record.Failed.push(name)
                              Record.FileCount++
                            }
                          }
                          resolve1()
                        } catch (e) {
                          console.log(e)
                          resolve1()
                        }
                      })
                    })()
                  )
                  if (
                    (arr.length >= 10 || ii === v.instanceList.length - 1) &&
                    !scope.isClose
                  ) {
                    await Promise.all(arr)
                    arr = []
                  }
                }
                params.study.seriesList.push({
                  studyInstanceUid: dicomInfo.studyUid,
                  seriesInstanceUid: v.seriesUid,
                  seriesNumber: v.seriesNumber,
                  seriesTime: v.seriesTime,
                  sliceThickness: v.sliceThickness,
                  imagePositionPatient: v.imagePositionPatient,
                  imageOrientationPatient: v.imageOrientationPatient,
                  sequenceName: v.sequenceName,
                  protocolName: v.protocolName,
                  imagerPixelSpacing: v.imagerPixelSpacing,
                  acquisitionTime: dicomInfo.acquisitionTime,
                  acquisitionNumber: dicomInfo.acquisitionNumber,
                  triggerTime: dicomInfo.triggerTime,
                  modality: v.modality,
                  description: v.description,
                  instanceCount: v.instanceList.length,
                  bodyPartExamined: dicomInfo.bodyPart,
                  instanceList: instanceList,
                  ImageResizePath: ImageResizePath,
                })
              }
              let text = JSON.stringify(Record)
              let logJsonBlob = scope.generateTxtFile(text)
              let logJsonObjectName = `/${params.trialId}/Image/${params.subjectId}/${params.subjectVisitId}/${dicomInfo.visitTaskId}/${dicomInfo.studyUid}/${params.studyMonitorId}.txt`
              let logRes
              try {
                logRes = await scope.OSSclient.put(
                  logJsonObjectName,
                  logJsonBlob
                )
              } catch (e) {
                scope.uploadQueues[index].uploadState.record = Record
                scope.studyErrorList.push(dicomInfo.accNumber)
                clearInterval(t)
                resolve()
              }
              for (let i = 0; i < seriesList.length; i++) {
                let v = seriesList[i]
                let o = params.study.seriesList.find((o) => {
                  return o.seriesInstanceUid === v.seriesUid
                })
                if (o && !o.ImageResizePath) {
                  let fileId =
                    cornerstoneWADOImageLoader.wadouri.fileManager.add(
                      v.instanceList[0].file
                    )
                  let blob = await scope.dicomToPng(
                    fileId,
                    v.instanceList[0].imageColumns,
                    v.instanceList[0].imageRows
                  )
                  let thumbnailPath = `/${params.trialId}/Image/${params.trialSiteId}/${params.subjectId}/${params.subjectVisitId}/${dicomInfo.studyUid}/${v.seriesUid}.png`
                  let OSSclient = scope.OSSclient
                  try {
                    let seriesRes = await OSSclient.put(thumbnailPath, blob)
                    if (seriesRes && seriesRes.url) {
                      o.ImageResizePath = scope.$getObjectName(seriesRes.url)
                    }
                  } catch (e) {
                    console.log(e)
                  }
                }
              }
              if (logRes && logRes.url) {
                params.study.instanceCount = dicomInfo.failedFileCount
                params.RecordPath = scope.$getObjectName(logRes.url)
                if (scope.isClose) return false
                console.log(params)
                params.VisitTaskId = dicomInfo.visitTaskId
                addOrUpdateArchiveTaskStudy(params)
                  .then((res) => {
                    if (dicomInfo.failedFileCount === dicomInfo.fileCount) {
                      scope.$message.success(
                        scope.$t('trials:uploadDicomList:label:uploaded')
                      )
                    } else {
                      scope.studyErrorList.push(dicomInfo.accNumber)
                    }
                    scope.uploadQueues[index].uploadState.record = Record
                    scope.getList()
                    if (
                      scope.$route.path !==
                      '/trials/trials-panel/visit/crc-question'
                    ) {
                      scope.$emit('getList')
                    }
                    clearInterval(t)
                    resolve()
                  })
                  .catch((res) => {
                    scope.uploadQueues[index].uploadState.record = Record
                    scope.studyErrorList.push(dicomInfo.accNumber)
                    clearInterval(t)
                    resolve()
                  })
              } else {
                scope.uploadQueues[index].uploadState.record = Record
                scope.studyErrorList.push(dicomInfo.accNumber)
                clearInterval(t)
                resolve()
              }
            })
            .catch((err) => {
              console.log(err)
              let Record = {
                Failed: [],
                Existed: [],
                Uploaded: [],
                FileCount: 0,
              }
              let fileList = scope.uploadQueues[index].fileList
              fileList.forEach((v) => {
                Record.Failed.push(v.webkitRelativePath)
              })
              scope.uploadQueues[index].uploadState.record = Record
              scope.studyErrorList.push(dicomInfo.accNumber)
              resolve()
            })
        } catch (e) {
          console.log(e)
          resolve()
        }
      })
    },
    dicomToPng(imageId, width, height) {
      return new Promise((resolve) => {
        cornerstone.loadImage(imageId).then(async (image) => {
          let canvas = document.createElement('canvas')
          canvas.width = width
          canvas.height = height
          if (image) {
            cornerstone.renderToCanvas(canvas, image)
            // 将 Canvas 图像对象转换为 PNG 格式
            let blob = await this.canvasToBlob(canvas)
            resolve(blob)
          } else {
            resolve()
          }
        })
      }).catch((reason) => {
        reason()
      })
    },
    canvasToBlob(canvas) {
      return new Promise((resolve) => {
        canvas.toBlob((blob) => {
          resolve(blob)
        })
      })
    },
    generateTxtFile(text) {
      let blob = new Blob(['\ufeff', text], { type: 'text/plain' })
      return blob
    },
    // 预览阅片影像
    handleViewReadingImages(row) {
      if (this.open) {
        this.open.close()
      }
      var token = getToken()
      let trialId = this.$route.query.trialId
      const routeData = this.$router.resolve({
        path: `/showvisitdicoms?trialId=${trialId}&subjectVisitId=${row.SourceSubjectVisitId}&isReading=1&TokenKey=${token}`,
      })
      this.open = window.open(routeData.href, '_blank')
    },
  },
}
</script>
<style lang="scss" scoped>
.top {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.btnBox,
.form-group {
  display: flex;
  align-items: center;
}
#inputForm .file-input {
  position: relative;
  overflow: hidden;
  display: inline-block;
}
#inputForm .file-input input[type='file'] {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}
</style>