pacs
continuous-integration/drone/push Build is passing Details

uat_us
wangxiaoshuang 2024-07-17 10:09:26 +08:00
parent 7f36aa5a05
commit e51e7d0e66
10 changed files with 1809 additions and 424 deletions

156
package-lock.json generated
View File

@ -2820,36 +2820,6 @@
}
}
},
"chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"optional": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"dependencies": {
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"optional": true
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"optional": true,
"requires": {
"has-flag": "^4.0.0"
}
}
}
},
"chokidar": {
"version": "2.1.8",
"resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-2.1.8.tgz",
@ -3229,13 +3199,6 @@
}
}
},
"json5": {
"version": "2.2.3",
"resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true,
"optional": true
},
"locate-path": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-3.0.0.tgz",
@ -3479,32 +3442,6 @@
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
"dev": true
},
"vue-loader-v16": {
"version": "npm:vue-loader@16.8.3",
"resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-16.8.3.tgz",
"integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==",
"dev": true,
"optional": true,
"requires": {
"chalk": "^4.1.0",
"hash-sum": "^2.0.0",
"loader-utils": "^2.0.0"
},
"dependencies": {
"loader-utils": {
"version": "2.0.4",
"resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz",
"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
"dev": true,
"optional": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
}
}
},
"webpack-dev-middleware": {
"version": "3.7.3",
"resolved": "https://registry.npmmirror.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz",
@ -14228,6 +14165,11 @@
"integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==",
"dev": true
},
"qrcodejs2": {
"version": "0.0.2",
"resolved": "https://registry.npmmirror.com/qrcodejs2/-/qrcodejs2-0.0.2.tgz",
"integrity": "sha512-+Y4HA+cb6qUzdgvI3KML8GYpMFwB24dFwzMkS/yXq6hwtUGNUnZQdUnksrV1XGMc2mid5ROw5SAuY9XhI3ValA=="
},
"qs": {
"version": "6.11.2",
"resolved": "https://registry.npmmirror.com/qs/-/qs-6.11.2.tgz",
@ -17518,6 +17460,94 @@
}
}
},
"vue-loader-v16": {
"version": "npm:vue-loader@16.8.3",
"resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-16.8.3.tgz",
"integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==",
"dev": true,
"optional": true,
"requires": {
"chalk": "^4.1.0",
"hash-sum": "^2.0.0",
"loader-utils": "^2.0.0"
},
"dependencies": {
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"optional": true,
"requires": {
"color-convert": "^2.0.1"
}
},
"chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"optional": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"optional": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true,
"optional": true
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"optional": true
},
"json5": {
"version": "2.2.3",
"resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true,
"optional": true
},
"loader-utils": {
"version": "2.0.4",
"resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz",
"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
"dev": true,
"optional": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"optional": true,
"requires": {
"has-flag": "^4.0.0"
}
}
}
},
"vue-pdf": {
"version": "4.3.0",
"resolved": "https://registry.npmmirror.com/vue-pdf/-/vue-pdf-4.3.0.tgz",

View File

@ -3745,4 +3745,44 @@ export function ConfigTrialPACSInfoConfirm(data) {
method: 'post',
data
})
}
// 获取推送记录
export function getSCPImageUploadList(data) {
return request({
url: `/Patient/getSCPImageUploadList`,
method: 'post',
data
})
}
// 获取影像检查患者列表
export function getPatientList(data) {
return request({
url: `/Patient/getPatientList`,
method: 'post',
data
})
}
// 获取影像检查患者检查列表
export function getPatientStudyList(data) {
return request({
url: `/Patient/getPatientStudyList`,
method: 'post',
data
})
}
// 获取接收方AE列表
export function getDicomCalledAEList(params) {
return request({
url: `/Patient/getDicomCalledAEList`,
method: 'get',
params
})
}
// 获取发送方AE列表
export function getDicomCallingAEList(params) {
return request({
url: `/Patient/getDicomCallingAEList`,
method: 'get',
params
})
}

View File

@ -4,14 +4,15 @@
<el-tabs v-model="trialsTab" @tab-click="clickTab">
<el-tab-pane v-for="item of trialsRouter.children.find(v => {return v.name == 'TrialsPanel'}).children" :key="`tab${item.path}`" :disabled="TotalNeedSignTrialDocCount !== 0 && item.path !== '/trials/trials-panel/attachments'" :label="$t(item.LanguageMark)" :name="item.path">
<el-tabs v-if="!item.tabHiddn" v-model="trialsTabChild" @tab-click="clickTab">
<el-tab-pane
v-for="item1 of item.children"
v-if="TrialConfig && isShow(item1.path)"
:key="`tab1${item1.path}`"
:disabled="TotalNeedSignTrialDocCount !== 0 && item1.path !== '/trials/trials-panel/attachments/self-attachment' || (TrialStatusStr === 'Initializing' && (item1.path === '/trials/trials-panel/setting/personnel-manage' || item1.path === '/trials/trials-panel/setting/qc-question' || item1.path === '/trials/trials-panel/setting/reading-unit' || item1.path === '/trials/trials-panel/setting/medical-audit' || item1.path === '/trials/trials-panel/setting/email-manage'))"
:label="$t(item1.LanguageMark)"
:name="item1.path"
/>
<template v-for="item1 of item.children">
<el-tab-pane
v-if="TrialConfig && isShow(item1.path)"
:key="`tab1${item1.path}`"
:disabled="TotalNeedSignTrialDocCount !== 0 && item1.path !== '/trials/trials-panel/attachments/self-attachment' || (TrialStatusStr === 'Initializing' && (item1.path === '/trials/trials-panel/setting/personnel-manage' || item1.path === '/trials/trials-panel/setting/qc-question' || item1.path === '/trials/trials-panel/setting/reading-unit' || item1.path === '/trials/trials-panel/setting/medical-audit' || item1.path === '/trials/trials-panel/setting/email-manage'))"
:label="$t(item1.LanguageMark)"
:name="item1.path"
/>
</template>
</el-tabs>
</el-tab-pane>
</el-tabs>
@ -126,6 +127,10 @@ export default {
var additionalAssessmentList = [
'/trials/trials-panel/subject/brain-metastasis'
]
let dicomList = [
'/trials/trials-panel/trial-summary/image-inspect',
'/trials/trials-panel/trial-summary/push-record',
]
if (this.TrialConfig.QCProcessEnum === 0 && ~qualityList.indexOf(path)) {
isShow = false
}
@ -135,6 +140,9 @@ export default {
if (!this.IsAdditionalAssessment && ~additionalAssessmentList.indexOf(path)) {
isShow = false
}
if ((!this.TrialConfig.IsPACSConnect || !this.TrialConfig.IsTrialPACSConfirmed) && ~dicomList.indexOf(path)) {
isShow = false
}
return isShow
},
goBack() {

View File

@ -17,6 +17,7 @@
<el-radio-group
v-model="form.IsPACSConnect"
:disabled="form.IsTrialPACSConfirmed && !isEdit"
@change="changeConnect"
>
<el-radio
v-for="item of $d.PACSConnectMode"
@ -114,7 +115,6 @@
v-if="
form.IsTrialPACSConfirmed === true &&
!isEdit &&
TrialStatusStr === 'Initializing' &&
hasPermi(['trials:trials-panel:setting:trial-config:save'])
"
type="primary"
@ -354,8 +354,7 @@ export default {
},
],
},
TrialStatusStr: "",
isEdit: true,
isEdit: false,
Id: null,
signVisible: false,
signCode: null,
@ -366,7 +365,16 @@ export default {
};
},
methods: {
initForm() {
changeConnect(val) {
if (!val) {
this.form.CalledAE = null;
this.form.Ip = null;
this.form.Port = null;
this.form.Modality = null;
this.form.IsTestOK = null;
}
},
initForm(res) {
this.getInfo();
},
// dicomAE
@ -397,7 +405,7 @@ export default {
if (res.IsSuccess) {
this.form.IsPACSConnect = res.OtherInfo.IsPACSConnect;
this.form.IsTrialPACSConfirmed = res.OtherInfo.IsTrialPACSConfirmed;
if (!res.OtherInfo.IsTrialProcessConfirmed) {
if (!res.OtherInfo.IsTrialPACSConfirmed) {
this.isEdit = true;
}
this.form.IsTestOK = res.Result.IsTestOK;
@ -465,6 +473,7 @@ export default {
this.signVisible = false;
this.confirmVisible = false;
this.updateVisible = false;
this.isEdit = false;
res = await this.addOrUpdateDicomAE();
if (res) this.$emit("refresh");
}

View File

@ -0,0 +1,281 @@
<template>
<el-dialog
:visible.sync="visible"
:close-on-click-modal="false"
:fullscreen="true"
custom-class="upload-dialog"
:before-close="beforeCloseStudyDig"
>
<span slot="title"
>{{ $t("trials:imageInspect:viewStudy:message:viewStudy") }}{{
$t("trials:imageInspect:viewStudy:message:patientInfo")
}}{{ Patient.PatientIdStr }}{{ Patient.PatientName }}</span
>
<div class="search">
<el-form :inline="true" class="base-search-form">
<!-- 检查类型 -->
<el-form-item
:label="$t('trials:imageInspect:viewStudy:table:modality')"
>
<el-select
v-model="searchData.Modalities"
clearable
style="width: 140px"
>
<el-option
v-for="item of $d.modalType"
:key="item.id"
:label="item.label"
:value="item.label"
>
</el-option>
</el-select>
</el-form-item>
<!-- 检查日期 -->
<el-form-item
:label="$t('trials:imageInspect:viewStudy:table:studyDate')"
>
<el-date-picker
v-model="dateValue"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="['00:00:00', '23:59:59']"
>
</el-date-picker>
</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>
</div>
<!--检查列表-->
<el-table
ref="viewStudyList"
v-loading="loading"
v-adaptive="{ bottomOffset: 60 }"
:data="list"
stripe
height="100"
@sort-change="handleSortByColumn"
:default-sort="{ prop: 'StudyTime', order: 'descending' }"
>
<el-table-column type="index" width="40" />
<!--检查描述-->
<el-table-column
align="center"
prop="Description"
:label="$t('trials:imageInspect:viewStudy:table:studyDescription')"
show-overflow-tooltip
min-width="120"
sortable="custom"
></el-table-column>
<!--检查类型-->
<el-table-column
align="center"
prop="Modalities"
:label="$t('trials:imageInspect:viewStudy:table:modality')"
show-overflow-tooltip
min-width="120"
sortable="custom"
></el-table-column>
<!--Called AE-->
<el-table-column
prop="CalledAE"
:label="$t('trials:imageInspect:viewStudy:table:CalledAE')"
show-overflow-tooltip
min-width="120"
>
</el-table-column>
<!--Calling AE-->
<el-table-column
prop="CallingAE"
:label="$t('trials:imageInspect:viewStudy:table:CallingAE')"
show-overflow-tooltip
min-width="120"
>
</el-table-column>
<!--序列数量-->
<el-table-column
align="center"
prop="SeriesCount"
:label="$t('trials:imageInspect:viewStudy:table:seriesCount')"
show-overflow-tooltip
min-width="100"
sortable="custom"
></el-table-column>
<!--图像数量-->
<el-table-column
align="center"
prop="InstanceCount"
:label="$t('trials:imageInspect:viewStudy:table:instanceCount')"
show-overflow-tooltip
min-width="100"
sortable="custom"
></el-table-column>
<!--检查日期-->
<el-table-column
align="center"
prop="StudyTime"
:label="$t('trials:imageInspect:viewStudy:table:studyDate')"
show-overflow-tooltip
min-width="180"
sortable="custom"
></el-table-column>
<!--操作-->
<el-table-column :label="$t('common:action:action')" min-width="150">
<template slot-scope="scope">
<!-- 影像 -->
<el-button
circle
icon="el-icon-view"
:title="$t('trials:imageInspect:viewStudy:button:image')"
@click.stop="image(scope.row)"
/>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<!-- <pagination
class="page"
:total="total"
:page.sync="searchData.PageIndex"
:limit.sync="searchData.PageSize"
@pagination="getList"
/> -->
</el-dialog>
</template>
<script>
import Pagination from "@/components/Pagination";
import { getPatientStudyList } from "@/api/trials.js";
import { getToken } from "@/utils/auth";
const defaultSearchData = () => {
return {
Modalities: null,
EarliestStudyTime: null,
LatestStudyTime: null,
PatientId: null,
Asc: false,
SortField: "StudyTime",
};
};
export default {
name: "viewStudyList",
components: { Pagination },
props: {
visible: {
required: true,
default: false,
},
Patient: {
required: true,
default: () => {
return {};
},
},
},
data() {
return {
//
searchData: defaultSearchData(),
dateValue: [],
//
loading: false,
list: [],
newWindow: null,
};
},
created() {
this.getList();
},
methods: {
//
beforeCloseStudyDig() {
if (this.newWindow) {
this.newWindow.close();
}
this.$emit("update:visible", false);
},
//
async getList() {
let data = {};
Object.keys(this.searchData).forEach((key) => {
data[key] = this.searchData[key];
});
data.PatientId = this.Patient.PatientId;
if (this.dateValue && this.dateValue[0] && this.dateValue[1]) {
data.EarliestStudyTime = this.$moment(this.dateValue[0]).format(
"YYYY-MM-DD HH:mm:ss"
);
data.LatestStudyTime = this.$moment(this.dateValue[1]).format(
"YYYY-MM-DD HH:mm:ss"
);
} else {
data.EarliestStudyTime = null;
data.LatestStudyTime = null;
}
try {
this.loading = true;
let res = await getPatientStudyList(data);
this.loading = false;
if (res.IsSuccess) {
this.list = res.Result;
}
} catch (err) {
this.loading = false;
console.log(err);
}
},
//
handleSearch() {
this.searchData.PageIndex = 1;
this.getList();
},
//
handleReset() {
this.reset();
this.getList();
},
//
reset() {
this.searchData = defaultSearchData();
this.dateValue = [];
},
//
image(item) {
let token = getToken();
const routeData = this.$router.resolve({
path: `/showdicom?studyId=${item.SCPStudyId}&TokenKey=${token}&type=Patient`,
});
this.newWindow = window.open(routeData.href, "_blank");
},
//
report() {},
//
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();
},
},
};
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,369 @@
<template>
<BaseContainer>
<template slot="search-container">
<el-form :inline="true">
<!--病历号-->
<el-form-item
:label="$t('trials:imageInspect:table:patientIdStr')"
prop="PatientIdStr"
>
<el-input
v-model="searchData.PatientIdStr"
size="small"
clearable
style="width: 120px"
/>
</el-form-item>
<!--患者姓名-->
<el-form-item
:label="$t('trials:imageInspect:table:patientName')"
prop="PatientName"
>
<el-input
v-model="searchData.PatientName"
size="small"
clearable
style="width: 120px"
/>
</el-form-item>
<!--接收端AE-->
<el-form-item
:label="$t('trials:imageInspect:table:calledAE')"
prop="CalledAE"
>
<el-select
v-model="searchData.CalledAE"
clearable
style="width: 120px"
>
<el-option
v-for="item of calledAEList"
:key="item"
:value="item"
:label="item"
/>
</el-select>
</el-form-item>
<!--发送端AE-->
<el-form-item
:label="$t('trials:imageInspect:table:callingAE')"
prop="CallingAE"
>
<el-select
v-model="searchData.CallingAE"
clearable
style="width: 120px"
>
<el-option
v-for="item of callingAEList"
:key="item"
:value="item"
:label="item"
/>
</el-select>
</el-form-item>
<!--所在中心-->
<el-form-item
:label="$t('trials:imageInspect:table:trialSiteKeyInfo')"
prop="TrialSiteKeyInfo"
>
<el-input
v-model="searchData.TrialSiteKeyInfo"
size="small"
clearable
style="width: 150px"
:placeholder="
$t('trials:imageInspect:placeholder:trialSiteKeyInfo')
"
/>
</el-form-item>
<!--最新接受日期-->
<el-form-item :label="$t('trials:imageInspect:table:createTime')">
<el-date-picker
v-model="datetimerange"
type="datetimerange"
:default-time="['00:00:00', '23:59:59']"
:start-placeholder="$t('trials:loginLog:table:beginTime')"
:end-placeholder="$t('trials:loginLog:table:endTime')"
value-format="yyyy-MM-dd HH:mm:ss"
@change="handleDatetimeChange"
/>
</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 }"
height="100"
:data="list"
class="table"
@sort-change="handleSortByColumn"
:default-sort="{ prop: 'LatestPushTime', order: 'descending' }"
>
<el-table-column type="index" width="50" />
<!--病历号-->
<el-table-column
:label="$t('trials:imageInspect:table:patientIdStr')"
prop="PatientIdStr"
min-width="90"
show-overflow-tooltip
sortable="custom"
/>
<!--患者姓名-->
<el-table-column
:label="$t('trials:imageInspect:table:patientName')"
prop="PatientName"
min-width="90"
show-overflow-tooltip
sortable="custom"
/>
<!--出生日期-->
<el-table-column
:label="$t('trials:imageInspect:table:patientBirthDate')"
prop="PatientBirthDate"
min-width="90"
show-overflow-tooltip
sortable="custom"
/>
<!--性别-->
<el-table-column
:label="$t('trials:imageInspect:table:patientSex')"
prop="PatientSex"
min-width="90"
show-overflow-tooltip
sortable="custom"
/>
<!--接收端AE-->
<el-table-column
:label="$t('trials:imageInspect:table:calledAEList')"
prop="CalledAEList"
min-width="90"
show-overflow-tooltip
sortable="custom"
><template slot-scope="scope">
{{ scope.row.CallingAEList.join(", ") }}
</template>
</el-table-column>
<!--发送端AE-->
<el-table-column
:label="$t('trials:imageInspect:table:callingAEList')"
prop="CallingAEList"
min-width="90"
show-overflow-tooltip
sortable="custom"
>
<template slot-scope="scope">
{{ scope.row.CallingAEList.join(", ") }}
</template>
</el-table-column>
<!--检查-->
<el-table-column
:label="$t('trials:imageInspect:table:studyCount')"
prop="StudyCount"
min-width="160"
show-overflow-tooltip
sortable="custom"
>
<template slot-scope="scope">
<el-button
v-if="scope.row.StudyCount >= 1"
type="text"
@click="handleOpenDialog(scope.row, 'study')"
>
<span>{{ scope.row.StudyCount }}</span>
</el-button>
<span v-else>{{ scope.row.StudyCount }}</span>
</template>
</el-table-column>
<!--所在中心-->
<el-table-column
:label="$t('trials:imageInspect:table:trialSiteCodeAndName')"
prop="TrialSiteCode"
min-width="160"
show-overflow-tooltip
sortable="custom"
>
<template slot-scope="scope">
{{ scope.row.trialSiteCode }},{{ scope.row.trialSiteName }}
</template>
</el-table-column>
<!--受试者ID-->
<el-table-column
:label="$t('trials:imageInspect:table:subjectCode')"
prop="SubjectCode"
min-width="90"
show-overflow-tooltip
sortable="custom"
/>
<!--最新接收时间-->
<el-table-column
:label="$t('trials:imageInspect:table:lastestPushTime')"
prop="LatestPushTime"
min-width="90"
show-overflow-tooltip
sortable="custom"
/>
</el-table>
<!-- 分页组件 -->
<pagination
class="page"
:total="total"
:page.sync="searchData.PageIndex"
:limit.sync="searchData.PageSize"
@pagination="getList"
/>
</template>
<!--查看检查列表-->
<viewStudy
v-if="visible"
:visible.sync="visible"
:Patient="selectPatient"
@getList="getList"
/>
</BaseContainer>
</template>
<script>
import {
getPatientList,
getDicomCalledAEList,
getDicomCallingAEList,
} from "@/api/trials";
import BaseContainer from "@/components/BaseContainer";
import Pagination from "@/components/Pagination";
import moment from "moment";
import viewStudy from "./components/view-study";
const searchDataDefault = () => {
return {
PatientIdStr: null,
PatientName: null,
CallingAE: null,
CalledAE: null,
BeginPushTime: null,
EndPushTime: null,
SubejctCode: null,
TrialSiteKeyInfo: null,
PageIndex: 1,
PageSize: 20,
Asc: true,
SortField: "LatestPushTime",
};
};
export default {
components: { BaseContainer, Pagination, viewStudy },
data() {
return {
moment,
searchData: searchDataDefault(),
list: [],
total: 0,
loading: false,
datetimerange: [],
calledAEList: [],
callingAEList: [],
visible: false,
selectPatient: {},
};
},
created() {
this.getCalledAEList();
this.getCallingAEList();
},
mounted() {
this.getList();
},
methods: {
//
handleOpenDialog(item) {
this.visible = true;
this.selectPatient = item;
},
// AE
async getCalledAEList() {
try {
let params = {
TrialId: this.$route.query.trialId,
};
let res = await getDicomCalledAEList(params);
if (res.IsSuccess) {
this.calledAEList = res.Result;
}
} catch (err) {
console.log(err);
}
},
// AE
async getCallingAEList() {
try {
let params = {
TrialId: this.$route.query.trialId,
};
let res = await getDicomCallingAEList(params);
if (res.IsSuccess) {
this.callingAEList = res.Result;
}
} catch (err) {
console.log(err);
}
},
getList() {
this.loading = true;
this.searchData.TrialId = this.$route.query.trialId;
getPatientList(this.searchData)
.then((res) => {
this.loading = false;
this.list = res.Result.CurrentPageData;
this.total = res.Result.TotalCount;
})
.catch(() => {
this.loading = false;
});
},
handleDatetimeChange(val) {
if (val) {
this.searchData.BeginPushTime = val[0];
this.searchData.EndPushTime = val[1];
} else {
this.searchData.BeginPushTime = "";
this.searchData.EndPushTime = "";
}
},
handleSearch() {
this.searchData.PageIndex = 1;
this.getList();
},
//
handleReset() {
this.datetimerange = null;
this.handleDatetimeChange();
this.searchData = searchDataDefault();
this.getList();
},
//
handleSortByColumn(column) {
if (column.order === "ascending") {
this.searchData.Asc = true;
} else {
this.searchData.Asc = false;
}
this.searchData.SortField = column.prop;
this.searchData.PageIndex = 1;
this.getList();
},
},
};
</script>

View File

@ -0,0 +1,311 @@
<template>
<BaseContainer>
<template slot="search-container">
<el-form :inline="true">
<!--所在中心-->
<el-form-item
:label="$t('trials:pushRecord:table:trialSiteKeyInfo')"
prop="TrialSiteKeyInfo"
>
<el-input
v-model="searchData.TrialSiteKeyInfo"
size="small"
clearable
style="width: 150px"
:placeholder="$t('trials:pushRecord:placeholder:trialSiteKeyInfo')"
/>
</el-form-item>
<!--接收端AE-->
<el-form-item
:label="$t('trials:pushRecord:table:calledAE')"
prop="CalledAE"
>
<el-select
v-model="searchData.CalledAE"
clearable
style="width: 120px"
>
<el-option
v-for="item of calledAEList"
:key="item"
:value="item"
:label="item"
/>
</el-select>
</el-form-item>
<!--发送端AE-->
<el-form-item
:label="$t('trials:pushRecord:table:callingAE')"
prop="CallingAE"
>
<el-select
v-model="searchData.CallingAE"
clearable
style="width: 120px"
>
<el-option
v-for="item of callingAEList"
:key="item"
:value="item"
:label="item"
/>
</el-select>
</el-form-item>
<!--最新接受日期-->
<el-form-item :label="$t('trials:pushRecord:table:createTime')">
<el-date-picker
v-model="datetimerange"
type="datetimerange"
:default-time="['00:00:00', '23:59:59']"
:start-placeholder="$t('trials:loginLog:table:beginTime')"
:end-placeholder="$t('trials:loginLog:table:endTime')"
value-format="yyyy-MM-dd HH:mm:ss"
@change="handleDatetimeChange"
/>
</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 }"
height="100"
:data="list"
class="table"
@sort-change="handleSortByColumn"
:default-sort="{ prop: 'StartTime', order: 'descending' }"
>
<el-table-column type="index" width="50" />
<!--中心编号-->
<el-table-column
:label="$t('trials:pushRecord:table:trialSiteCode')"
prop="TrialSiteCode"
min-width="160"
show-overflow-tooltip
sortable="custom"
/>
<!--中心名称-->
<el-table-column
:label="$t('trials:pushRecord:table:trialSiteAliasName')"
prop="TrialSiteAliasName"
min-width="160"
show-overflow-tooltip
sortable="custom"
/>
<!--发送端AE-->
<el-table-column
:label="$t('trials:pushRecord:table:callingAEList')"
prop="CallingAEList"
min-width="90"
show-overflow-tooltip
sortable="custom"
>
<template slot-scope="scope">
{{ scope.row.CallingAEList.join(", ") }}
</template>
</el-table-column>
<!--发送端IP-->
<el-table-column
:label="$t('trials:pushRecord:table:callingAEIP')"
prop="CallingAEIP"
min-width="160"
show-overflow-tooltip
sortable="custom"
/>
<!--接收端AE-->
<el-table-column
:label="$t('trials:pushRecord:table:calledAEList')"
prop="CalledAEList"
min-width="90"
show-overflow-tooltip
sortable="custom"
><template slot-scope="scope">
{{ scope.row.CallingAEList.join(", ") }}
</template>
</el-table-column>
<!--检查数-->
<el-table-column
:label="$t('trials:pushRecord:table:studyCount')"
prop="StudyCount"
min-width="160"
show-overflow-tooltip
sortable="custom"
/>
<!--图像数量-->
<el-table-column
:label="$t('trials:pushRecord:table:fileCount')"
prop="FileCount"
min-width="160"
show-overflow-tooltip
sortable="custom"
/>
<!--图像大小-->
<el-table-column
:label="$t('trials:pushRecord:table:fileSize')"
prop="FileSize"
min-width="160"
show-overflow-tooltip
sortable="custom"
/>
<!--推送开始时间-->
<el-table-column
:label="$t('trials:pushRecord:table:startTime')"
prop="StartTime"
min-width="160"
show-overflow-tooltip
sortable="custom"
/>
<!--推送结束时间-->
<el-table-column
:label="$t('trials:pushRecord:table:endTime')"
prop="EndTime"
min-width="160"
show-overflow-tooltip
sortable="custom"
/>
</el-table>
<!-- 分页组件 -->
<pagination
class="page"
:total="total"
:page.sync="searchData.PageIndex"
:limit.sync="searchData.PageSize"
@pagination="getList"
/>
</template>
</BaseContainer>
</template>
<script>
import {
getSCPImageUploadList,
getDicomCalledAEList,
getDicomCallingAEList,
} from "@/api/trials";
import BaseContainer from "@/components/BaseContainer";
import Pagination from "@/components/Pagination";
import moment from "moment";
const searchDataDefault = () => {
return {
CallingAE: null,
CalledAE: null,
StartTime: null,
EndTime: null,
TrialSiteKeyInfo: null,
PageIndex: 1,
PageSize: 20,
Asc: true,
SortField: "StartTime",
};
};
export default {
components: { BaseContainer, Pagination },
data() {
return {
moment,
searchData: searchDataDefault(),
list: [],
total: 0,
loading: false,
datetimerange: [],
calledAEList: [],
callingAEList: [],
};
},
created() {
this.getCalledAEList();
this.getCallingAEList();
},
mounted() {
this.getList();
},
methods: {
// AE
async getCalledAEList() {
try {
let params = {
TrialId: this.$route.query.trialId,
};
let res = await getDicomCalledAEList(params);
if (res.IsSuccess) {
this.calledAEList = res.Result;
}
} catch (err) {
console.log(err);
}
},
// AE
async getCallingAEList() {
try {
let params = {
TrialId: this.$route.query.trialId,
};
let res = await getDicomCallingAEList(params);
if (res.IsSuccess) {
this.callingAEList = res.Result;
}
} catch (err) {
console.log(err);
}
},
getList() {
this.loading = true;
this.searchData.TrialId = this.$route.query.trialId;
getSCPImageUploadList(this.searchData)
.then((res) => {
this.loading = false;
this.list = res.Result.CurrentPageData;
this.total = res.Result.TotalCount;
})
.catch(() => {
this.loading = false;
});
},
handleDatetimeChange(val) {
if (val) {
this.searchData.StartTime = val[0];
this.searchData.EndTime = val[1];
} else {
this.searchData.StartTime = "";
this.searchData.EndTime = "";
}
},
handleSearch() {
this.searchData.PageIndex = 1;
this.getList();
},
//
handleReset() {
this.datetimerange = null;
this.handleDatetimeChange();
this.searchData = searchDataDefault();
this.getList();
},
//
handleSortByColumn(column) {
if (column.order === "ascending") {
this.searchData.Asc = true;
} else {
this.searchData.Asc = false;
}
this.searchData.SortField = column.prop;
this.searchData.PageIndex = 1;
this.getList();
},
},
};
</script>

View File

@ -193,365 +193,389 @@
</el-table-column>
</el-table>
<!-- 多文件上传 -->
<form id="inputForm" ref="uploadForm" enctype="multipart/form-data">
<el-divider content-position="left">{{
$t("trials:uploadedDicoms:title:dicomFilesOnly")
}}</el-divider>
<div class="form-group">
<div id="directoryInputWrapper" class="btn btn-link file-input">
<el-button
type="primary"
:disabled="btnLoading"
:loading="btnLoading"
size="small"
>{{
$t("trials:uploadedDicomsicom:button:selectFolder")
}}</el-button
>
<input
type="file"
name="file"
ref="pathClear"
:disabled="btnLoading"
webkitdirectory
multiple
@change="beginScanFiles($event)"
/>
</div>
</div>
</form>
<!-- 文件列表 -->
<el-table
ref="dicomFilesTable"
:data="uploadQueues"
:row-key="(row) => row.studyIndex"
class="dicomFiles-table"
@selection-change="handleSelectionChange"
>
<el-table-column
type="selection"
width="55"
:selectable="handleSelectable"
/>
<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 }}
<el-divider content-position="left">{{
$t("trials:uploadedDicoms:title:dicomFilesOnly")
}}</el-divider>
<el-tabs v-model="uploadActiveName">
<!-- 本地上传 -->
<el-tab-pane
:label="$t('trials:uploadedDicoms:tab:uploadFile')"
name="file"
>
<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="small"
>{{
$t("trials:uploadedDicomsicom:button:selectFolder")
}}</el-button
>
<input
type="file"
name="file"
ref="pathClear"
:disabled="btnLoading"
webkitdirectory
multiple
@change="beginScanFiles($event)"
/>
</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>
</form>
<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="120"
show-overflow-tooltip
>
<template slot-scope="scope">
<el-progress
color="#409eff"
:percentage="
(scope.row.dicomInfo.failedFileCount * 100) /
scope.row.dicomInfo.fileCount
"
:show-text="false"
<!-- 文件列表 -->
<el-table
ref="dicomFilesTable"
:data="uploadQueues"
:row-key="(row) => row.studyIndex"
class="dicomFiles-table"
@selection-change="handleSelectionChange"
>
<el-table-column
type="selection"
width="55"
:selectable="handleSelectable"
/>
<span
>{{ scope.row.dicomInfo.failedFileCount }} /
{{ scope.row.dicomInfo.fileCount }}</span
>
</template>
</el-table-column>
<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>
<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 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 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>
{{ scope.row.dicomInfo.studyTime }}
</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
</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="120"
show-overflow-tooltip
>
<template slot-scope="scope">
<el-progress
color="#409eff"
:percentage="
(scope.row.dicomInfo.failedFileCount * 100) /
scope.row.dicomInfo.fileCount
"
:show-text="false"
/>
<span
>{{ scope.row.dicomInfo.failedFileCount }} /
{{ scope.row.dicomInfo.fileCount }}</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>
/
<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-column
v-show="isScan"
:label="$t('common:action:action')"
width="200"
>
<template slot-scope="scope">
<!-- 预览 -->
<!-- :disabled="scope.row.dicomInfo.failedFileCount < scope.row.dicomInfo.fileCount && scope.row.dicomInfo.failedFileCount !== 0"-->
<el-button
icon="el-icon-view"
circle
:disabled="
scope.row.uploadState.stateCode !== '' &&
scope.row.dicomInfo.failedFileCount <
scope.row.dicomInfo.fileCount &&
!scope.row.uploadState.record
"
:title="$t('trials:uploadedDicoms:action:preview')"
size="small"
@click="handlePreview(scope.row.dicomInfo.studyUid)"
/>
<!-- 移除 -->
<el-button
icon="el-icon-delete"
circle
:title="$t('trials:uploadedDicoms:action:delete')"
size="small"
:disabled="
scope.row.uploadState.stateCode !== '' &&
scope.row.dicomInfo.failedFileCount <
scope.row.dicomInfo.fileCount &&
!scope.row.uploadState.record
"
@click="handleDelete(scope.$index, scope.row)"
/>
</template>
</el-table-column>
</el-table>
<div style="text-align: right; padding: 10px 0px">
<!-- 关闭 -->
<!-- <el-button :disabled="btnLoading" size="small" type="primary" @click="cancel">
</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-column
v-show="isScan"
:label="$t('common:action:action')"
width="200"
>
<template slot-scope="scope">
<!-- 预览 -->
<!-- :disabled="scope.row.dicomInfo.failedFileCount < scope.row.dicomInfo.fileCount && scope.row.dicomInfo.failedFileCount !== 0"-->
<el-button
icon="el-icon-view"
circle
:disabled="
scope.row.uploadState.stateCode !== '' &&
scope.row.dicomInfo.failedFileCount <
scope.row.dicomInfo.fileCount &&
!scope.row.uploadState.record
"
:title="$t('trials:uploadedDicoms:action:preview')"
size="small"
@click="handlePreview(scope.row.dicomInfo.studyUid)"
/>
<!-- 移除 -->
<el-button
icon="el-icon-delete"
circle
:title="$t('trials:uploadedDicoms:action:delete')"
size="small"
:disabled="
scope.row.uploadState.stateCode !== '' &&
scope.row.dicomInfo.failedFileCount <
scope.row.dicomInfo.fileCount &&
!scope.row.uploadState.record
"
@click="handleDelete(scope.$index, scope.row)"
/>
</template>
</el-table-column>
</el-table>
<div style="text-align: right; padding: 10px 0px">
<!-- 关闭 -->
<!-- <el-button :disabled="btnLoading" size="small" type="primary" @click="cancel">
{{ $t('trials:uploadDicomList:button:close') }}
</el-button> -->
<!-- 上传 -->
<el-button
size="small"
type="primary"
:disabled="selectArr.length == 0 || !isScan"
:loading="btnLoading"
@click="beginUploadQueues"
<!-- 上传 -->
<el-button
size="small"
type="primary"
:disabled="selectArr.length == 0 || !isScan"
:loading="btnLoading"
@click="beginUploadQueues"
>
{{ $t("trials:uploadDicomList:button:upload") }}
</el-button>
</div>
</el-tab-pane>
<!-- pacs上传 -->
<el-tab-pane
:label="$t('trials:uploadNonDicoms:tab:uploadPacs')"
name="pacs"
:disabled="btnLoading"
>
{{ $t("trials:uploadDicomList:button:upload") }}
</el-button>
</div>
<uploadDicomPacs v-if="uploadActiveName === 'pacs'" />
</el-tab-pane>
</el-tabs>
<!-- 预览影像模态框 -->
<el-dialog
v-if="previewVisible"
@ -758,9 +782,10 @@ import { dcmUpload } from "@/utils/dcmUpload/dcmUpload";
import { convertBytes } from "@/utils/dicom-character-set";
import moment from "moment";
import store from "@/store";
import uploadDicomPacs from "./uploadDiocmPacs.vue";
export default {
name: "UploadDicomFiles",
components: { DicomPreview, uploadPetClinicalData },
components: { DicomPreview, uploadPetClinicalData, uploadDicomPacs },
props: {
data: {
type: Object,
@ -783,6 +808,7 @@ export default {
},
data() {
return {
uploadActiveName: "file",
editStudyInfoVisible: false,
studyForm: {
StudyCode: "",

View File

@ -0,0 +1,311 @@
<template>
<BaseContainer>
<template slot="search-container">
<el-form :inline="true">
<!--所在中心-->
<el-form-item
:label="$t('trials:pushRecord:table:trialSiteKeyInfo')"
prop="TrialSiteKeyInfo"
>
<el-input
v-model="searchData.TrialSiteKeyInfo"
size="small"
clearable
style="width: 150px"
:placeholder="$t('trials:pushRecord:placeholder:trialSiteKeyInfo')"
/>
</el-form-item>
<!--接收端AE-->
<el-form-item
:label="$t('trials:pushRecord:table:calledAE')"
prop="CalledAE"
>
<el-select
v-model="searchData.CalledAE"
clearable
style="width: 120px"
>
<el-option
v-for="item of calledAEList"
:key="item"
:value="item"
:label="item"
/>
</el-select>
</el-form-item>
<!--发送端AE-->
<el-form-item
:label="$t('trials:pushRecord:table:callingAE')"
prop="CallingAE"
>
<el-select
v-model="searchData.CallingAE"
clearable
style="width: 120px"
>
<el-option
v-for="item of callingAEList"
:key="item"
:value="item"
:label="item"
/>
</el-select>
</el-form-item>
<!--最新接受日期-->
<el-form-item :label="$t('trials:pushRecord:table:createTime')">
<el-date-picker
v-model="datetimerange"
type="datetimerange"
:default-time="['00:00:00', '23:59:59']"
:start-placeholder="$t('trials:loginLog:table:beginTime')"
:end-placeholder="$t('trials:loginLog:table:endTime')"
value-format="yyyy-MM-dd HH:mm:ss"
@change="handleDatetimeChange"
/>
</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: 120 }"
height="100"
:data="list"
class="table"
@sort-change="handleSortByColumn"
:default-sort="{ prop: 'StartTime', order: 'descending' }"
>
<el-table-column type="index" width="50" />
<!--中心编号-->
<el-table-column
:label="$t('trials:pushRecord:table:trialSiteCode')"
prop="TrialSiteCode"
min-width="160"
show-overflow-tooltip
sortable="custom"
/>
<!--中心名称-->
<el-table-column
:label="$t('trials:pushRecord:table:trialSiteAliasName')"
prop="TrialSiteAliasName"
min-width="160"
show-overflow-tooltip
sortable="custom"
/>
<!--发送端AE-->
<el-table-column
:label="$t('trials:pushRecord:table:callingAEList')"
prop="CallingAEList"
min-width="90"
show-overflow-tooltip
sortable="custom"
>
<template slot-scope="scope">
{{ scope.row.CallingAEList.join(", ") }}
</template>
</el-table-column>
<!--发送端IP-->
<el-table-column
:label="$t('trials:pushRecord:table:callingAEIP')"
prop="CallingAEIP"
min-width="160"
show-overflow-tooltip
sortable="custom"
/>
<!--接收端AE-->
<el-table-column
:label="$t('trials:pushRecord:table:calledAEList')"
prop="CalledAEList"
min-width="90"
show-overflow-tooltip
sortable="custom"
><template slot-scope="scope">
{{ scope.row.CallingAEList.join(", ") }}
</template>
</el-table-column>
<!--检查数-->
<el-table-column
:label="$t('trials:pushRecord:table:studyCount')"
prop="StudyCount"
min-width="160"
show-overflow-tooltip
sortable="custom"
/>
<!--图像数量-->
<el-table-column
:label="$t('trials:pushRecord:table:fileCount')"
prop="FileCount"
min-width="160"
show-overflow-tooltip
sortable="custom"
/>
<!--图像大小-->
<el-table-column
:label="$t('trials:pushRecord:table:fileSize')"
prop="FileSize"
min-width="160"
show-overflow-tooltip
sortable="custom"
/>
<!--推送开始时间-->
<el-table-column
:label="$t('trials:pushRecord:table:startTime')"
prop="StartTime"
min-width="160"
show-overflow-tooltip
sortable="custom"
/>
<!--推送结束时间-->
<el-table-column
:label="$t('trials:pushRecord:table:endTime')"
prop="EndTime"
min-width="160"
show-overflow-tooltip
sortable="custom"
/>
</el-table>
<!-- 分页组件 -->
<pagination
class="page"
:total="total"
:page.sync="searchData.PageIndex"
:limit.sync="searchData.PageSize"
@pagination="getList"
/>
</template>
</BaseContainer>
</template>
<script>
import {
getSCPImageUploadList,
getDicomCalledAEList,
getDicomCallingAEList,
} from "@/api/trials";
import BaseContainer from "@/components/BaseContainer";
import Pagination from "@/components/Pagination";
import moment from "moment";
const searchDataDefault = () => {
return {
CallingAE: null,
CalledAE: null,
StartTime: null,
EndTime: null,
TrialSiteKeyInfo: null,
PageIndex: 1,
PageSize: 20,
Asc: true,
SortField: "StartTime",
};
};
export default {
components: { BaseContainer, Pagination },
data() {
return {
moment,
searchData: searchDataDefault(),
list: [],
total: 0,
loading: false,
datetimerange: [],
calledAEList: [],
callingAEList: [],
};
},
created() {
this.getCalledAEList();
this.getCallingAEList();
},
mounted() {
this.getList();
},
methods: {
// AE
async getCalledAEList() {
try {
let params = {
TrialId: this.$route.query.trialId,
};
let res = await getDicomCalledAEList(params);
if (res.IsSuccess) {
this.calledAEList = res.Result;
}
} catch (err) {
console.log(err);
}
},
// AE
async getCallingAEList() {
try {
let params = {
TrialId: this.$route.query.trialId,
};
let res = await getDicomCallingAEList(params);
if (res.IsSuccess) {
this.callingAEList = res.Result;
}
} catch (err) {
console.log(err);
}
},
getList() {
this.loading = true;
this.searchData.TrialId = this.$route.query.trialId;
getSCPImageUploadList(this.searchData)
.then((res) => {
this.loading = false;
this.list = res.Result.CurrentPageData;
this.total = res.Result.TotalCount;
})
.catch(() => {
this.loading = false;
});
},
handleDatetimeChange(val) {
if (val) {
this.searchData.StartTime = val[0];
this.searchData.EndTime = val[1];
} else {
this.searchData.StartTime = "";
this.searchData.EndTime = "";
}
},
handleSearch() {
this.searchData.PageIndex = 1;
this.getList();
},
//
handleReset() {
this.datetimerange = null;
this.handleDatetimeChange();
this.searchData = searchDataDefault();
this.getList();
},
//
handleSortByColumn(column) {
if (column.order === "ascending") {
this.searchData.Asc = true;
} else {
this.searchData.Asc = false;
}
this.searchData.SortField = column.prop;
this.searchData.PageIndex = 1;
this.getList();
},
},
};
</script>

View File

@ -1045,7 +1045,7 @@ export default {
formRow: {},
searchData: searchDataDefault(),
loading: false,
uploadVisible: false,
uploadVisible: true,
qcVisible: false,
list: [],
total: 0,