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

360 lines
9.0 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<script setup>
/**
* name
* usersa0ChunLuyu
* date2023年6月8日 20:08:53
*/
import {
ref
} from 'vue'
import {
UploadImageAction,
QuestionSaveAction,
QuestionListAction,
$image,
$response
} from '@/api'
import {
onShow
} from '@dcloudio/uni-app'
const $props = defineProps({
hospital: {
type: String,
default: '0'
}
});
const question_list = ref([])
const QuestionList = async () => {
const response = await QuestionListAction({
...$props,
type: 1
})
$response(response, () => {
question_list.value = response.data.list.map((item) => {
item.content = JSON.parse(item.content)
item.more = (item.type === 1 || item.type === 4) ? '' : item.content.item.map((i) => {
return ''
})
item.answer = (item.type === 1 || item.type === 4) ? '' : [];
return item
})
})
}
const user_info = ref(false)
const getUserInfo = () => {
uni.$lu.user((info) => {
if (!!info.id) {
user_info.value = info
QuestionList()
}
})
}
const questionMark = (info, key) => {
switch (info.mark) {
case 'NAME':
question_list.value[key].answer = (!!user_info.value.person && !!user_info.value.person.id) ?
user_info.value.person.name :
''
break;
case 'SEX':
question_list.value[key].answer = [(!!user_info.value.person && user_info.value.person.sex === 1) ? '男' : '女']
break;
}
}
const chooseContent = (content, index = 0) => {
return content.split('{{MORE}}')[index]
}
const chooseItemClick = (question, key, answer, kk) => {
let index = question.answer.indexOf(chooseContent(answer))
if (index !== -1) {
question.answer.splice(index, 1)
} else {
switch (question.type) {
case 2:
question.answer = [chooseContent(answer)]
break;
case 3:
question.answer.push(chooseContent(answer))
break;
}
}
}
const chooseImage = (key) => {
uni.chooseImage({
count: 1,
success: (res) => {
const tempFilePath = res.tempFilePaths[0]
uni.getFileInfo({
filePath: tempFilePath,
success: (result) => {
if (key === 'photo') {
const fileSize = result.size;
const maxSize = 1024 * 1024 * 2;
if (fileSize > maxSize) {
uni.showToast({
title: '选择的文件过大,请重新选择',
icon: 'none'
});
} else {
imageToBase64(tempFilePath, key);
}
} else {
imageToBase64(tempFilePath, key);
}
}
})
}
})
}
const imageToBase64 = (url, key) => {
uni.getImageInfo({
src: url,
success(res) {
let canvasWidth = res.width;
let canvasHeight = res.height;
let img = new Image();
img.src = res.path;
let canvas = document.createElement('canvas');
let ctx = canvas.getContext('2d');
if (canvasWidth >= 1000) {
canvas.width = canvasWidth * .1;
} else {
canvas.width = canvasWidth;
}
if (canvasHeight >= 1000) {
canvas.height = canvasHeight * .1;
} else {
canvas.height = canvasHeight;
}
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
canvas.toBlob((file) => {
const fileReader = new FileReader()
fileReader.readAsDataURL(file)
fileReader.onload = (event) => {
if (fileReader.result) {
UploadImage(fileReader.result, key)
}
}
}, 'image/jpeg');
}
});
}
const UploadImage = async (base64, key) => {
const response = await UploadImageAction({
base64
})
$response(response, () => {
question_list.value[key].answer = response.data.url
})
}
const saveClick = (e) => {
let content = []
for (let i in question_list.value) {
if ((question_list.value[i].type === 1 || question_list.value[i].type === 4)) {
if (!question_list.value[i].answer) {
uni.$lu.toast(`请填写第${Number(i)+1}`)
uni.$lu.anchor(e, `anchor-${i}`)
return
}
}
if ((question_list.value[i].type === 2 || question_list.value[i].type === 3)) {
if (!question_list.value[i].answer.length) {
uni.$lu.toast(`请选择第${Number(i)+1}`)
uni.$lu.anchor(e, `anchor-${i}`)
return
} else {
for (let ii in question_list.value[i].content.item) {
let index = question_list.value[i].content.item[ii].indexOf('{{MORE}}')
if (index !== -1) {
let iii = question_list.value[i].answer.indexOf(chooseContent(question_list.value[i].content.item[ii]))
if (iii !== -1) {
if (!question_list.value[i].more[ii]) {
uni.$lu.toast(`请填写第${Number(i)+1}题,第${Number(ii)+1}`)
uni.$lu.anchor(e, `anchor-${i}-${ii}`)
return
}
}
}
}
}
}
content.push({
question: question_list.value[i].question,
answer: question_list.value[i].answer,
more: question_list.value[i].more,
})
}
QuestionSave(content)
}
const done_active = ref(false)
const QuestionSave = async (content) => {
const response = await QuestionSaveAction({
content: JSON.stringify(content),
type: 1
})
$response(response, () => {
done_active.value = true
})
}
onShow(() => {
getUserInfo()
})
</script>
<template>
<view>
<view>
<view class="question_title_wrapper">满意度调查问卷</view>
<view v-if="done_active">
<view class="question_tip_wrapper question_done_wrapper">问卷已提交,谢谢!</view>
</view>
<view v-else>
<view class="question_tip_wrapper">尊敬的客户: 为了促进我们持续的优化和改进体检质量,现在占用您的一些宝贵时间对我们的工作情况进行调查。感谢您的认真对待,谢谢!</view>
<view :id="`anchor-${k}`" class="question_item_wrapper" v-for="(i,k) in question_list" :key="k">
<view class="question_item_title_wrapper">{{ i.question }}</view>
<view :ref="questionMark(i,k)" class="question_item_item_wrapper">
<view v-if="Number(i.type) === 1">
<input :placeholder="i.content.placeholder" type="text" v-model="question_list[k].answer"
class="question_item_item_input_wrapper">
</view>
<view v-if="Number(i.type) === 2 || Number(i.type) === 3">
<view v-for="(ii,kk) in i.content.item">
<view @click="chooseItemClick(i,k,ii,kk)" class="question_item_item_choose_wrapper" :key="kk">
<view class="question_item_item_choose_checkbox_wrapper">
<uni-icons v-if="i.answer.indexOf(chooseContent(ii)) !== -1" color="#24ba2d" type="checkmarkempty"
size="40rpx"></uni-icons>
</view>
<view class="question_item_item_choose_text_wrapper">{{ chooseContent(ii) }}</view>
</view>
<view v-if="ii.indexOf('{{MORE}}') !== -1 && i.answer.indexOf(chooseContent(ii)) !== -1">
<view :id="`anchor-${k}-${kk}`" class="question_item_title_wrapper">{{ chooseContent(ii,1) }}</view>
<input type="text" v-model="question_list[k].more[kk]" class="question_item_item_input_wrapper">
</view>
</view>
</view>
<view v-if="Number(i.type) === 4">
<view @click="chooseImage(k)" class="image_wrapper">
<image :src="$image(question_list[k].answer)" v-if="!!question_list[k].answer"></image>
{{ i.content.placeholder }}
</view>
</view>
</view>
</view>
<view @click="saveClick" class="save_wrapper">提交</view>
</view>
<view class="blank_break_wrapper"></view>
</view>
<view class="blank_wrapper"></view>
</view>
</template>
<style>
page {
background: #ffffff;
}
</style>
<style scoped>
.question_item_item_choose_text_wrapper {
width: 550rpx;
}
.question_done_wrapper {
text-align: center;
}
.blank_break_wrapper {
height: 200rpx;
}
.save_wrapper {
width: 600rpx;
height: 80rpx;
background: linear-gradient(-90deg, #23D3AF, #0DC5CF);
font-size: 30rpx;
line-height: 80rpx;
text-align: center;
color: #ffffff;
border-radius: 999rpx;
margin: 150rpx auto 0;
}
.image_wrapper image {
position: absolute;
width: 300rpx;
height: 200rpx;
display: block;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 999;
}
.image_wrapper {
position: relative;
width: 300rpx;
height: 200rpx;
background: #f7f7f7;
border: 1rpx #33333340 solid;
margin: 20rpx auto 0;
font-size: 28rpx;
line-height: 200rpx;
text-align: center;
}
.question_item_item_choose_wrapper {
display: flex;
align-items: center;
width: 600rpx;
margin: 20rpx auto 0;
}
.question_item_item_choose_checkbox_wrapper {
width: 30rpx;
height: 30rpx;
background: #f7f7f7;
border: 1rpx #33333340 solid;
line-height: 30rpx;
margin-right: 20rpx;
text-align: center;
}
.question_item_item_input_wrapper {
border: 1rpx #cccccc solid;
height: 60rpx;
border-radius: 10rpx;
width: 580rpx;
padding-left: 20rpx;
margin: 30rpx auto 0;
}
.question_item_title_wrapper {
font-size: 30rpx;
margin-top: 50rpx;
width: 600rpx;
margin: 30rpx auto 0;
font-weight: bold;
}
.question_tip_wrapper {
font-size: 26rpx;
margin-top: 50rpx;
width: 600rpx;
margin: 30rpx auto 0;
}
.question_title_wrapper {
font-size: 40rpx;
font-weight: bold;
text-align: center;
margin-top: 50rpx;
}
</style>