意见反馈影像上传、影像质疑、一致性核查绑定访视
continuous-integration/drone/push Build is passing Details

uat_us
DESKTOP-6C3NK6N\WXS 2024-08-21 13:46:46 +08:00
parent e961829ef1
commit f5c4b49e6f
8 changed files with 1990 additions and 1076 deletions

View File

@ -3,7 +3,7 @@ import FEEDBACKCOMP from "./index.vue";
const FBConstructor = Vue.extend(FEEDBACKCOMP);
const FB = options => {
const { type, callBack, cancelBack, trialId = null, Id = null, visitTaskId = null } = options;
const { type, callBack, cancelBack, trialId = null, Id = null, visitTaskId = null, SubjectVisitId = null } = options;
if (!type) throw `type is requred.but ${type}`
const id = `FB${new Date().getTime()}`;
const instance = new FBConstructor();
@ -12,7 +12,7 @@ const FB = options => {
if (instance.vm.visible) return;
document.body.appendChild(instance.vm.$el);
console.log(type);
instance.vm.open({ type, trialId, Id, visitTaskId });
instance.vm.open({ type, trialId, Id, visitTaskId, SubjectVisitId });
instance.vm.$on("success", (Id) => {
if (callBack) callBack();

View File

@ -14,7 +14,7 @@
{{ title }}
</div>
<!-- 项目详情 -->
<div class="trialsBox" v-if="visitTaskId">
<div class="trialsBox" v-if="visitTaskId || SubjectVisitId">
<el-form
label-position="right"
:model="form"
@ -187,6 +187,7 @@ export default {
TrialSiteId: null,
TrialId: null,
VisitTaskId: null,
SubjectVisitId: null,
ScreenshotList: [],
ScreenshotListStr: null,
},
@ -251,16 +252,15 @@ export default {
},
methods: {
open(data) {
let { type, trialId, Id, visitTaskId } = data;
let { type, trialId, Id, visitTaskId, SubjectVisitId } = data;
this.type = type;
this.trialId = trialId;
this.Id = Id;
this.visitTaskId = visitTaskId;
console.log(visitTaskId, "visitTaskId");
this.SubjectVisitId = SubjectVisitId;
if (visitTaskId) {
this.isImgfail = true;
}
console.log(this.isImgfail, "isImgfail");
this.setTypeOption();
if (!Id) {
this.title = this.setTitle();
@ -284,6 +284,9 @@ export default {
if (this.visitTaskId) {
this.form.VisitTaskId = this.visitTaskId;
}
if (this.SubjectVisitId) {
this.form.SubjectVisitId = this.SubjectVisitId;
}
if (this.Id) {
this.form.Id = this.Id;
}
@ -336,6 +339,9 @@ export default {
if (res.Result.VisitTaskId) {
this.visitTaskId = res.Result.VisitTaskId;
}
if (res.Result.SubjectVisitId) {
this.SubjectVisitId = res.Result.SubjectVisitId;
}
let code = this.$fd("UserType", res.Result.UserTypeEnum);
this.title = this.setTitle(code, res.Result.FeedBackFullName);
if (visitTaskId) {

View File

@ -11,7 +11,8 @@ const getDefaultState = () => {
config: {},
uploadTip: null,
timer: null,
whiteList: []
whiteList: [],
checkTaskId: null
}
}

View File

@ -347,3 +347,6 @@ body .el-table th.gutter {
background: #000;
z-index: 3999;
}
.el-message-box__wrapper{
z-index: 9999 !important;
}

View File

@ -58,6 +58,7 @@ export default {
this.$FB({
type: "feedback",
trialId: this.$route.query.trialId,
SubjectVisitId: this.$store.state.trials.checkTaskId,
});
},
//

View File

@ -1,13 +1,18 @@
<template>
<BaseContainer style="height:100%;">
<BaseContainer style="height: 100%">
<!-- 搜索框 -->
<template slot="search-container">
<el-form :inline="true">
<!-- 中心编号 -->
<el-form-item :label="$t('trials:crcQuestion:table:siteId')">
<el-select v-model="searchData.TrialSiteId" clearable filterable style="width:120px;">
<el-select
v-model="searchData.TrialSiteId"
clearable
filterable
style="width: 120px"
>
<el-option
v-for="(item,index) of siteOptions"
v-for="(item, index) of siteOptions"
:key="index"
:label="item.TrialSiteCode"
:value="item.TrialSiteId"
@ -16,13 +21,16 @@
</el-form-item>
<!-- 受试者编号 -->
<el-form-item :label="$t('trials:crcQuestion:table:subjectId')">
<el-input v-model="searchData.SubjectCode" style="width:100px;" />
<el-input v-model="searchData.SubjectCode" style="width: 100px" />
</el-form-item>
<!-- 访视名称 -->
<el-form-item class="my_multiple" :label="$t('trials:crcQuestion:table:visitName')">
<el-form-item
class="my_multiple"
:label="$t('trials:crcQuestion:table:visitName')"
>
<el-select
v-model="searchData.VisitPlanArray"
style="width:140px"
style="width: 140px"
clearable
multiple
>
@ -34,39 +42,70 @@
>
<span style="float: left">{{ item.VisitName }}</span>
</el-option>
<el-option
key="Other"
label="Out of Plan"
value="1.11"
/>
<el-option key="Other" label="Out of Plan" value="1.11" />
</el-select>
</el-form-item>
<!-- 是否超限 -->
<el-form-item :label="$t('trials:crcQuestion:table:isOverTime')">
<el-select v-model="searchData.IsOverTime" clearable style="width:120px">
<el-option v-for="item of $d.YesOrNo" :value="item.value" :label="item.label" :key="item.id"/>
<el-select
v-model="searchData.IsOverTime"
clearable
style="width: 120px"
>
<el-option
v-for="item of $d.YesOrNo"
:value="item.value"
:label="item.label"
:key="item.id"
/>
</el-select>
</el-form-item>
<el-form-item :label="$t('trials:crcQuestion:table:isClose')">
<el-select v-model="searchData.IsClosed" clearable style="width:120px">
<el-option v-for="item of $d.YesOrNo" :value="item.value" :label="item.label" :key="item.id"/>
<el-select
v-model="searchData.IsClosed"
clearable
style="width: 120px"
>
<el-option
v-for="item of $d.YesOrNo"
:value="item.value"
:label="item.label"
:key="item.id"
/>
</el-select>
</el-form-item>
<el-form-item :label="$t('trials:crcQuestion:table:reuploadSatus')">
<el-select v-model="searchData.ReuploadEnum" clearable style="width:120px">
<el-option v-for="item of $d.ReuploadEnum" :value="item.value" :label="item.label" :key="item.id"/>
<el-select
v-model="searchData.ReuploadEnum"
clearable
style="width: 120px"
>
<el-option
v-for="item of $d.ReuploadEnum"
:value="item.value"
:label="item.label"
:key="item.id"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleSearch">
{{ $t('common:button:search') }}
{{ $t("common:button:search") }}
</el-button>
<el-button type="primary" icon="el-icon-refresh-left" @click="handleReset">
{{ $t('common:button:reset') }}
<el-button
type="primary"
icon="el-icon-refresh-left"
@click="handleReset"
>
{{ $t("common:button:reset") }}
</el-button>
<!--导出-->
<el-button type="primary" icon="el-icon-download" @click="handleExport">
{{ $t('common:button:export') }}
<el-button
type="primary"
icon="el-icon-download"
@click="handleExport"
>
{{ $t("common:button:export") }}
</el-button>
</el-form-item>
</el-form>
@ -76,7 +115,7 @@
<template slot="main-container">
<el-table
v-loading="loading"
v-adaptive="{bottomOffset:60}"
v-adaptive="{ bottomOffset: 60 }"
:data="list"
stripe
height="100"
@ -93,7 +132,7 @@
<template slot-scope="scope">
<el-button
type="text"
:style="{color:scope.row.IsClosed?'':'red'}"
:style="{ color: scope.row.IsClosed ? '' : 'red' }"
@click="handleReplay(scope.row)"
>
{{ scope.row.ChallengeCode }}
@ -132,16 +171,23 @@
sortable="custom"
>
<template slot-scope="scope">
<div v-if="otherInfo.QCProcessEnum === 1">
<!-- {{ scope.row.CurrentQCEnum === 1?'审核':'--' }} -->
<el-tag v-if="scope.row.CurrentQCEnum === 1" type="primary">{{ $fd('CurrentQCType', 0) }}</el-tag>
<el-tag v-if="scope.row.CurrentQCEnum === 1" type="primary">{{
$fd("CurrentQCType", 0)
}}</el-tag>
<span v-else>--</span>
</div>
<div v-else-if="otherInfo.QCProcessEnum === 2">
<!-- {{ scope.row.CurrentQCEnum === 1?'初审':scope.row.CurrentQCEnum === 2?'复审':'--' }} -->
<el-tag v-if="scope.row.CurrentQCEnum === 1" type="primary">{{ $fd('CurrentQCType', scope.row.CurrentQCEnum) }}</el-tag>
<el-tag v-else-if="scope.row.CurrentQCEnum === 2" type="warning">{{ $fd('CurrentQCType', scope.row.CurrentQCEnum) }}</el-tag>
<el-tag v-if="scope.row.CurrentQCEnum === 1" type="primary">{{
$fd("CurrentQCType", scope.row.CurrentQCEnum)
}}</el-tag>
<el-tag
v-else-if="scope.row.CurrentQCEnum === 2"
type="warning"
>{{ $fd("CurrentQCType", scope.row.CurrentQCEnum) }}</el-tag
>
<span v-else>--</span>
</div>
</template>
@ -170,8 +216,10 @@
width="140"
>
<template slot-scope="scope">
<el-tag v-if="scope.row.IsOverTime" type="danger">{{ $fd('YesOrNo', scope.row.IsOverTime) }}</el-tag>
<el-tag v-else>{{ $fd('YesOrNo', scope.row.IsOverTime) }}</el-tag>
<el-tag v-if="scope.row.IsOverTime" type="danger">{{
$fd("YesOrNo", scope.row.IsOverTime)
}}</el-tag>
<el-tag v-else>{{ $fd("YesOrNo", scope.row.IsOverTime) }}</el-tag>
</template>
</el-table-column>
<!-- 最新回复时间 -->
@ -191,8 +239,12 @@
sortable="custom"
>
<template slot-scope="scope">
<el-tag v-if="scope.row.IsClosed">{{ $fd('YesOrNo', scope.row.IsClosed) }}</el-tag>
<el-tag v-else type="danger">{{ $fd('YesOrNo', scope.row.IsClosed) }}</el-tag>
<el-tag v-if="scope.row.IsClosed">{{
$fd("YesOrNo", scope.row.IsClosed)
}}</el-tag>
<el-tag v-else type="danger">{{
$fd("YesOrNo", scope.row.IsClosed)
}}</el-tag>
</template>
</el-table-column>
<!-- 关闭时间 -->
@ -213,9 +265,15 @@
>
<template slot-scope="scope">
<span v-if="scope.row.ReuploadEnum === 0">--</span>
<el-tag v-else-if="scope.row.ReuploadEnum === 1" type="danger">{{ $fd('ReuploadEnum', scope.row.ReuploadEnum) }}</el-tag>
<el-tag v-else-if="scope.row.ReuploadEnum === 2" type="warning">{{ $fd('ReuploadEnum', scope.row.ReuploadEnum) }}</el-tag>
<el-tag v-else-if="scope.row.ReuploadEnum === 3" type="primary">{{ $fd('ReuploadEnum', scope.row.ReuploadEnum) }}</el-tag>
<el-tag v-else-if="scope.row.ReuploadEnum === 1" type="danger">{{
$fd("ReuploadEnum", scope.row.ReuploadEnum)
}}</el-tag>
<el-tag v-else-if="scope.row.ReuploadEnum === 2" type="warning">{{
$fd("ReuploadEnum", scope.row.ReuploadEnum)
}}</el-tag>
<el-tag v-else-if="scope.row.ReuploadEnum === 3" type="primary">{{
$fd("ReuploadEnum", scope.row.ReuploadEnum)
}}</el-tag>
</template>
</el-table-column>
<!-- 重传完成时间 -->
@ -247,7 +305,13 @@
</el-table>
<!-- 分页组件 -->
<pagination class="page" :total="total" :page.sync="searchData.PageIndex" :limit.sync="searchData.PageSize" @pagination="getList" />
<pagination
class="page"
:total="total"
:page.sync="searchData.PageIndex"
:limit.sync="searchData.PageSize"
@pagination="getList"
/>
</template>
<!-- 回复质疑 -->
@ -255,32 +319,54 @@
v-if="chatVisible"
:visible.sync="chatVisible"
:close-on-click-modal="false"
:close-on-press-escape="false"
:before-close="beforeClose"
width="800px"
:title="$t('trials:crcQuestion:dialogTitle:message1') + `(${currentQCRow.SubjectCode} ${currentQCRow.VisitName})`"
:title="
$t('trials:crcQuestion:dialogTitle:message1') +
`(${currentQCRow.SubjectCode} ${currentQCRow.VisitName})`
"
>
<chat-form ref="chatForm" :data="currentQCRow" user-type="crc" :body-parts="otherInfo.BodyPartTypes" :modalities="otherInfo.Modalitys" :subject-visit-id="currentQCRow.Id" :clinical-enum="otherInfo.ClinicalInformationTransmissionEnum" @close="close" @getDialogList="getDialogList" @getNextTask="getNextTask"/>
<chat-form
ref="chatForm"
:data="currentQCRow"
user-type="crc"
:body-parts="otherInfo.BodyPartTypes"
:modalities="otherInfo.Modalitys"
:subject-visit-id="currentQCRow.Id"
:clinical-enum="otherInfo.ClinicalInformationTransmissionEnum"
@close="beforeClose"
@getDialogList="getDialogList"
@getNextTask="getNextTask"
/>
</el-dialog>
</BaseContainer>
</template>
<script>
import { getCRCChallengeList, getTrialSiteSelect, getTrialVisitStageSelect, getQCChallengeDialogList, getNextCRCChallenge } from '@/api/trials'
import { getQCChallengeList_Export } from '@/api/export'
import ChatForm from './components/chatForm'
import BaseContainer from '@/components/BaseContainer'
import Pagination from '@/components/Pagination'
import {
getCRCChallengeList,
getTrialSiteSelect,
getTrialVisitStageSelect,
getQCChallengeDialogList,
getNextCRCChallenge,
} from "@/api/trials";
import { getQCChallengeList_Export } from "@/api/export";
import ChatForm from "./components/chatForm";
import BaseContainer from "@/components/BaseContainer";
import Pagination from "@/components/Pagination";
const searchDataDefault = () => {
return {
IsOverTime: null,
SubjectCode: '',
TrialSiteId: '',
SubjectCode: "",
TrialSiteId: "",
VisitPlanArray: [],
IsClosed: null,
PageIndex: 1,
PageSize: 20
}
}
PageSize: 20,
};
};
export default {
name: 'CrcQusetion',
name: "CrcQusetion",
components: { BaseContainer, Pagination, ChatForm },
data() {
return {
@ -293,115 +379,144 @@ export default {
siteOptions: [],
visitPlanOptions: [],
otherInfo: {},
trialId: this.$route.query.trialId
}
trialId: this.$route.query.trialId,
};
},
mounted() {
this.getList()
this.getSite()
this.getVisitPlanOptions()
this.getList();
this.getSite();
this.getVisitPlanOptions();
},
watch: {
chatVisible() {
if (!this.chatVisible) {
this.$store.state.trials.checkTaskId = null;
}
},
},
methods: {
beforeClose() {
this.chatVisible = false;
this.$store.state.trials.checkTaskId = null;
},
handleExport() {
getQCChallengeList_Export(this.searchData).then(res => {
}).catch(() => { this.loading = false })
getQCChallengeList_Export(this.searchData)
.then((res) => {})
.catch(() => {
this.loading = false;
});
},
//
getList() {
this.loading = true
this.searchData.TrialId = this.trialId
getCRCChallengeList(this.searchData).then(res => {
this.loading = false
this.list = res.Result.CurrentPageData
this.total = res.Result.TotalCount
this.otherInfo = res.OtherInfo
}).catch(() => { this.loading = false })
this.loading = true;
this.searchData.TrialId = this.trialId;
getCRCChallengeList(this.searchData)
.then((res) => {
this.loading = false;
this.list = res.Result.CurrentPageData;
this.total = res.Result.TotalCount;
this.otherInfo = res.OtherInfo;
})
.catch(() => {
this.loading = false;
});
},
//
handleReplay(row) {
this.loading = true
getQCChallengeDialogList(row.Id).then(res => {
this.loading = false
if (res.IsSuccess) {
if (res.Result.length > 0) { Object.assign(row, res.Result[0]) }
this.currentQCRow = { ...row }
this.chatVisible = true
}
}).catch(() => { this.loading = false })
},
close() {
this.chatVisible = false
this.loading = true;
getQCChallengeDialogList(row.Id)
.then((res) => {
this.loading = false;
if (res.IsSuccess) {
if (res.Result.length > 0) {
Object.assign(row, res.Result[0]);
}
this.currentQCRow = { ...row };
this.$store.state.trials.checkTaskId = row.SubjectVisitId;
this.chatVisible = true;
}
})
.catch(() => {
this.loading = false;
});
},
async getNextTask(qcChallengeId) {
try {
const params = {
trialId: this.trialId,
qcChallengeId: qcChallengeId
}
const res = await getNextCRCChallenge(params)
qcChallengeId: qcChallengeId,
};
const res = await getNextCRCChallenge(params);
if (res.IsSuccess) {
const res2 = await getQCChallengeDialogList(res.Result.Id)
const res2 = await getQCChallengeDialogList(res.Result.Id);
if (res2.IsSuccess) {
Object.assign(res.Result, res2.Result[0])
this.chatVisible = false
this.currentQCRow = res.Result
Object.assign(res.Result, res2.Result[0]);
this.chatVisible = false;
this.currentQCRow = res.Result;
this.$nextTick(() => {
this.chatVisible = true
})
this.chatVisible = true;
});
}
}
} catch (e) {
this.chatVisible = false
console.log(e)
this.chatVisible = false;
console.log(e);
}
},
getDialogList() {
this.loading = true
getQCChallengeDialogList(this.currentQCRow.Id).then(res => {
this.loading = false
if (res.IsSuccess && res.Result.length > 0) {
var i = this.list.findIndex(item => item.Id === this.currentQCRow.Id)
if (i > -1) {
this.currentQCRow = Object.assign(this.list[i], res.Result[0])
this.$refs['chatForm'].addMessage(res.Result[0].DialogList[res.Result[0].DialogList.length - 1])
this.loading = true;
getQCChallengeDialogList(this.currentQCRow.Id)
.then((res) => {
this.loading = false;
if (res.IsSuccess && res.Result.length > 0) {
var i = this.list.findIndex(
(item) => item.Id === this.currentQCRow.Id
);
if (i > -1) {
this.currentQCRow = Object.assign(this.list[i], res.Result[0]);
this.$refs["chatForm"].addMessage(
res.Result[0].DialogList[res.Result[0].DialogList.length - 1]
);
}
}
}
}).catch(() => { this.loading = false })
})
.catch(() => {
this.loading = false;
});
},
//
handleReset() {
this.searchData = searchDataDefault()
this.getList()
this.searchData = searchDataDefault();
this.getList();
},
//
handleSearch() {
this.searchData.PageIndex = 1
this.getList()
this.searchData.PageIndex = 1;
this.getList();
},
//
handleSortByColumn(column) {
if (column.order === 'ascending') {
this.searchData.Asc = true
if (column.order === "ascending") {
this.searchData.Asc = true;
} else {
this.searchData.Asc = false
this.searchData.Asc = false;
}
this.searchData.SortField = column.prop
this.searchData.PageIndex = 1
this.getList()
this.searchData.SortField = column.prop;
this.searchData.PageIndex = 1;
this.getList();
},
// site
getSite() {
getTrialSiteSelect(this.trialId).then(res => {
this.siteOptions = res.Result
})
getTrialSiteSelect(this.trialId).then((res) => {
this.siteOptions = res.Result;
});
},
// 访
getVisitPlanOptions() {
getTrialVisitStageSelect(this.trialId)
.then((res) => {
this.visitPlanOptions = res.Result
})
}
}
}
getTrialVisitStageSelect(this.trialId).then((res) => {
this.visitPlanOptions = res.Result;
});
},
},
};
</script>

File diff suppressed because it is too large Load Diff