中心调查表链接添加二维码
continuous-integration/drone/push Build is passing Details

uat_us
wangxiaoshuang 2024-07-15 15:52:47 +08:00
parent e45903d55e
commit 7f36aa5a05
3 changed files with 334 additions and 134 deletions

View File

@ -50,6 +50,7 @@
"path-to-regexp": "2.4.0",
"pdfobject": "^2.2.8",
"popper.js": "^1.16.1",
"qrcodejs2": "0.0.2",
"sass-loader": "^8.0.0",
"screenfull": "^4.2.0",
"sortablejs": "^1.15.0",

View File

@ -455,7 +455,7 @@ $cursor: #fff;
<style lang="scss" scoped>
$bg: #2d3a4b;
$dark_gray: #0093dd;
$dark_gray: #889aa4;
$light_gray: #606266;
.login-container {
position: relative;

View File

@ -5,9 +5,14 @@
<el-form :inline="true">
<!-- 中心 -->
<el-form-item :label="$t('trials:researchRecord: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"
@ -20,17 +25,21 @@
v-model="searchData.UserKeyInfo"
class="mr"
clearable
:placeholder="`${$t('trials:researchRecord:placeholder:contactorInfo')}`"
style="width:140px;"
:placeholder="`${$t(
'trials:researchRecord:placeholder:contactorInfo'
)}`"
style="width: 140px"
/>
</el-form-item>
<!-- 初审人 -->
<el-form-item :label="$t('trials:researchRecord:table:preliminaryUser')">
<el-form-item
:label="$t('trials:researchRecord:table:preliminaryUser')"
>
<el-input
v-model="searchData.PreliminaryUserName"
class="mr"
clearable
style="width:140px;"
style="width: 140px"
/>
</el-form-item>
<!-- 审核人 -->
@ -39,14 +48,19 @@
v-model="searchData.ReviewerUserName"
class="mr"
clearable
style="width:140px;"
style="width: 140px"
/>
</el-form-item>
<!-- 状态 -->
<el-form-item :label="$t('trials:researchRecord:table:status')">
<el-select v-model="searchData.State" clearable filterable style="width:120px;">
<el-select
v-model="searchData.State"
clearable
filterable
style="width: 120px"
>
<el-option
v-for="(item,index) of $d.ResearchRecord"
v-for="(item, index) of $d.ResearchRecord"
:key="index"
:label="item.label"
:value="item.value"
@ -55,8 +69,19 @@
</el-form-item>
<!-- 是否废除 -->
<el-form-item :label="$t('trials:researchRecord:table:isDeleted')">
<el-select v-model="searchData.IsDeleted" clearable filterable style="width:120px;">
<el-option v-for="item of $d.YesOrNo" v-show="item.raw.ValueCN !== ''" :key="`IsDeleted${item.value}`" :label="item.label" :value="item.value" />
<el-select
v-model="searchData.IsDeleted"
clearable
filterable
style="width: 120px"
>
<el-option
v-for="item of $d.YesOrNo"
v-show="item.raw.ValueCN !== '无'"
:key="`IsDeleted${item.value}`"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<!-- 更新时间 -->
@ -66,34 +91,42 @@
type="daterange"
value-format="yyyy-MM-dd"
format="yyyy-MM-dd"
style="width:250px;"
style="width: 250px"
/>
</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
v-hasPermi="['trials:trials-panel:attachments:site-research:summary-record']"
v-hasPermi="[
'trials:trials-panel:attachments:site-research:summary-record',
]"
type="primary"
icon="el-icon-info"
@click="showResearchUser"
>
{{ $t('trials:researchRecord:button:questionStaffs') }}
{{ $t("trials:researchRecord:button:questionStaffs") }}
</el-button>
<!-- 调查表链接 -->
<el-button
v-hasPermi="['trials:trials-panel:attachments:site-research:questionnaire-link']"
v-hasPermi="[
'trials:trials-panel:attachments:site-research:questionnaire-link',
]"
type="primary"
icon="el-icon-link"
@click="showResearchLink"
>
{{ $t('trials:researchRecord:button:questionLink') }}
{{ $t("trials:researchRecord:button:questionLink") }}
</el-button>
</el-form>
</template>
@ -103,7 +136,7 @@
<el-table
ref="siteResearchList"
v-loading="loading"
v-adaptive="{bottomOffset:60}"
v-adaptive="{ bottomOffset: 60 }"
:data="list"
stripe
height="100"
@ -153,7 +186,11 @@
show-overflow-tooltip
>
<template slot-scope="scope">
{{ scope.row.PreliminaryUser?scope.row.PreliminaryUser.RealName:"" }}
{{
scope.row.PreliminaryUser
? scope.row.PreliminaryUser.RealName
: ""
}}
</template>
</el-table-column>
<!-- 审核人 -->
@ -164,7 +201,7 @@
show-overflow-tooltip
>
<template slot-scope="scope">
{{ scope.row.ReviewerUser?scope.row.ReviewerUser.RealName:"" }}
{{ scope.row.ReviewerUser ? scope.row.ReviewerUser.RealName : "" }}
</template>
</el-table-column>
<!-- 状态 -->
@ -175,10 +212,18 @@
show-overflow-tooltip
>
<template slot-scope="scope">
<el-tag v-if="scope.row.State === 0" type="primary">{{ $fd('ResearchRecord', scope.row.State) }}</el-tag>
<el-tag v-if="scope.row.State === 1" type="info">{{ $fd('ResearchRecord', scope.row.State) }}</el-tag>
<el-tag v-if="scope.row.State === 2" type="warning">{{ $fd('ResearchRecord', scope.row.State) }}</el-tag>
<el-tag v-if="scope.row.State === 3" type="danger">{{ $fd('ResearchRecord', scope.row.State) }}</el-tag>
<el-tag v-if="scope.row.State === 0" type="primary">{{
$fd("ResearchRecord", scope.row.State)
}}</el-tag>
<el-tag v-if="scope.row.State === 1" type="info">{{
$fd("ResearchRecord", scope.row.State)
}}</el-tag>
<el-tag v-if="scope.row.State === 2" type="warning">{{
$fd("ResearchRecord", scope.row.State)
}}</el-tag>
<el-tag v-if="scope.row.State === 3" type="danger">{{
$fd("ResearchRecord", scope.row.State)
}}</el-tag>
</template>
</el-table-column>
<!-- 是否废除 -->
@ -189,8 +234,12 @@
show-overflow-tooltip
>
<template slot-scope="scope">
<el-tag v-if="scope.row.IsDeleted" type="danger">{{ $fd('YesOrNo', scope.row.IsDeleted) }}</el-tag>
<el-tag v-else type="primary">{{ $fd('YesOrNo', scope.row.IsDeleted) }}</el-tag>
<el-tag v-if="scope.row.IsDeleted" type="danger">{{
$fd("YesOrNo", scope.row.IsDeleted)
}}</el-tag>
<el-tag v-else type="primary">{{
$fd("YesOrNo", scope.row.IsDeleted)
}}</el-tag>
</template>
</el-table-column>
<!-- 更新时间 -->
@ -200,9 +249,7 @@
min-width="150"
show-overflow-tooltip
/>
<el-table-column
width="150"
>
<el-table-column width="150">
<template slot-scope="scope">
<!-- 查看 -->
<el-button
@ -214,7 +261,9 @@
/>
<!-- 审批 -->
<el-button
v-hasPermi="['trials:trials-panel:attachments:site-research:auidt']"
v-hasPermi="[
'trials:trials-panel:attachments:site-research:auidt',
]"
:disabled="scope.row.State === 0 || scope.row.State === 3"
circle
:title="$t('trials:researchRecord:action:view')"
@ -223,7 +272,9 @@
/>
<!-- 废除 -->
<el-button
v-hasPermi="['trials:trials-panel:attachments:site-research:abolish']"
v-hasPermi="[
'trials:trials-panel:attachments:site-research:abolish',
]"
:disabled="scope.row.State !== 0 || scope.row.IsDeleted"
circle
:title="$t('trials:researchRecord:action:abolish')"
@ -235,7 +286,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>
<!-- 中心人员 -->
@ -246,10 +303,12 @@
custom-class="base-dialog-wrapper"
:fullscreen="true"
>
<div class="base-modal-body" style="border:1px solid #ccc;padding: 10px">
<div
class="base-modal-body"
style="border: 1px solid #ccc; padding: 10px"
>
<Users v-if="researchUserVisible" />
</div>
</el-dialog>
<!-- 调查表 -->
@ -265,53 +324,87 @@
<!-- 调查表链接 -->
<base-model :config="share_model">
<template slot="dialog-body">
<div>
<i style="color:#428bca;" class="el-icon-success" />
<!-- 成功创建调查表链接 -->
<span>{{ $t('trials:researchRecord:message:createLinkSuccessfully') }}</span>
</div>
<div style="margin:10px 0;">
<!-- 链接 -->
{{ $t('trials:researchRecord:label:link') }}
<el-input ref="shareLink" v-model="shareLink" readonly type="textarea" autosize />
</div>
<div>
<!-- 复制链接 -->
<el-button type="primary" round @click="copyLink">
{{ $t('trials:researchRecord:button:copyLink') }}
</el-button>
<div style="width: 100%; display: flex">
<div class="shareLink">
<div>
<i style="color: #428bca" class="el-icon-success" />
<!-- 成功创建调查表链接 -->
<span>{{
$t("trials:researchRecord:message:createLinkSuccessfully")
}}</span>
</div>
<div style="margin: 10px 0">
<!-- 链接 -->
{{ $t("trials:researchRecord:label:link") }}
<el-input
ref="shareLink"
v-model="shareLink"
readonly
type="textarea"
autosize
/>
</div>
<div>
<!-- 复制链接 -->
<el-button
type="primary"
round
@click="copyLink"
class="shareLinkBtn"
>
{{ $t("trials:researchRecord:button:copyLink") }}
</el-button>
</div>
</div>
<div class="shareCode">
<div class="qrCode">
<div id="qrcode" ref="qrcode"></div>
</div>
<div class="codeBtnBox">
<el-button @click="handleCopyImg" type="primary" round>{{
$t("trials:researchRecord:button:copyCode")
}}</el-button>
<el-button @click="savePic" round>{{
$t("trials:researchRecord:button:savePic")
}}</el-button>
</div>
</div>
</div>
</template>
</base-model>
</BaseContainer>
</template>
<script>
import { getTrialSiteSurveyList, getTrialSiteSelect, abandonSiteSurvey } from '@/api/trials'
import { changeURLStatic } from '@/utils/history.js'
import BaseContainer from '@/components/BaseContainer'
import Pagination from '@/components/Pagination'
import Users from './components/users'
import ResearchForm from '@/views/research/form'
import BaseModel from '@/components/BaseModel'
import {
getTrialSiteSurveyList,
getTrialSiteSelect,
abandonSiteSurvey,
} from "@/api/trials";
import { changeURLStatic } from "@/utils/history.js";
import BaseContainer from "@/components/BaseContainer";
import Pagination from "@/components/Pagination";
import Users from "./components/users";
import ResearchForm from "@/views/research/form";
import BaseModel from "@/components/BaseModel";
import QRCode from "qrcodejs2";
const searchDataDefault = () => {
return {
SortField: '',
SortField: "",
Asc: true,
PageIndex: 1,
PageSize: 20,
TrialSiteId: '',
UserKeyInfo: '',
TrialSiteId: "",
UserKeyInfo: "",
State: null,
IsDeleted: '',
IsDeleted: "",
DateRange: [],
PreliminaryUserName: null,
ReviewerUserName: null
}
}
ReviewerUserName: null,
};
};
export default {
name: 'SiteResearchList',
name: "SiteResearchList",
components: { BaseContainer, Pagination, Users, ResearchForm, BaseModel },
data() {
return {
@ -323,117 +416,223 @@ export default {
siteOptions: [],
researchUserVisible: false,
researchInfoVisible: false,
share_model: { visible: false, title: '', width: '500px' },
shareLink: '',
researchState: this.$d.ResearchRecord
}
share_model: {
visible: false,
title: this.$t("trials:researchRecord:title:shark"),
width: "800px",
},
shareLink: "",
researchState: this.$d.ResearchRecord,
qrcode: null,
};
},
mounted() {
this.getList()
this.getSite()
this.getList();
this.getSite();
},
methods: {
//
getList() {
this.loading = true
this.searchData.TrialId = this.trialId
this.loading = true;
this.searchData.TrialId = this.trialId;
if (this.searchData.DateRange && this.searchData.DateRange.length === 2) {
this.searchData.UpdateTimeBegin = this.searchData.DateRange[0]
this.searchData.updateTimeEnd = this.searchData.DateRange[1]
this.searchData.UpdateTimeBegin = this.searchData.DateRange[0];
this.searchData.updateTimeEnd = this.searchData.DateRange[1];
} else {
this.searchData.UpdateTimeBegin = ''
this.searchData.updateTimeEnd = ''
this.searchData.UpdateTimeBegin = "";
this.searchData.updateTimeEnd = "";
}
getTrialSiteSurveyList(this.searchData).then(res => {
this.loading = false
this.list = res.Result.CurrentPageData
this.total = res.Result.TotalCount
}).catch(() => {
this.loading = false
})
getTrialSiteSurveyList(this.searchData)
.then((res) => {
this.loading = false;
this.list = res.Result.CurrentPageData;
this.total = res.Result.TotalCount;
})
.catch(() => {
this.loading = false;
});
},
//
handleViewResearchList(row) {
changeURLStatic('trialSiteSurveyId', row.Id)
this.researchInfoVisible = true
changeURLStatic("trialSiteSurveyId", row.Id);
this.researchInfoVisible = true;
},
//
handleRepealResearch(row) {
//
this.$confirm(this.$t('trials:researchRecord:message:abolish'), {
type: 'warning',
distinguishCancelAndClose: true
})
.then(() => {
abandonSiteSurvey(this.trialId, row.Id)
.then(res => {
if (res.IsSuccess) {
this.getList()
//
this.$message.success(this.$t('trials:researchRecord:message:abolishSuccessfully'))
}
})
})
this.$confirm(this.$t("trials:researchRecord:message:abolish"), {
type: "warning",
distinguishCancelAndClose: true,
}).then(() => {
abandonSiteSurvey(this.trialId, row.Id).then((res) => {
if (res.IsSuccess) {
this.getList();
//
this.$message.success(
this.$t("trials:researchRecord:message:abolishSuccessfully")
);
}
});
});
},
//
showResearchUser() {
this.researchUserVisible = true
this.researchUserVisible = true;
},
//
copyLink() {
//
this.$copyText(`${this.$t('trials:researchRecord:message:researchFormLink')}: ${this.shareLink}`).then(
res => {
this.$copyText(
`${this.$t("trials:researchRecord:message:researchFormLink")}: ${
this.shareLink
}`
)
.then((res) => {
//
this.$message.success(this.$t('trials:researchRecord:message:copySuccessfully'))
}
).catch(() => {
//
this.$alert(this.$t('trials:researchRecord:message:copyFailed'))
})
this.$message.success(
this.$t("trials:researchRecord:message:copySuccessfully")
);
})
.catch(() => {
//
this.$alert(this.$t("trials:researchRecord:message:copyFailed"));
});
},
//
creatQrCode() {
this.$refs.qrcode.innerHTML = ""; //
let text = this.shareLink;
this.qrcode = new QRCode(this.$refs.qrcode, {
text: text, // ,#
width: 200,
height: 200,
colorDark: "#000000",
colorLight: "#ffffff",
correctLevel: QRCode.CorrectLevel.H,
});
// qrcode.clear(); //
},
//
savePic() {
let qrCodeCanvas = document
.getElementById("qrcode")
.getElementsByTagName("canvas");
let a = document.createElement("a");
a.href = qrCodeCanvas[0].toDataURL("image/url");
a.download = `${this.$t("trials:researchRecord:title:code")}.png`;
a.click();
},
//
handleCopyImg() {
let qrCodeCanvas = document
.getElementById("qrcode")
.getElementsByTagName("canvas");
qrCodeCanvas[0].toBlob(async (blob) => {
console.log(blob);
const data = [
new ClipboardItem({
[blob.type]: blob,
}),
]; // https://w3c.github.io/clipboard-apis/#dom-clipboard-write
await navigator.clipboard.write(data).then(
() => {
this.$message.success(
this.$t("trials:researchRecord:message:copySuccess")
);
},
() => {
this.$message.error(
this.$t("trials:researchRecord:message:UnableWrite")
);
}
);
});
},
// site
getSite() {
getTrialSiteSelect(this.trialId).then(res => {
this.siteOptions = res.Result
})
getTrialSiteSelect(this.trialId).then((res) => {
this.siteOptions = res.Result;
});
},
//
showResearchLink() {
const trialId = this.trialId
this.shareLink = `${location.protocol}//${location.host}/researchLogin?trialId=${trialId}&lang=${this.$i18n.locale}`
this.share_model.visible = true
const trialId = this.trialId;
this.shareLink = `${location.protocol}//${location.host}/researchLogin?trialId=${trialId}&lang=${this.$i18n.locale}`;
this.share_model.visible = true;
this.$nextTick(() => {
this.creatQrCode();
});
},
//
handleReset() {
this.searchData = searchDataDefault()
this.searchData.DateRange = []
this.searchData = searchDataDefault();
this.searchData.DateRange = [];
if (this.searchData.DateRange && this.searchData.DateRange.length === 2) {
this.searchData.UpdateTimeBegin = this.searchData.DateRange[0]
this.searchData.updateTimeEnd = this.searchData.DateRange[1]
this.searchData.UpdateTimeBegin = this.searchData.DateRange[0];
this.searchData.updateTimeEnd = this.searchData.DateRange[1];
} else {
this.searchData.UpdateTimeBegin = ''
this.searchData.updateTimeEnd = ''
this.searchData.UpdateTimeBegin = "";
this.searchData.updateTimeEnd = "";
}
this.getList()
this.getList();
this.$nextTick(() => {
this.$refs.siteResearchList.clearSort()
})
this.$refs.siteResearchList.clearSort();
});
},
//
handleSearch() {
this.getList()
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.getList()
this.searchData.SortField = column.prop;
this.getList();
},
},
beforeDestroy() {
if (this.qrcode) {
this.qrcode = null;
}
},
};
</script>
<style lang="scss" scoped>
.shareLink {
padding-right: 20px;
width: 50%;
position: relative;
.shareLinkBtn{
position: absolute;
bottom: 0px;
left: 0px;
}
}
</script>
.shareCode {
width: 50%;
border-left: 1px solid #eee;
display: flex;
justify-content: center;
flex-wrap: wrap;
.qrCode {
width: 220px;
height: 220px;
display: flex;
border: 1px solid #c0c4cc;
border-radius: 5px;
box-shadow: 1px 1px 5px #c0c4cc;
align-items: center;
justify-content: center;
}
.codeBtnBox {
margin-top: 20px;
width: 100%;
display: flex;
justify-content: space-around;
}
}
</style>