You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

713 lines
18 KiB

5 months ago
<template>
<div class="throm-interfere-informed">
<a-card style="width:100%" :tab-list="tabList" :active-tab-key="activeTabKey" @tabChange="onTabChange">
<div class="throm-before4-container Informed-container">
<div class="video-container" v-if="activeTabKey == 'tab1'">
<h1 style="text-align: center;font-size: 2rem;line-height: 5rem;font-weight: bold;">急性脑梗塞静脉溶栓治疗知情同意书
</h1>
<div style="transition: all 1s; overflow: hidden; ">
<div v-html="content" class="card-content ql-editor content-detail"
style="white-space: pre-wrap"></div>
</div>
<div class="informed-list">
<div class="informed-item">
<span class="psign">患者签名: </span>
<div class="item-img" v-if="informed.patientSign" @click="lookSign(informed.patientSign)">
<img :src="apiUrl + informed.patientSign" alt="" />
</div>
<div class="item-img" v-else></div>
<a-button :disabled="writeAble" shape="round" class="item-btn"
@click="patientSign = !patientSign">
{{ informed.patientSign ? '重新签名' : '点击签名' }}
</a-button>
</div>
<div class="informed-item1">
<span>签名日期: </span>
<a-input :disabled="writeAble" @focus="changeDate('patientTime')" :value="getPatientTime"
class="item-input" readOnly />
</div>
</div>
<div>
<signature class="item-sign" ref="patientSign" @close="patientSignClose"
@reset="handeReset('patientSign')" v-if="patientSign">
</signature>
</div>
<div class="informed-info informed-info-sky">
如果患者无法签署知情同意书请其授权的亲属在此签名:
</div>
<div class="informed-list before">
<div class="informed-item">
<span>授权亲属签字: </span>
<div class="item-img" v-if="informed.empowerSign" @click="lookSign(informed.empowerSign)">
<img :src="apiUrl + informed.empowerSign" alt="" />
</div>
<div class="item-img" style="min-width: 110px;" v-else> </div>
<a-button :disabled="writeAble" type="continue" shape="round" class="item-btn"
@click="empowerSign = !empowerSign">{{
informed.empowerSign ? '重新签名' : '点击签名'
}}</a-button>
</div>
<div class="informed-item1">
<span>与患者关系</span>
<a-input :disabled="writeAble" v-model="informed.empowerRelation" class="item-input" />
</div>
<!-- <div class="informed-item">
<span>签名日期</span>
<a-input :disabled="writeAble" @focus="changeDate('legalTime')" :value="getLegalTime"
class="item-input" readOnly />
</div> -->
</div>
<div>
<signature class="item-sign" ref="empowerSign" @close="empowerSignClose"
@reset="handeReset('empowerSign')" v-if="empowerSign">
</signature>
</div>
<template v-if="source === 'normal'">
<div class="informed-info">
<strong> 医生陈述 </strong>
</div>
<div class="informed-info">
我已经告知患者将要进行的治疗方式此次治疗及术后可能发生的并发症和风险可能存在的其它治疗方法并且解答了患者关于此次治疗的相关问题
</div>
<div class="informed-list">
<div class="informed-item">
<span>医生签名: </span>
<div class="item-img" v-if="informed.doctorSign" @click="lookSign(informed.doctorSign)">
<img :src="apiUrl + informed.doctorSign" alt="" />
</div>
<div class="item-img" v-else> </div>
<a-button :disabled="writeAble" type="continue" shape="round" class="item-btn"
@click="doctorSign = !doctorSign">{{
informed.doctorSign
? '重新签名'
: '点击签名'
}}</a-button>
</div>
<div class="informed-item1">
<span>签名日期</span>
<a-input :disabled="writeAble" @focus="changeDate('doctorTime')" :value="getDoctorTime"
class="item-input" readOnly />
</div>
</div>
<div>
<signature class="item-sign" ref="doctorSign" @close="doctorSignClose"
@reset="handeReset('doctorSign')" v-if="doctorSign">
</signature>
</div>
</template>
<div class="common-picker">
<van-datetime-picker v-if="picker" v-model="currentDate" type="date" @confirm="confirmPicker"
@cancel="picker = false" />
</div>
</div>
<div class="video-container" v-if="activeTabKey == 'tab2'">
<div class="upload-informed-container">
<div class="upload-container">
<div class="info">知情同意图片</div>
<div class="upload-list" style="min-height: 300px;" v-if="fileList.length">
<!-- <div class="upload-list-item" v-for="(item, index) in fileList" :key="index"
@click="handlePreview(item)">
<div class="img">
<img :src="item" alt="" />
</div>
</div> -->
<div class="upload-list-item" v-for="(item, index) in fileList" :key="index"
@click="handlePreview(item)">
<div class="img">
<img :src="item" alt="" />
</div>
<div class="delete" @click="del(index)">
<a-icon type="close-circle" theme="filled" />
</div>
</div>
</div>
<div class="plus" v-if="fileList.length < 5" @click="openCamera">
<a-icon type="plus" />
</div>
<div class="emtpy" style="padding: 60px 0;" v-else>
<a-empty :image="emptyImage" description="暂无图片" />
</div>
</div>
<a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
<img style="width: 100%" :src="previewImage" />
</a-modal>
</div>
</div>
<div class="video-container" v-if="activeTabKey == 'tab3'">
<div class="info">百人中使用药物结果分布情况</div>
<div class="img">
<img src="@/assets/images/100.png" alt="" style="width: 100%;" />
</div>
<div class="image-container">
<video :src="getVideo" controls autoplay loop muted v-if="getVideo" width="100%">
您的浏览器不支持 video 标签
</video>
<!-- <div class="notImg" v-else>溶栓视频安全区</div> -->
<div class="emtpy" v-else>
<a-empty :image="emptyImage" description="未检测到影像信息" />
</div>
</div>
</div>
</div>
</a-card>
<a-modal :width="650" :destroyOnClose="true" v-model="lookVisable" title="查看签名" :footer="null">
<div class="modal-content">
<img :src="apiUrl + currentSign" alt="" style="width: 100%; height: 100%;" />
</div>
</a-modal>
5 months ago
<div class="throm-common-button">
<a-button :disabled="writeAble" class="" type="primary" size="large" block @click="onSubmitSign"
v-if="!disabled && activeTabKey == 'tab1'">提交</a-button>
<a-button :disabled="writeAble" class="" block type="primary" size="large" @click="onSubmit">下一步</a-button>
5 months ago
</div>
</div>
</template>
<script>
import {
mapState,
mapMutations
} from 'vuex';
import signature from '@/components/signature/signature';
import emptyImage from '@/assets/images/slice/empty.png'
import {
imgUrl
} from '@/config/setting.js';
import {
uploadfile,
saveInformedConsent,
queryConsentResult,
thTime,
uploadBase64,
4 months ago
queryVideo,
queryBook
5 months ago
} from 'api';
export default {
name: 'ThromBefor4',
props: {
source: {
type: String,
default: 'normal',
},
},
data() {
return {
emptyImage,
activeTabKey: 'tab1',
tabList: [{
key: 'tab1',
tab: '知情同意',
},
{
key: 'tab2',
tab: '拍照上传',
},
{
key: 'tab3',
tab: '谈话辅助工具',
}
],
apiUrl: imgUrl,
informed: {
doctorSign: '',
doctorTime: '',
patientSign: '',
patientTime: '',
empowerSign: '',
empowerRelation: '',
empowerMobile: '',
legalTime: '',
},
content: '',
picker: false,
lookVisable: false,
currentSign: '',
currentDate: new Date(),
patientSign: '',
empowerSign: '',
doctorSign: '',
disabled: false,
previewVisible: false,
previewImage: '',
fileList: [],
}
},
components: {
signature,
},
computed: {
...mapState('patient', ['patientData', 'book', 'video', 'writeAble']),
getDoctorTime() {
const {
informed
} = this;
if (!informed.doctorTime) return;
return informed.doctorTime.split(' ')[0];
},
getPatientTime() {
const {
informed
} = this;
if (!informed.patientTime) return;
return informed.patientTime.split(' ')[0];
},
getLegalTime() {
const {
informed
} = this;
if (!informed.legalTime) return;
return informed.legalTime.split(' ')[0];
},
getVideo() {
let path;
this.video.forEach((item) => {
if (item.type === 1) {
path = item.path;
}
});
// console.log('path: ', path);
return this.apiUrl + path;
},
},
created() {
// console.log('book', this.book)
this.queryVideo()
4 months ago
// this.queryBook(); //知情同意
4 months ago
this.content = this.book.find((item) => item.type === 1)?.content || '';
5 months ago
// console.log(this.content);
},
mounted() {
this.queryConsentResult();
this.thTime();
const {
recordValDict
} = this.patientData;
if (recordValDict) {
this.$nextTick(() => {
this.echo(recordValDict);
});
}
},
methods: {
...mapMutations('patient', ['setVideo']),
uploadImage() {
},
4 months ago
async queryBook() {
let res = await queryBook({type: 1});
const {
data,
code,
msg
} = res;
console.log('介入 book', data)
if (code === 200) {
this.setBook(data);
}
},
5 months ago
async queryVideo() {
let res = await queryVideo();
const {
data,
code,
msg
} = res;
if (code === 200) {
this.setVideo(data.list);
}
},
onSubmit() {
this.$emit('next')
},
async onSubmitSign() {
const {
informed
} = this;
const {
firstAidId
} = this.patientData;
if (!firstAidId) return this.$message.error('缺少急救');
let res = await saveInformedConsent({
...informed,
firstAidId,
templateText: this.content,
4 months ago
type: 1,
5 months ago
});
const {
code,
data,
msg
} = res;
if (code === 200) {
this.$message.success('保存成功');
// this.$emit('next')
// if (this.source === 'first') {
// this.$emit('on-success', true);
// } else {
// // this.$router.go(-1);
// }
}
},
handleNext() {
this.$emit('next')
},
onTabChange(key, type) {
this.activeTabKey = key;
},
lookSign(url) {
this.currentSign = url;
this.lookVisable = true;
},
changeDate(type) {
this.picker = true;
this.type = type;
if (this.informed[type]) {
this.currentDate = new Date(this.informed[type]);
}
},
confirmPicker(date) {
console.log(date)
let y = date.getFullYear();
let m = date.getMonth() + 1;
m = m < 10 ? '0' + m : m;
let d = date.getDate();
d = d < 10 ? '0' + d : d;
let dateTime = y + '-' + m + '-' + d;
this.picker = false;
this.informed[this.type] = dateTime;
},
async thTime() {
if (this.writeAble) {
return;
}
const {
firstAidId
} = this.patientData;
if (!firstAidId) return this.$message.error('缺少急救');
let res = await thTime({
firstAidId,
});
const {
code,
data,
msg
} = res;
if (code === 200) {
//
}
},
async queryConsentResult() {
const {
firstAidId
} = this.patientData;
if (!firstAidId) return this.$message.error('缺少急救');
let res = await queryConsentResult({
firstAidId,
4 months ago
type: 1,
5 months ago
});
const {
code,
data,
msg
} = res;
if (code === 200) {
4 months ago
console.log('result 溶栓',this.informed, data)
5 months ago
this.utils.merge(this.informed, data);
}
},
// 谈话医师签名:
doctorSignClose(params) {
const file = params;
// 使用FormData传参数和文件
var form = new FormData();
// 文件
form.append('file', file);
uploadfile(form).then((res) => {
if (res.code === 200) {
this.informed.doctorSign = res.url;
4 months ago
const now = new Date()
let y = now.getFullYear();
let m = now.getMonth() + 1;
m = m < 10 ? '0' + m : m;
let d = now.getDate();
d = d < 10 ? '0' + d : d;
let dateTime = y + '-' + m + '-' + d;
this.informed.doctorTime = dateTime;
5 months ago
this.$message.success('谈话医师签名保存成功');
this.doctorSign = false;
} else {
this.$message.error('谈话医师签名保存失败');
}
});
},
// 患者本人签名:
patientSignClose(params) {
const file = params;
// 使用FormData传参数和文件
var form = new FormData();
// 文件
form.append('file', file);
uploadfile(form).then((res) => {
if (res.code === 200) {
this.informed.patientSign = res.url;
4 months ago
const now = new Date()
let y = now.getFullYear();
let m = now.getMonth() + 1;
m = m < 10 ? '0' + m : m;
let d = now.getDate();
d = d < 10 ? '0' + d : d;
let dateTime = y + '-' + m + '-' + d;
this.informed.patientTime = dateTime;
5 months ago
this.$message.success('患者本人签名保存成功');
this.patientSign = false;
} else {
this.$message.error('患者本人签名保存失败');
}
});
},
// 授权人签名
empowerSignClose(params) {
const file = params;
var form = new FormData();
form.append('file', file);
uploadfile(form).then((res) => {
if (res.code === 200) {
this.informed.empowerSign = res.url;
4 months ago
const now = new Date();
let y = now.getFullYear();
let m = now.getMonth() + 1;
m = m < 10 ? '0' + m : m;
let d = now.getDate();
d = d < 10 ? '0' + d : d;
let dateTime = y + '-' + m + '-' + d;
this.informed.legalTime = dateTime;
5 months ago
this.$message.success('授权人签名保存成功');
this.empowerSign = false;
} else {
this.$message.error('授权人签名保存失败');
}
});
},
handeReset(value) {
this.informed[value] = null;
},
echo(data) {
if (data['JMRS-ZQTY-PIC']) {
const {
answer
} = data['JMRS-ZQTY-PIC'][0];
this.fileList = answer;
}
},
del(index) {
if (this.writeAble) {
this.$message.success('患者已审核,内容不可更改');
return;
}
this.fileList.splice(index, 1);
},
handleCancel() {
this.previewVisible = false;
},
async handlePreview(path) {
this.previewImage = path;
this.previewVisible = true;
},
openCamera() {
if (this.writeAble) {
this.$message.success('患者已审核,内容不可更改');
return;
}
const cmr = plus.camera.getCamera();
const res = cmr.supportedImageResolutions[0];
const fmt = cmr.supportedImageFormats[0];
cmr.captureImage(
(path) => {
plus.io.resolveLocalFileSystemURL(
path,
(entry) => {
//压缩图片
this.compressImage(entry.toLocalURL(), entry.name);
},
(e) => {
plus.nativeUI.toast(
'读取拍照文件错误:' + e.message
);
}
);
},
(error) => {
// alert("Capture image failed: " + error.message);
}, {
resolution: res,
format: fmt,
filter: 'image',
}
);
},
//压缩图片
compressImage(url, filename) {
var name = '_doc/upload/' + filename;
plus.zip.compressImage({
src: url, //src: (String 类型 )压缩转换原始图片的路径
dst: name, //压缩转换目标图片的路径
quality: 90, //quality: (Number 类型 )压缩图片的质量.取值范围为1-100
overwrite: true, //overwrite: (Boolean 类型 )覆盖生成新文件
width: '250',
height: '320',
},
(zip) => {
//页面显示图片
this.showPics(zip.target, name);
},
(error) => {
plus.nativeUI.toast('压缩图片失败,请稍候再试');
}
);
},
//显示图片
showPics(url, name) {
let _this = this;
//根据路径读取到文件
plus.io.resolveLocalFileSystemURL(url, (entry) => {
entry.file((file) => {
var fileReader = new plus.io.FileReader();
fileReader.readAsDataURL(file);
fileReader.onloadend = (e) => {
var picUrl = e.target.result.toString();
this.uploadBase64(picUrl, file.name);
};
});
});
},
// 上传成功回
async uploadBase64(base64, fileName) {
if (!base64) return '您还未选择图片';
let res = await uploadBase64({
base64,
fileName,
});
const {
realPath,
code,
msg
} = res;
if (code === 200) {
this.fileList.push(realPath);
} else {
this.$message.error(res.msg);
}
},
}
}
</script>
<style lang="less" scoped>
.throm-interfere-informed {
padding: 10px;
.video-container {
.info {
5 months ago
font-size: 18px;
5 months ago
margin-bottom: 2rem;
}
.plus {
width: 180px;
height: 180px;
display: flex;
align-items: center;
justify-content: center;
background: #ffffff;
border: 2px dashed #a3acbf;
border-radius: 12px;
font-size: 40px;
color: #a3acbf;
}
.upload-list {
display: flex;
flex-wrap: wrap;
.upload-list-item {
width: 180px;
margin-right: 3%;
margin-bottom: 10px;
background: #f2f2f2;
display: flex;
justify-content: center;
align-items: center;
position: relative;
.img {
width: 180px;
height: 180px;
overflow: hidden;
overflow: hidden;
border-radius: 12px;
background: #f2f2f2;
img {
width: 100%;
height: auto;
}
}
.delete {
position: absolute;
right: -5px;
top: -10px;
.anticon {
font-size: 26px;
color: #7690e5;
}
}
}
}
.ant-upload-select-picture-card i {
font-size: 32px;
color: #999;
}
.ant-upload-select-picture-card .ant-upload-text {
margin-top: 8px;
color: #666;
}
}
.image-container {
margin-top: 3rem;
margin-bottom: 2rem;
.notImg {
background-color: #000000;
color: #ffffff;
text-align: center;
line-height: 50vh;
font-size: 2rem;
}
.emtpy {
height: 50vh;
display: flex;
justify-content: center;
align-items: center;
}
}
}
</style>
<style lang="less">
.throm-interfere-informed {}
</style>