Merge branch 'main' of https://gitea.frp.extimaging.com/XCKJ/hir_web into main
continuous-integration/drone/push Build is passing Details

main
caiyiling 2024-05-29 17:08:03 +08:00
commit b9086e135f
15 changed files with 651 additions and 20 deletions

View File

@ -22,7 +22,7 @@ VUE_APP_LOGOUT_FOR_PERMISSION = false
VUE_APP_LOGOUT_FOR_TIME = 1800
# 是否开启密码正则验证 true:是 false:否
VUE_APP_PASSWORD_FOR_PERMISSION = true
VUE_APP_PASSWORD_FOR_PERMISSION = false
# 是否开启密码正则验证 true:是 false:否
VUE_APP_PASSWORD_FOR_REGULAR = ^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[-_.@^+\$!%#*?&\$~])[A-Za-z0-9-~_.@^+\$~!%#*?&]{8,32}$

View File

@ -1,6 +1,6 @@
# just a flag
ENV = 'production'
NODE_ENV = 'production'
ENV = 'uat'
NODE_ENV = 'uat'
# base public path
VUE_APP_BASE_PATH = '/'

View File

@ -1,6 +1,6 @@
# just a flag
ENV = 'production'
NODE_ENV = 'production'
ENV = 'usa'
NODE_ENV = 'usa'
# base public path
VUE_APP_BASE_PATH = '/'

View File

@ -37,6 +37,24 @@ export function getPatientJoinedTrialList(data) {
})
}
// 检查->scp影像推送记录
export function getSCPImageUploadList(data) {
return request({
url: '/Patient/getSCPImageUploadList',
method: 'post',
data
})
}
// 下载记录
export function getTrialSubjectVisitDownloadList(data) {
return request({
url: '/Patient/getTrialSubjectVisitDownloadList',
method: 'post',
data
})
}
// 获取患者列表(下拉框)
export function getTrialSubejctSelectList(data) {
return request({

View File

@ -68,14 +68,15 @@ const searchDataDefault = () => {
return {
UserName: null,
Phone: null,
EMail:null,
OrganizationName: null,
UserState: null,
UserType: null,
PageIndex: 1,
PageSize: 20,
Asc: true,
Asc: false,
RealName: "",
SortField: "",
SortField: "CreateTime",
CreateTimeArr: [],
BeginCreateTime: null,
EndCreateTime: null,
@ -212,6 +213,13 @@ export default {
width: "120px",
placeholder: "",
},
{
type: "Input",
label: this.$t("system:userlist:label:EMail"),
prop: "EMail",
width: "120px",
placeholder: "",
},
{
type: "Input",
label: this.$t("system:userlist:label:Organization"),

View File

@ -0,0 +1,310 @@
<template>
<el-dialog
:visible.sync="visible"
:close-on-click-modal="false"
:fullscreen="true"
custom-class="upload-dialog"
:before-close="beforeCloseStudyDig"
>
<span slot="title"> </span>
<div class="search">
<el-form :inline="true" class="base-search-form">
<!-- Called AE -->
<el-form-item
class="my_multiple"
:label="$t('trials:inspection:search:CalledAE')"
>
<el-select
v-model="searchData.CalledAE"
clearable
style="width: 140px"
>
<el-option
v-for="(item, index) of calledAeList"
:key="index"
:label="item"
:value="item"
>
</el-option>
</el-select>
</el-form-item>
<!-- Calling AE -->
<el-form-item
class="my_multiple"
:label="$t('trials:inspection:search:CallingAE')"
>
<el-select
v-model="searchData.callingAE"
clearable
style="width: 140px"
>
<el-option
v-for="(item, index) of callingAeList"
:key="index"
:label="item"
:value="item"
>
</el-option>
</el-select>
</el-form-item>
<!-- 推送日期 -->
<el-form-item :label="$t('trials:inspection:table:pushDate')">
<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: 'StartTime', order: 'descending' }"
>
<el-table-column type="index" width="40" />
<!--Called AE-->
<el-table-column
prop="CalledAE"
:label="$t('trials:inspection:table:CalledAE')"
show-overflow-tooltip
min-width="120"
>
</el-table-column>
<!--Calling AE-->
<el-table-column
prop="CallingAE"
:label="$t('trials:inspection:table:CallingAE')"
show-overflow-tooltip
min-width="120"
>
</el-table-column>
<!--Calling AE IP-->
<el-table-column
prop="CallingAEIP"
:label="$t('trials:inspection:table:CallingAEIP')"
show-overflow-tooltip
min-width="120"
>
</el-table-column>
<!--检查数量--->
<el-table-column
:label="$t('trials:inspection:table:StudyCount')"
prop="StudyCount"
min-width="90"
show-overflow-tooltip
sortable="custom"
/>
<!--图像数量-->
<el-table-column
align="center"
prop="FileCount"
:label="$t('trials:inspection:table:FileCount')"
show-overflow-tooltip
min-width="100"
sortable="custom"
></el-table-column>
<!--图像大小-->
<el-table-column
align="center"
prop="FileSize"
:label="$t('trials:inspection:table:FileSize')"
show-overflow-tooltip
min-width="100"
sortable="custom"
>
<template slot-scope="scope">
<span>{{
scope.row.FileSize && scope.row.FileSize > 0
? `${(scope.row.FileSize / 1024 / 1024).toFixed(2)}MB`
: 0
}}</span>
</template>
</el-table-column>
<!--推送开始日期-->
<el-table-column
align="center"
prop="StartTime"
:label="$t('trials:inspection:table:StartTime')"
show-overflow-tooltip
min-width="180"
sortable="custom"
></el-table-column>
<!--推送结束日期-->
<el-table-column
align="center"
prop="EndTime"
:label="$t('trials:inspection:table:EndTime')"
show-overflow-tooltip
min-width="180"
sortable="custom"
></el-table-column>
<!--操作-->
<!-- <el-table-column :label="$t('common:action:action')" min-width="80">
<template slot-scope="scope">
<el-button
circle
disabled
icon="el-icon-view"
:title="$t('trials:inspection: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 { getSCPImageUploadList } from "@/api/inspection.js";
import { getToken } from "@/utils/auth";
const defaultSearchData = () => {
return {
CallingAE: null,
CalledAE: null,
CallingAEIP: null,
StartTime: null,
EndTime: null,
PageIndex: 1,
PageSize: 10,
Asc: false,
SortField: "StartTime",
};
};
export default {
name: "pushRecordList",
components: { Pagination },
props: {
visible: {
required: true,
default: false,
},
calledAeList: {
required: true,
default: () => {
return [];
},
},
callingAeList: {
required: true,
default: () => {
return [];
},
},
},
data() {
return {
//
searchData: defaultSearchData(),
dateValue: [],
//
loading: false,
list: [],
total: 0,
};
},
created() {
this.getList();
},
methods: {
async getList() {
let data = {};
Object.keys(this.searchData).forEach((key) => {
data[key] = this.searchData[key];
});
if (this.dateValue && this.dateValue[0] && this.dateValue[1]) {
data.StartTime = this.$moment(this.dateValue[0]).format(
"YYYY-MM-DD HH:mm:ss"
);
data.EndTime = this.$moment(this.dateValue[1]).format(
"YYYY-MM-DD HH:mm:ss"
);
} else {
data.StartTime = null;
data.EndTime = null;
}
try {
this.loading = true;
let res = await getSCPImageUploadList(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);
}
},
//
handleSearch() {
this.searchData.PageIndex = 1;
this.getList();
},
//
handleReset() {
this.reset();
this.getList();
},
//
reset() {
this.searchData = defaultSearchData();
this.dateValue = [];
},
//
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();
},
beforeCloseStudyDig() {
this.$setOpenWindow();
this.$emit("update:visible", false);
},
//
image(item) {
let token = getToken();
const routeData = this.$router.resolve({
path: `/showdicom?studyId=${item.SCPStudyId}&TokenKey=${token}&type=Patient`,
});
let newWindow = window.open(routeData.href, "_blank");
this.$setOpenWindow(newWindow);
},
},
};
</script>

View File

@ -273,6 +273,7 @@ export default {
this.list = res.Result;
}
} catch (err) {
this.loading = false;
console.log(err);
}
},

View File

@ -92,6 +92,12 @@
{{ $t("common:button:reset") }}
</el-button>
</el-form-item>
<el-form-item>
<!-- 推送记录 -->
<el-button type="primary" @click="handleOpenDialog({}, 'push')">
{{ $t("common:button:push") }}
</el-button>
</el-form-item>
</el-form>
</template>
@ -294,6 +300,13 @@
:Patient="selectPatient"
@getList="getList"
/>
<!--推送记录列表-->
<pushRecordList
v-if="pushTrialsVisible"
:visible.sync="pushTrialsVisible"
:calledAeList="calledAeList"
:callingAeList="callingAeList"
/>
</BaseContainer>
</template>
<script>
@ -302,6 +315,7 @@ import Pagination from "@/components/Pagination";
import researchTrialsList from "./components/research-trials-list";
import addTrialsList from "./components/add-trials-list";
import viewStudyList from "./components/view-study-list";
import pushRecordList from "./components/push-record-list";
import { getPatientList, deletePatientStudyAllData } from "@/api/inspection.js";
import { getDicomCalledAEList, getDicomCallingAEList } from "@/api/dicomAE.js";
@ -328,6 +342,7 @@ export default {
researchTrialsList,
addTrialsList,
viewStudyList,
pushRecordList,
},
data() {
return {
@ -348,6 +363,8 @@ export default {
addTrialsVisible: false,
//
studyTrialsVisible: false,
//
pushTrialsVisible: false,
};
},
created() {

View File

@ -32,7 +32,10 @@
<!-- 工作台 -->
<!-- <span slot="title">{{ $t('trials:menuTitle:workbench') }}</span>
</el-menu-item> -->
<el-menu-item v-if="hasPermi(['role:pm','role:oa','role:admin','role:dev'])" index="1">
<el-menu-item
v-if="hasPermi(['role:pm', 'role:oa', 'role:admin', 'role:dev'])"
index="1"
>
<i class="el-icon-odometer" />
<!-- 检查 -->
<span slot="title">{{ $t("trials:menuTitle:inspection") }}</span>
@ -78,6 +81,12 @@
<el-menu-item v-if="!hasPermi(['role:air'])" index="4-2">{{
$t("trials:trials-myinfo:title:accountInfo")
}}</el-menu-item>
<!-- 管理后台 -->
<el-menu-item
v-if="hasPermi(['role:dev', 'role:oa', 'role:admin'])"
index="4-4"
>{{ $t("trials:trials-myinfo:title:system") }}</el-menu-item
>
<!-- 退出 -->
<el-menu-item index="4-3">{{
$t("trials:trials-myinfo:button:loginout")
@ -171,6 +180,9 @@ export default {
case "4-3":
this.logout();
break;
case "4-4":
this.go("/system");
break;
case "1":
this.go("/trials/trials-inspection");
break;

View File

@ -316,8 +316,8 @@ export default {
trigger: "blur",
},
{
max: 100,
message: `${this.$t("common:ruleMessage:maxLength")} 100`,
max: 500,
message: `${this.$t("common:ruleMessage:maxLength")} 500`,
},
],
ModalityIds: [

View File

@ -184,7 +184,7 @@ export default {
Object.keys(res.Result).forEach((key) => {
this.data[key] = res.Result[key];
});
this.form.PurchaseDuration = this.data.PurchaseDuration;
this.form.PurchaseDuration = this.data.PurchaseDuration * 12;
}
} catch (err) {
console.log(err);

View File

@ -157,4 +157,9 @@ export default {
},
},
};
</script>
</script>
<style lang="scss" scoped>
::v-deep .is-error{
margin-bottom: 44px;
}
</style>

View File

@ -35,7 +35,7 @@
/>
</el-form-item>
<!-- 患者姓名 -->
<el-form-item :label="$t('trials:uploadDicomList:table:patientName')">
<el-form-item :label="$t('trials:rereadTask:table:patientName')">
<el-input
v-model="searchData.PatientName"
style="width: 140px"
@ -169,7 +169,7 @@
<el-table-column type="index" width="40" align="left" />
<!-- 受试者编号 -->
<el-table-column
prop="SubjectCode"
prop="OriginalReReadingTask.SubjectCode"
min-width="100"
:label="$t('trials:reviewTrack:table:subjectCode')"
show-overflow-tooltip
@ -184,11 +184,12 @@
>
<template slot-scope="scope">
<span
v-for="(item, index) in scope.row.PatientList"
v-for="(item, index) in scope.row.OriginalReReadingTask
.PatientList"
:key="`${index}${item.PatientId}`"
>
{{
index === scope.row.PatientList.length - 1
index === scope.row.OriginalReReadingTask.PatientList.length - 1
? item.PatientIdStr
: `${item.PatientIdStr}, `
}}
@ -197,9 +198,9 @@
</el-table-column>
<!-- 患者姓名 -->
<el-table-column
prop="SubjectShortName"
prop="OriginalReReadingTask.SubjectShortName"
min-width="100"
:label="$t('trials:uploadDicomList:table:patientName')"
:label="$t('trials:rereadTask:table:patientName')"
show-overflow-tooltip
sortable="custom"
/>

View File

@ -72,14 +72,14 @@
{{ $t("common:button:reset") }}
</el-button>
<!-- 自动绑定 -->
<el-button
<!-- <el-button
type="primary"
@click="automaticBind"
:loading="automaticBindLoading"
v-if="activeName === 'notSubmit'"
>
{{ $t("trials:study:button:automaticBind") }}
</el-button>
</el-button> -->
</el-form-item>
</el-form>
</template>

View File

@ -0,0 +1,259 @@
<template>
<BaseContainer>
<template slot="search-container">
<el-form :inline="true">
<el-form-item
:label="$t('trials:downloadRecord:table:SubjectCode')"
prop="SubjectCode"
>
<el-input
v-model="searchData.SubjectCode"
size="small"
clearable
style="width: 120px"
/>
</el-form-item>
<el-form-item :label="$t('trials:downloadRecord:table:IP')" prop="IP">
<el-input
v-model="searchData.IP"
size="small"
clearable
style="width: 120px"
/>
</el-form-item>
<el-form-item
:label="$t('trials:downloadRecord:table:VisitName')"
prop="VisitName"
>
<el-input
v-model="searchData.VisitName"
size="small"
clearable
style="width: 120px"
/>
</el-form-item>
<el-form-item
:label="$t('trials:downloadRecord:table:Name')"
prop="LoginUserName"
>
<el-input
v-model="searchData.Name"
size="small"
clearable
style="width: 120px"
/>
</el-form-item>
<!-- 下载日期 -->
<el-form-item :label="$t('trials:downloadRecord:table:DownloadTime')">
<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>
</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: 'DownloadTime', order: 'descending' }"
>
<el-table-column type="index" width="50" />
<!--受试者-->
<el-table-column
:label="$t('trials:downloadRecord:table:SubjectCode')"
prop="SubjectCode"
min-width="90"
show-overflow-tooltip
sortable="custom"
>
</el-table-column>
<!--ip-->
<el-table-column
:label="$t('trials:downloadRecord:table:IP')"
prop="IP"
min-width="90"
show-overflow-tooltip
sortable="custom"
/>
<!--访视名-->
<el-table-column
:label="$t('trials:downloadRecord:table:VisitName')"
prop="VisitName"
min-width="90"
show-overflow-tooltip
sortable="custom"
/>
<!--下载用户名称-->
<el-table-column
:label="$t('trials:downloadRecord:table:DownloadUserName')"
prop="DownloadUserName"
min-width="90"
show-overflow-tooltip
sortable="custom"
>
</el-table-column>
<!--下载用户别名--->
<el-table-column
:label="$t('trials:downloadRecord:table:DownLoadUserFullName')"
prop="DownLoadUserFullName"
min-width="90"
show-overflow-tooltip
sortable="custom"
/>
<!--检查数量--->
<el-table-column
:label="$t('trials:downloadRecord:table:StudyCount')"
prop="StudyCount"
min-width="90"
show-overflow-tooltip
sortable="custom"
/>
<!--下载图像数量--->
<el-table-column
:label="$t('trials:downloadRecord:table:VisitImageFileCount')"
prop="VisitImageFileCount"
min-width="90"
show-overflow-tooltip
sortable="custom"
/>
<!--下载图像大小--->
<el-table-column
:label="$t('trials:downloadRecord:table:VisitImageFileSize')"
prop="VisitImageZipSize"
min-width="90"
show-overflow-tooltip
sortable="custom"
>
<template slot-scope="scope">
<span>{{
scope.row.VisitImageZipSize && scope.row.VisitImageZipSize > 0
? `${(scope.row.VisitImageZipSize / 1024 / 1024).toFixed(2)}MB`
: 0
}}</span>
</template>
</el-table-column>
<!--下载时间--->
<el-table-column
:label="$t('trials:downloadRecord:table:DownloadTime')"
prop="DownloadTime"
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>
</BaseContainer>
</template>
<script>
import { getTrialSubjectVisitDownloadList } from "@/api/inspection";
import BaseContainer from "@/components/BaseContainer";
import Pagination from "@/components/Pagination";
const searchDataDefault = () => {
return {
TrialId: "",
SubjectCode: null,
IP: "",
VisitName: "",
Name: "",
BeginDownloadTime: null,
EndDownloadTime: null,
Asc: false,
SortField: "DownloadTime",
PageIndex: 1,
PageSize: 20,
};
};
export default {
components: { BaseContainer, Pagination },
data() {
return {
searchData: searchDataDefault(),
list: [],
total: 0,
loading: false,
dateValue: [],
};
},
mounted() {
this.getList();
},
methods: {
getList() {
this.loading = true;
this.searchData.TrialId = this.$route.query.trialId;
if (this.dateValue && this.dateValue[0] && this.dateValue[1]) {
this.searchData.BeginDownloadTime = this.$moment(
this.dateValue[0]
).format("YYYY-MM-DD HH:mm:ss");
this.searchData.EndDownloadTime = this.$moment(
this.dateValue[1]
).format("YYYY-MM-DD HH:mm:ss");
} else {
this.searchData.BeginDownloadTime = null;
this.searchData.EndDownloadTime = null;
}
getTrialSubjectVisitDownloadList(this.searchData)
.then((res) => {
this.loading = false;
this.list = res.Result.CurrentPageData;
this.total = res.Result.TotalCount;
})
.catch(() => {
this.loading = false;
});
},
handleSearch() {
this.searchData.PageIndex = 1;
this.getList();
},
//
handleReset() {
this.searchData = searchDataDefault();
this.dateValue = [];
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>