hir_web/src/views/trials/trials-panel/hirVisit/index.vue

503 lines
16 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<BaseContainer>
<!-- 搜索框 -->
<template slot="search-container">
<el-form :inline="true">
<!-- 受试者编号 -->
<el-form-item :label="$t('trials:crcQuestion:table:subjectId')">
<el-input
v-model="searchData.SubjectCode"
clearable
style="width: 140px"
/>
</el-form-item>
<!-- 患者姓名 -->
<el-form-item :label="$t('trials:uploadDicomList:table:patientName')">
<el-input
v-model="searchData.SubjectShortName"
clearable
style="width: 140px"
/>
</el-form-item>
<!-- 患者性别 -->
<el-form-item :label="$t('trials:subject:table:gender')">
<el-select
v-model="searchData.SubjectSex"
clearable
filterable
style="width: 150px"
>
<el-option
v-for="item of $d.sex"
:key="item.id"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<!-- 访视名称 -->
<!-- <el-form-item :label="$t('trials:globalReview:table:visitName')">
<el-select
v-model="searchData.SiteId"
clearable
filterable
style="width: 150px"
>
<el-option
v-for="item of visitOptions"
:key="item.SiteId"
:label="item.TrialSiteCode"
:value="item.SiteId"
/>
</el-select>
</el-form-item> -->
<!-- 状态 -->
<!-- <el-form-item :label="$t('trials:trials-list:table:status')">
<el-select
v-model="searchData.SiteId"
clearable
filterable
style="width: 150px"
>
<el-option
v-for="item of siteOptions"
:key="item.SiteId"
:label="item.TrialSiteCode"
:value="item.SiteId"
/>
</el-select>
</el-form-item> -->
<el-form-item>
<!-- 查询 -->
<el-button type="primary" icon="el-icon-search" @click="handleSearch">
{{ $t("common:button:search") }}
</el-button>
<!-- 重置 -->
<el-button
type="primary"
icon="el-icon-refresh-left"
@click="handleReset"
>
{{ $t("common:button:reset") }}
</el-button>
</el-form-item>
</el-form>
</template>
<!-- 访视列表 -->
<template slot="main-container">
<el-table
v-loading="loading"
v-adaptive="{ bottomOffset: 60 }"
:data="list"
stripe
height="100"
@sort-change="handleSortByColumn"
>
<el-table-column width="40">
<template>
<i
class="el-icon-warning-outline"
:title="$t('trials:hirVisit:tipMessage:tipOne')"
style="color: red"
></i>
</template>
</el-table-column>
<el-table-column type="index" width="40" />
<!-- 受试者编号 -->
<el-table-column
prop="SubjectCode"
:label="$t('trials:uploadMonitor:table:subjectId')"
show-overflow-tooltip
/>
<!-- 患者编号 -->
<el-table-column
prop="PatientList.PatientIdStr"
:label="$t('trials:uploadDicomList:table:pId')"
show-overflow-tooltip
>
<template slot-scope="scope">
<span
v-for="(item, index) in scope.row.PatientList"
:key="`${index}${item.PatientId}`"
>
{{
index === scope.row.PatientList.length - 1
? item.PatientIdStr
: `${item.PatientIdStr}, `
}}
</span>
</template>
</el-table-column>
<!-- 患者姓名 -->
<el-table-column
prop="SubjectShortName"
:label="$t('trials:uploadDicomList:table:patientName')"
show-overflow-tooltip
/>
<!-- 性别 -->
<el-table-column
prop="SubjectSex"
:label="$t('trials:subject:table:gender')"
show-overflow-tooltip
/>
<!-- 访视名称 -->
<el-table-column
prop="VisitName"
:label="$t('trials:uploadMonitor:table:visitName')"
show-overflow-tooltip
/>
<!-- 数据收集 -->
<!-- <el-table-column
prop="StudyCode"
:label="$t('trials:crcUpload:table:dataCollected')"
show-overflow-tooltip
/> -->
<!-- 最早拍片日期 -->
<el-table-column
prop="VisitEarliestStudyTime"
:label="$t('trials:trials-panel:table:EarliestScanDate')"
show-overflow-tooltip
sortable="custom"
/>
<!-- 最晚拍片日期 -->
<el-table-column
prop="VisitLatestStudyTime"
:label="$t('trials:linkedRP:table:latestScanDate')"
show-overflow-tooltip
sortable="custom"
/>
<!-- 状态 -->
<el-table-column
prop="SubmitState"
:label="$t('trials:trials-list:table:status')"
show-overflow-tooltip
sortable="custom"
>
<template slot-scope="scope">
<el-tag v-if="scope.row.SubmitState * 1 === 0" type="warning">{{
$fd("SubmitState", scope.row.SubmitState * 1)
}}</el-tag>
<el-tag v-else-if="scope.row.SubmitState * 1 === 1" type="danger">{{
$fd("SubmitState", scope.row.SubmitState * 1)
}}</el-tag>
<el-tag v-else-if="scope.row.SubmitState * 1 === 2">{{
$fd("SubmitState", scope.row.SubmitState * 1)
}}</el-tag>
</template>
</el-table-column>
<!-- 提交时间 -->
<el-table-column
prop="SubmitTime"
:label="$t('trials:crcUpload:table:submitTime')"
show-overflow-tooltip
sortable="custom"
/>
<!--操作-->
<el-table-column
:label="$t('common:action:action')"
min-width="100"
fixed="right"
v-if="
hasPermi(['trials:trials-panel:hirVisit:edit']) ||
hasPermi(['trials:trials-panel:hirVisit:submit']) ||
hasPermi(['trials:trials-panel:hirVisit:remove']) ||
hasPermi(['trials:trials-panel:hirVisit:result']) ||
hasPermi(['trials:trials-panel:hirVisit:downlaod'])
"
>
<template slot-scope="scope">
<!---->
<el-button
type="text"
v-hasPermi="['trials:trials-panel:hirVisit:edit']"
@click.stop="editStudy(scope.row)"
>{{ $t("trials:hirVisit:button:editStudy") }}</el-button
>
<!--提交-->
<el-button
type="text"
v-hasPermi="['trials:trials-panel:hirVisit:submit']"
@click.stop="submit(scope.row)"
>{{ $t("common:button:submit") }}</el-button
>
<!--删除-->
<el-button
type="text"
v-hasPermi="['trials:trials-panel:hirVisit:remove']"
@click.stop="remove(scope.row)"
>{{ $t("common:button:delete") }}</el-button
>
<!--评估结果-->
<el-button
type="text"
v-hasPermi="['trials:trials-panel:hirVisit:result']"
@click.stop="result(scope.row)"
>{{ $t("trials:adReview:title:result") }}</el-button
>
<!--下载影像-->
<el-button
type="text"
v-hasPermi="['trials:trials-panel:hirVisit:download']"
@click.stop="downloadImage(scope.row)"
>{{ $t("trials:reading:button:uploadImages") }}</el-button
>
<!--下载医疗报告-->
<el-button
type="text"
v-hasPermi="['trials:trials-panel:hirVisit:download']"
@click.stop="downloadReport(scope.row)"
>{{ $t("trials:reading:button:uploadReport") }}</el-button
>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<pagination
class="page"
:total="total"
:page.sync="searchData.PageIndex"
:limit.sync="searchData.PageSize"
@pagination="getList"
/>
</template>
<!--修改检查-->
<editStudyList
:visible.sync="editStudyVisible"
:data="editStudyData"
v-if="editStudyVisible"
/>
</BaseContainer>
</template>
<script>
import BaseContainer from "@/components/BaseContainer";
import Pagination from "@/components/Pagination";
import editStudyList from "./components/edit-study-list.vue";
import {
getPatientSubejctVisitList,
getSubjectImageZipInfo,
} from "@/api/trials/visit.js";
import { submitVisitStudyBinding } from "@/api/inspection.js";
import JSZip from "jszip";
import axios from "axios";
import { saveAs } from "file-saver";
const defaultSearchData = () => {
return {
subjectCode: null,
subjectShortName: null,
subjectSex: null,
pageIndex: 1,
pageSize: 20,
asc: false,
sortField: "SubmitTime",
};
};
export default {
name: "hirVisit",
components: { BaseContainer, Pagination, editStudyList },
data() {
return {
// 查询
searchData: defaultSearchData(),
visitOptions: [],
// 列表
list: [
{
StudyCode: 1,
},
],
loading: false,
total: 0,
// 修改检查
editStudyVisible: false,
editStudyData: {},
};
},
created() {
this.getList();
},
methods: {
// 查询
handleSearch() {
this.getList();
},
// 重置
handleReset() {
this.searchData = defaultSearchData();
this.getList();
},
// 排序
handleSortByColumn(sort) {
this.searchData.SortField = sort.prop;
if (sort.order === "ascending") this.searchData.Asc = true;
if (sort.order === "descending") this.searchData.Asc = false;
if (!sort.order) this.searchData.SortField = null;
this.getList();
},
// 获取列表
async getList() {
let data = {};
Object.keys(this.searchData).forEach((key) => {
data[key] = this.searchData[key];
});
data.TrialId = this.$route.query.trialId;
try {
this.loading = true;
let res = await getPatientSubejctVisitList(data);
this.loading = false;
if (res.IsSuccess) {
this.list = res.Result.CurrentPageData;
this.total = res.Result.TotalCount;
}
} catch (err) {
this.loading = false;
console.log(err);
}
},
// 修改检查
editStudy(item) {
this.editStudyData = item;
this.editStudyVisible = true;
},
// 提交
async submit(item) {
let confirm = await this.$confirm(
this.$t("trials:adjustRecord:message:confirm"),
{
type: "warning",
distinguishCancelAndClose: true,
confirmButtonText: this.$t("common:button:confirm"),
cancelButtonText: this.$t("recompose:button:cancel"),
}
);
if (confirm !== "confirm") return;
let data = {
TrialId: this.$route.query.trialId,
SubjectVisitId: [item.SubjectVisitId],
};
try {
this.loading = true;
let res = await submitVisitStudyBinding(data);
this.loading = false;
if (res.IsSuccess) {
this.$message.success(
this.$t("trials:crcUpload:message:submittedSuccessfully")
);
}
} catch (err) {
this.btnLoading2 = false;
console.log(err);
}
},
// 删除
remove() {},
// 评估结果
result() {},
// 下载报告
downloadReport() {},
// 下载影像
async downloadImage(item) {
try {
let res = await getSubjectImageZipInfo(item.SubjectId);
if (res.IsSuccess) {
let item = res.Result;
await this.setfolder(item);
}
} catch (err) {
console.log(err);
}
},
async setfolder(item) {
const zip = new JSZip(); // 创建实例对象
let zipObj = {};
const promises = [];
for (let patient of item.PatientList) {
if (!zipObj[patient.PatientIdStr]) {
zipObj[patient.PatientIdStr] = zip.folder(patient.PatientIdStr);
console.log(zipObj[patient.PatientIdStr]);
}
for (let visit of patient.VisitList) {
for (let study of visit.StudyList) {
let date = study.StudyTime.split(" ")[0];
if (!zipObj[`${patient.PatientIdStr}${date}`]) {
zipObj[`${patient.PatientIdStr}${date}`] =
zipObj[patient.PatientIdStr].folder(date);
}
for (let series of study.SeriesList) {
if (!zipObj[`${patient.PatientIdStr}${date}${series.Modality}`]) {
zipObj[`${patient.PatientIdStr}${date}${series.Modality}`] =
zipObj[`${patient.PatientIdStr}${date}`].folder(
series.Modality
);
}
for (let instance of series.InstancePathList) {
let obj = {
subjectCode: item.SubjectCode,
patientIdStr: patient.PatientIdStr,
visitName: visit.VisitName,
date: study.StudyTime.split(" ")[0],
modality: series.Modality,
instancePath: instance.Path,
dicomName: instance.Path.split("/Dicom/")[1],
};
const promise = this.handleBatchDown(
obj,
zipObj[`${patient.PatientIdStr}${date}${series.Modality}`]
);
promises.push(promise);
}
}
}
}
}
// 生成 zip 文件
Promise.all(promises)
.then(() => {
// 生成zip 文件
zip
.generateAsync({
type: "blob",
compression: "DEFLATE", // STORE: 默认不压缩, DEFLATE需要压缩
compressionOptions: {
level: 9, // 压缩等级 1~9 1 压缩速度最快, 9 最优压缩方式
},
})
.then((res) => {
saveAs(res, item.SubjectCode + new Date().getTime() + "_CV.zip"); // 使用FileSaver.saveAs保存文件文件名可自定义
zipObj = null;
});
})
.catch((reason) => {});
},
async handleBatchDown(item, zip) {
return new Promise((resolve) => {
let path = `/${item.subjectCode}_${item.patientIdStr}/${item.visitName}/${item.date}_${item.modality}${item.instancePath}`;
this.getFileData(
this.OSSclientConfig.basePath + path
// "https://th.bing.com/th/id/OIP.duz6S7Fvygrqd6Yj_DcXAQHaF7?rs=1&pid=ImgDetMain"
).then((res) => {
const fileName = item.dicomName + ".dcm";
zip.file(fileName, res.data, { binary: true });
resolve();
});
});
},
getFileData(fileUrl) {
return new Promise((resolve, reject) => {
axios(fileUrl, {
method: "GET",
responseType: "blob", // 返回的数据会被强制转为blob类型 转换成arraybuffer 也行
})
.then((res) => {
resolve(res);
})
.catch((error) => {
reject(error);
});
});
},
},
};
</script>