395 lines
10 KiB
Vue
395 lines
10 KiB
Vue
<template>
|
|
<div class="question">
|
|
<!-- 高级题型不显示 -->
|
|
<div class="question-inner-wrapper" v-if="questionType <= 100">
|
|
<div class="title" :style="`color: ${themeColor.stemColor}`">
|
|
<span v-if="showTitle" class="question-inner-span" v-html="title"></span>
|
|
<div class="stem">
|
|
<rich-text :nodes="`${newTitle}${tip}`" isPreview />
|
|
</div>
|
|
</div>
|
|
<Remark
|
|
:title="title + '问题评论'"
|
|
:type="3"
|
|
:questionIndex="questionIndex"
|
|
v-if="!isAnswer"
|
|
style="margin-bottom: 22px;"
|
|
/>
|
|
</div>
|
|
<div v-if="error && questionType <= 100" class="error">{{ error }}</div>
|
|
<!-- 题 -->
|
|
<slot />
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import RichText from "@/components/RichText.vue";
|
|
import { computed, defineComponent, inject } from "vue";
|
|
import Remark from "../components/Remark/index.vue";
|
|
|
|
export default defineComponent({
|
|
components: { RichText, Remark },
|
|
props: {
|
|
// 标题
|
|
stem: {
|
|
type: String,
|
|
default: "",
|
|
},
|
|
title: {
|
|
type: String,
|
|
default: "",
|
|
},
|
|
// 标题
|
|
tip: {
|
|
type: String,
|
|
default: "",
|
|
},
|
|
// 错误
|
|
error: {
|
|
type: String,
|
|
default: "",
|
|
},
|
|
// 题型
|
|
questionType: {
|
|
type: Number,
|
|
default: 0,
|
|
},
|
|
// 题号
|
|
questionIndex: {
|
|
type: Number,
|
|
default: 0,
|
|
},
|
|
// 问卷列表
|
|
questions: {
|
|
type: Array,
|
|
default: () => [],
|
|
},
|
|
// 是否显示题号
|
|
showTitle: {
|
|
type: [Boolean, Number],
|
|
default: false,
|
|
},
|
|
// 是否移动端
|
|
isMobile: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
// 是否答题模式
|
|
isAnswer: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
},
|
|
setup(props) {
|
|
const themeColor = inject("themeColor"); // 主题颜色
|
|
const buttonColor = themeColor.value?.buttonColor; // 按钮颜色
|
|
const buttonTextColor = themeColor.value?.buttonTextColor; // 按钮文字颜色
|
|
const answerColor = themeColor.value?.answerColor || "#333333"; // 答案颜色
|
|
const answerColor30 = toRgba(answerColor, 0.3); // 背景颜色(透明度30s)
|
|
const answerColor10 = toRgba(answerColor, 0.1); // 背景颜色(透明度10)
|
|
const answerBorder = answerColor === "#333333" ? "#d9d9d9" : answerColor; // 边框颜色
|
|
const answerPlaceholder = toRgba(answerColor, 0.3); // placeholder颜色
|
|
|
|
// 16进制转rgba
|
|
function toRgba(color, opacity) {
|
|
return (
|
|
"rgba(" +
|
|
parseInt(color.substring(1, 3), 16) +
|
|
"," +
|
|
parseInt(color.substring(3, 5), 16) +
|
|
"," +
|
|
parseInt(color.substring(5, 7), 16) +
|
|
"," +
|
|
opacity +
|
|
")"
|
|
);
|
|
}
|
|
|
|
const newTitle = computed(() => {
|
|
let title = props.stem;
|
|
const matchArr = title.match(/(\[%cite\(.*?\)%\])/g) || [];
|
|
matchArr.forEach((matchValue) => {
|
|
const value = matchValue.replace("[%cite(", "").replace(")%]", "");
|
|
let replacement = ""; // 替换文本
|
|
// 查找引用问题
|
|
const question = props.questions.find((question) => {
|
|
// 矩阵题
|
|
if (question.question_type >= 8 && question.question_type <= 11) {
|
|
return question.title === value.split("_R")[0].split("_C")[0];
|
|
}
|
|
// 排序题
|
|
if (question.question_type === 16) {
|
|
return question.title === value.split("_A")[0];
|
|
}
|
|
return question.title === value;
|
|
});
|
|
if (question) {
|
|
let options = []; // 选项
|
|
question.list.forEach((list) => {
|
|
options = [...options, ...list.options];
|
|
});
|
|
if (question.answer) {
|
|
const { answer } = question;
|
|
if (question.question_type === 1) {
|
|
// 查找引用选项(单选)
|
|
const option = options.find((option) => option.option_key === Object.keys(answer)[0]);
|
|
if (answer[option.option_key] === "1") {
|
|
replacement = option.option;
|
|
} else {
|
|
replacement = answer[option.option_key];
|
|
}
|
|
} else if (
|
|
question.question_type === 2 &&
|
|
Object.keys(answer).length >= question.config.min_select
|
|
) {
|
|
// 查找引用选项(多选)
|
|
options.forEach((option) => {
|
|
if (answer[option.option_key] === "1") {
|
|
replacement += option.option;
|
|
} else if (answer[option.option_key]) {
|
|
replacement += answer[option.option_key];
|
|
}
|
|
});
|
|
} else if (question.question_type === 4) {
|
|
// 查找引用选项(填空)
|
|
replacement = answer.value;
|
|
} else if (question.question_type === 5 && options.length > 1) {
|
|
// 查找引用选项(打分)
|
|
options.forEach((option) => {
|
|
replacement += option.option;
|
|
});
|
|
} else if (question.question_type === 17) {
|
|
// 查找引用选项(恒定总和)
|
|
options.forEach((option) => {
|
|
replacement += option.option;
|
|
});
|
|
} else if (question.question_type >= 8 && question.question_type <= 11) {
|
|
// 查找引用选项(矩阵题)
|
|
// const val = value.split("_").reverse()[0];
|
|
// let row = [];
|
|
// let col = [];
|
|
// question.list.forEach((list) => {
|
|
// if (list.type === 1) {
|
|
// row = [...row, ...list.options];
|
|
// } else if (list.type === 2) {
|
|
// col = [...col, ...list.options];
|
|
// }
|
|
// });
|
|
// if (val[0] === "R") {
|
|
// col.forEach((colItem) => {
|
|
// replacement += colItem.option;
|
|
// });
|
|
// } else if (val[0] === "C") {
|
|
// row.forEach((rowItem) => {
|
|
// replacement += rowItem.option;
|
|
// });
|
|
// }
|
|
} else if (question.question_type === 16) {
|
|
// 查找引用选项(排序)
|
|
let optionKey;
|
|
const sort = value.split("_A")[1] * 1;
|
|
Object.keys(answer).forEach((key) => {
|
|
if (answer[key] === sort) {
|
|
optionKey = key;
|
|
}
|
|
});
|
|
const option = options.find((option) => option.option_key === optionKey);
|
|
replacement += option?.option || "";
|
|
}
|
|
}
|
|
}
|
|
title = title
|
|
.replace(`${matchValue}`, replacement)
|
|
.replaceAll("<p ", "<span ")
|
|
.replaceAll("<p>", "<span>")
|
|
.replaceAll("</p>", "</span>");
|
|
});
|
|
return title;
|
|
});
|
|
|
|
return {
|
|
newTitle,
|
|
buttonColor,
|
|
buttonTextColor,
|
|
themeColor,
|
|
answerColor,
|
|
answerColor30,
|
|
answerColor10,
|
|
answerBorder,
|
|
answerPlaceholder,
|
|
};
|
|
},
|
|
});
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.question {
|
|
.question-inner-wrapper {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.title {
|
|
flex: 1;
|
|
min-height: 24px;
|
|
margin-bottom: 24px;
|
|
display: flex;
|
|
|
|
> span {
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.stem {
|
|
flex: 1;
|
|
}
|
|
}
|
|
|
|
.error {
|
|
font-size: 12px;
|
|
color: #ff374f;
|
|
line-height: 20px;
|
|
margin: -22px 0 10px;
|
|
}
|
|
|
|
:deep(p) {
|
|
margin-bottom: 0;
|
|
}
|
|
}
|
|
// .question-inner-span {
|
|
// width: 100%;
|
|
// }
|
|
</style>
|
|
|
|
<style lang="scss" scoped>
|
|
:deep(.ant-radio-inner) {
|
|
border-color: v-bind(answerColor) !important;
|
|
background-color: transparent;
|
|
}
|
|
|
|
:deep(.ant-radio-inner::after) {
|
|
background-color: v-bind(answerColor);
|
|
}
|
|
|
|
:deep(.ant-checkbox-inner) {
|
|
border-color: v-bind(answerColor) !important;
|
|
background-color: transparent;
|
|
}
|
|
|
|
:deep(.ant-checkbox-checked .ant-checkbox-inner) {
|
|
background-color: v-bind(answerColor);
|
|
}
|
|
|
|
:deep(.ant-input) {
|
|
color: v-bind(answerColor);
|
|
border-color: v-bind(answerBorder) !important;
|
|
background-color: transparent;
|
|
}
|
|
|
|
:deep(.ant-input-number) {
|
|
color: v-bind(answerColor);
|
|
border-color: v-bind(answerBorder) !important;
|
|
background-color: transparent;
|
|
}
|
|
|
|
:deep(.ant-select-selector) {
|
|
color: v-bind(answerColor);
|
|
border-color: v-bind(answerBorder) !important;
|
|
background-color: transparent !important;
|
|
}
|
|
|
|
:deep(.ant-input:hover) {
|
|
border-color: v-bind(answerColor);
|
|
}
|
|
|
|
:deep(.ant-input::placeholder) {
|
|
color: v-bind(answerPlaceholder) !important;
|
|
}
|
|
|
|
:deep(.ant-select-selection-placeholder) {
|
|
color: v-bind(answerPlaceholder) !important;
|
|
}
|
|
|
|
// :deep(.ant-rate) {
|
|
// color: v-bind(answerColor) !important;
|
|
// }
|
|
|
|
// :deep(.ant-rate-star-zero .ant-rate-star-second) {
|
|
// color: v-bind(answerColor30);
|
|
// }
|
|
|
|
:deep(.num-item) {
|
|
color: v-bind(answerColor) !important;
|
|
border-color: v-bind(answerColor) !important;
|
|
}
|
|
|
|
:deep(.num-item-active) {
|
|
color: #fff !important;
|
|
border-color: v-bind(answerColor) !important;
|
|
background-color: v-bind(answerColor) !important;
|
|
}
|
|
|
|
// :deep(.num-item:hover) {
|
|
// color: #fff !important;
|
|
// border-color: v-bind(answerColor) !important;
|
|
// background-color: v-bind(answerColor) !important;
|
|
// }
|
|
|
|
:deep(.rich-rate-item-active) {
|
|
border-color: v-bind(answerColor) !important;
|
|
background-color: v-bind(answerColor) !important;
|
|
}
|
|
|
|
// :deep(.rich-rate-item:hover) {
|
|
// border-color: v-bind(answerColor) !important;
|
|
// background-color: v-bind(answerColor) !important;
|
|
// }
|
|
|
|
:deep(.step-inner) {
|
|
border-color: v-bind(answerColor) !important;
|
|
}
|
|
|
|
:deep(.ant-slider-track) {
|
|
background-color: v-bind(answerColor) !important;
|
|
}
|
|
|
|
:deep(.ant-slider-handle) {
|
|
border-color: v-bind(answerColor) !important;
|
|
}
|
|
|
|
:deep(.ant-slider-dot-active) {
|
|
border-color: v-bind(answerColor) !important;
|
|
}
|
|
|
|
:deep(.ant-slider-mark-text) {
|
|
color: v-bind(answerColor);
|
|
}
|
|
|
|
:deep(.ant-upload) {
|
|
border-color: v-bind(answerBorder) !important;
|
|
background-color: v-bind(answerColor10) !important;
|
|
}
|
|
|
|
:deep(.pfe-button) {
|
|
color: v-bind(buttonTextColor) !important;
|
|
background-color: v-bind(buttonColor) !important;
|
|
}
|
|
|
|
// 公共样式
|
|
:deep(.answer-color) {
|
|
color: v-bind(answerColor) !important;
|
|
}
|
|
|
|
:deep(.answer-border) {
|
|
border-color: v-bind(answerBorder) !important;
|
|
}
|
|
|
|
:deep(.answer-background30) {
|
|
background-color: v-bind(answerColor30) !important;
|
|
}
|
|
|
|
:deep(.answer-background10) {
|
|
background-color: v-bind(answerColor10) !important;
|
|
}
|
|
</style>
|