<template>
<view class="container">
<view class="question" v-if="current && current != 'finish'">
<view class="title">
<view class="title_num">{{ current.serial_no }}</view>
<view class="title_value">
<text>{{ current.type | typeFormat }}</text>
<text class="title_value_require" v-if="current.require == 1">*</text>
</view>
</view>
<view class="value">
<text class="value_name">题目:</text>
<text class="value_title">{{ current.title }}</text>
</view>
<view class="tips" v-if="current.explain">{{ current.explain }}</view>
<view class="type">
<!-- 评分 -->
<view class="type_star" v-if="current.type == 'score'">
<u-rate :count="5" v-model="star" active-color="#02b7cb" gutter="20" size="34" :touchable="false">
</u-rate>
<view class="type_star_score" v-if="star != 0">
您的评分:<text>{{ star }} 分</text>
</view>
</view>
<!-- 单选 -->
<view class="type_radio" v-if="current.type == 'radio'">
<u-radio-group v-model="radio" placement="column" :size="26">
<view class="type_radio_box" v-for="item of current.options" :key="item.key">
<u-radio :name="item.value" :label="item.value" checked-color="#2ec0d5">
{{ item.value }}
</u-radio>
<input v-if="
current.opinion == 0 &&
item.opinion == 1 &&
radio == item.value
" v-model="opinionValue" required :placeholder="`请输入${item.value}原因`" />
</view>
</u-radio-group>
</view>
<!-- 多选 -->
<view class="type_checkbox" v-if="current.type == 'checkbox'">
<u-checkbox-group v-model="checkbox" placement="column" :size="26">
<u-checkbox v-for="item of current.options" :key="item.key" :name="item.value"
:label="item.value" checked-color="#2ec0d5" shape="square">
{{ item.value }}
</u-checkbox>
</u-checkbox-group>
</view>
<!-- 文本输入 -->
<view class="type_text" v-if="current.type == 'text'">
<view class="type_text_title">请输入就诊感受:</view>
<textarea type="textarea" :autosize="{ minRows: 4, maxRows: 8 }" placeholder="请输入您在本院的就诊感受"
v-model="textarea" />
</view>
<!-- 意见收集 -->
<view class="type_text" v-if="current.opinion == 1">
<view class="type_text_title">意见与建议:</view>
<textarea type="textarea" :autosize="{ minRows: 4, maxRows: 8 }" placeholder="请输入您的宝贵意见与建议"
v-model="opinions" />
</view>
</view>
<!-- 下一题按钮 -->
<view class="btn">
<u-button size="large" color="linear-gradient(to bottom, #89d4d5, #2ec0d5)" round block hairline
@click="next">
下一题
</u-button>
</view>
</view>
<!-- 答题完成后的图标 -->
<view class="finish" v-if="current == 'finish'">
<image class="img" :src="require('@/static/imgs/login/ico-success-card@3x.png')" mode=""></image>
<view class="finish_value">感谢您的反馈</view>
</view>
<!-- 再次确认的询问框 -->
<u-modal :show="show" @confirm="confirm" @cancel="cancel" :showCancelButton="true" :confirmText="confirmText"
:cancelText="cancelText">
<view class="slot-content">
<rich-text :nodes="content"></rich-text>
</view>
</u-modal>
<!-- 刚进页面的询问框 -->
<u-modal :show="show1" @confirm="confirm1" @cancel="cancel" :showCancelButton="true" :confirmText="confirmText1"
:cancelText="cancelText1">
<view class="slot-content">
<rich-text :nodes="content1"></rich-text>
</view>
</u-modal>
<loding :show="loading" text="题目加载中"></loding>
</view>
</template>
<script>
import {
createAnswer,
getAnswerStat,
setAnswerSubject,
getSubject,
} from '@/utils/server/server/index.js'
import {
showToast
} from '@/utils/tool.js'
import {
mapState
} from "vuex";
export default {
data() {
return {
code: "", // 问卷代码
title: "", // 问卷标题
subjectList: [],
isFinish: false,
current: null,
count: 0, // 问卷填写次数
answer_id: "", // 创建答卷后的ID
star: 0, // 评分
radio: "", // 单选
checkbox: [], // 多选
textarea: "", // 文本输入
opinions: "", // 意见收集
configCount: 1, // 设置的次数 infinite=不限制次数
// configCount: "infinite", // 设置的次数 infinite=不限制次数
isUnfinished: false, // 是否有未答完
needDialog: true, // 是否需要二级退出弹框
opinionValue: "", // 差评原因
show: false, // 开启模态框
content: '', // 模态框富文本内容
confirmText: '确认', // 模态框确认按钮文字
cancelText: '取消', // 模态框取消按钮文字
show1: false, // 开启模态框
content1: '', // 模态框富文本内容
confirmText1: '确认', // 模态框确认按钮文字
cancelText1: '取消', // 模态框取消按钮文字
loading: false, //是否显示遮罩层
unfinished_answer: [], //未完成的题目数据
business_no:'',
business_source:''
}
},
onLoad({
options
}) {
let query = JSON.parse(options)
console.log(query, 'query')
const {
template_code,
summary,
title
} = query;
if (!template_code) {
uni.showModal({
title: '提示',
content: '问卷code缺失\n请联系管理员',
showCancel: false,
success: function(res) {
if (res.confirm) {
console.log('用户点击确定');
uni.navigateBack({
delta: 1
})
}
}
});
return;
}
this.title = title;
this.code = template_code;
if(query.business_no) this.business_no = query.business_no
if(query.business_source) this.business_source = query.business_source
if(!this.userInfo.id){
this.$store.dispatch("getAllUser", {
isPush: false
}).then(async (res) => {
console.log(res,'获取就诊人')
});
}
},
onShow() {
this.show1 = true
this.content1 =
`<ol style="padding:0 10px;list-style: revert;"><li style="list-style-type:revert">${this.title}一周只能填写 <span style="color: #F90; font-weight: 700;">${this.configCount}</span> 次;</li><li style="list-style-type:revert">请您根据实际情况进行填写;</li><li style="list-style-type:revert">若有更好的建议可在带有意见输入的框中进行填写;</li></ol>`
this.confirmText1 = '获取问卷'
this.cancelText1 = '先不填'
},
filters: {
typeFormat(value) {
return (
new Map([
["score", "评分题"],
["radio", "单选题"],
["checkbox", "多选题"],
["text", "表述题"],
]).get(value) || "未知"
);
},
},
watch: {
subjectList: {
handler(n, o) {
this.current = this.subjectList.find((v) => !v.status) || null;
console.log("当前题目=>", this.current);
if (this.subjectList.length > 0 && !this.current) {
this.current = "finish";
}
if (this.current === "finish") {
showToast({
title: '感谢您的反馈'
})
setTimeout(() => this.$router.back(), 2000);
}
},
deep: true,
},
},
methods: {
async confirm1() {
this.show1 = false
// 判是否有未答完的试卷
// 加载题目
this.loading = true
await this.checkQuestionnaireCount(); // 查询问卷次数
this.loading = false
// 没有未答完的题
if (!this.isUnfinished) {
// 次数限制判断
if (await this.answerLimit(this.configCount)) return;
// 获取题目
await this.getTitle();
// 创建答卷
if (this.subjectList.length > 0) await this.createQuestionnaire();
// 没有题目
else await this.answerLimit(-1, `暂无${this.title}题目`);
}
},
/** 查询问卷填写次数 */
async checkQuestionnaireCount() {
console.log("进入了查询次数");
const params = {
patient_id: this.userInfo.id,
template_code: this.code,
// start_time: this.$moment().subtract(1, 'week').format('YYYY-MM-DD HH:mm:ss'),
start_time: this.$moment()
.subtract(5, "minute")
.format("YYYY-MM-DD HH:mm:ss"),
end_time: this.$moment().format("YYYY-MM-DD HH:mm:ss"), // 当前时间
};
console.log("问卷代码", params);
// 问卷代码
await getAnswerStat(params).then(async (res) => {
console.log(res, 'res')
const {
answer_count,
unfinished_answer
} = res;
this.unfinished_answer = unfinished_answer
console.log('unfinished_answer', unfinished_answer)
if (unfinished_answer.length > 0) {
this.isUnfinished = true;
console.warn(`有${unfinished_answer.length}份答卷未答完12`);
this.show = true
this.content =
`<span style="color:#A48D71">您有 <span style="color:#f90">${unfinished_answer.length}</span> 份【${this.title}】\n答卷未答完,请先答完问卷</span>`
this.confirmText = '继续答题'
this.cancelText = '不答了'
} else {
console.log(`填写过 ${answer_count} 次`);
this.count = answer_count; // 次数从0开始
}
}).catch((err) => console.log(err));
},
/** 作答限制
* @param {Number} num
* |- -1 代表直接限制并弹出提示
* |- 0-X数字 代表达到某个数值次数就限制作用域限制答题次数
* |- infinite 代表无限次数
* @param {String} msg 作用于出发限制后的信息提示
*/
async answerLimit(num = 1, msg = `您已填写过${this.title}`) {
let flag = false;
if (num == "infinite") {
return flag; // 无限制次数
}
if (this.count < 0 || this.count >= num) {
console.log('flag============================================>')
flag = true;
showToast({
title: msg
})
setTimeout(() => {
uni.navigateBack({
delta: 1
})
}, 1000)
return flag
}
},
confirm() {
this.show = false
const {
id,
subject
} = this.unfinished_answer[0];
this.answer_id = id;
this.subjectList = subject.map((v) => ({
...v,
status: false
})) || [];
},
/** 获取题目 */
async getTitle() {
await getSubject({
patient_id: this.userInfo.id,
template_code: this.code,
})
.then(({
subject
}) => {
console.log("题目=>", subject);
this.subjectList =
subject.map((v) => ({
...v,
status: false
})) || [];
console.log(this.subjectList, ' this.subjectList')
})
.catch((err) => console.log(err));
},
/** 创建答卷 */
async createQuestionnaire() {
console.log('createQuestionnaire')
await createAnswer({
patient_id: this.userInfo.id,
template_code: this.code,
business_no:this.business_no,
business_source:this.business_source
})
.then(({
answer_id
}) => {
console.log("创建答卷ID=>", answer_id);
this.answer_id = answer_id;
})
.catch((err) => console.log(err));
},
async next() {
const {
current,
answer_id,
star: score,
radio,
checkbox,
textarea,
opinions,
opinionValue,
} = this;
console.log("1212121", {
current,
answer_id,
star: score,
radio,
checkbox,
textarea,
opinions,
opinionValue,
});
if (!answer_id) {
showToast({
title: '问卷异常\n请重新答题'
})
setTimeout(() => {
// flag = true;
uni.switchTab({
url: '/pages/server/server'
})
}, 1000)
}
const {
id: subject_id,
type,
require
} = current;
const answer = new Map([
["radio", radio],
["checkbox", checkbox],
["text", textarea],
["score", score]
]);
const params = {
patient_id: this.userInfo.id,
answer_id,
subject_id
};
if ([...answer.keys()].includes(type)) params.answer = answer.get(type);
if (type == "score") params.score = parseFloat(score)
if (opinions) params.opinions = opinions;
if (opinionValue) params.opinions = opinionValue;
console.log("题目作答入参=>", params);
if (!!require && !params.answer) {
return showToast({
title: '该题为必答题请先作答'
})
}
this.loading = true
await setAnswerSubject(params).then((res) => {
// this.current.status = true;
// this.loading = false;
// this.clearAnswers();
if (res.status == 200) {
console.log("题目作答成功=>", res);
this.current.status = true;
this.loading = false;
this.clearAnswers();
} else {
console.log("题目作答失败=>", res);
this.loading = false;
this.clearAnswers();
showToast({
title: `提交失败\n${res.message}`
})
}
}).catch(err => {
console.log("题目作答失败=>", res);
this.loading = false;
showToast({
title: `提交失败\n${res.message}`
})
})
},
cancel() {
this.show = false
this.show1 = false
uni.switchTab({
url: '/pages/server/server'
})
},
/** 清空答题内容 */
clearAnswers() {
this.radio = "";
this.checkbox = [];
this.star = 0;
this.textarea = "";
this.opinions = "";
this.opinionValue = "";
},
},
computed: {
...mapState(["userInfo"]),
},
}
</script>
<style lang="scss" scoped>
/deep/ .u-radio {
width: 100%;
}
.container {
background-color: #f9f9f9;
padding: 20rpx;
height: 100vh;
.question {
margin: 0 40rpx;
position: relative;
&::after {
content: "";
display: block;
height: 140rpx;
}
.title {
display: flex;
align-items: center;
justify-content: center;
height: 120rpx;
&_num {
height: 70rpx;
width: 70rpx;
text-align: center;
background: linear-gradient(to bottom, #7fcecf, #54bcc3);
line-height: 70rpx;
border-radius: 70rpx;
color: #fff;
}
&_value {
display: flex;
align-items: center;
font-size: 40rpx;
color: #3c9cff;
font-weight: 700;
margin: 0 40rpx;
&_require {
color: red;
margin-left: 10rpx;
}
}
}
.value {
font-size: 36rpx;
&_name {
font-weight: 700;
color: #3c9cff;
}
&_title {
color: #3c9cff;
}
}
.tips {
margin: 20rpx 0;
color: #999;
text-align: center;
}
.type {
margin: 40rpx 0;
&_star {
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
margin: 40rpx 0;
&_score {
display: flex;
align-items: center;
font-weight: 700;
margin-top: 20rpx;
color: #4fb3ff;
&>text {
color: #ffd21e;
font-size: 36rpx;
}
}
}
&_radio,
&_checkbox {
display: flex;
// justify-content: center;
margin: 40rpx 0;
padding-left: 3em;
::v-deep .u-radio,
.u-checkbox {
margin: 20rpx 0;
}
&_box {
display: flex;
align-items: center;
margin: 10rpx 0;
font-size: 52rpx;
// justify-content: center;
flex-wrap: wrap;
::v-deep input {
flex: 1;
}
}
::v-deep .u-checkbox {
margin: 10rpx 0;
}
::v-deep .van-cell {
background: transparent;
}
}
&_text {
margin: 40rpx 0;
&_title {
font-weight: 700;
margin-bottom: 10rpx;
color: #3c9cff;
}
.textarea {
color: #050505;
width: 96%;
}
}
}
.btn {
position: fixed;
left: 0;
right: 0;
bottom: 0;
padding: 20rpx 40rpx;
}
}
.finish {
width: 100%;
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -80%);
display: flex;
flex-direction: column;
align-items: center;
.img {
width: 220rpx;
height: 220rpx;
}
&_value {
color: #de9c62;
font-size: 44rpx;
margin-top: 20rpx;
font-weight: 700;
}
}
}
</style>
需要展示全部调查,去除哪些代码?
最新发布