feat(Design): 新增填空题组件并优化问卷发布功能- 新增 CompletionQuestionAction 组件用于填空题配置
-重命名 RateAction 为 RateQuestionAction,优化打分题配置- 更新 QuestionAction 组件,支持多选、打分和填空题型 - 改进问卷发布页面,增加复制链接和下载二维码功能 - 优化代码结构,提高可维护性和可读性
This commit is contained in:
1
components.d.ts
vendored
1
components.d.ts
vendored
@@ -10,6 +10,7 @@ declare module 'vue' {
|
|||||||
Contenteditable: typeof import('./src/components/contenteditable.vue')['default']
|
Contenteditable: typeof import('./src/components/contenteditable.vue')['default']
|
||||||
RouterLink: typeof import('vue-router')['RouterLink']
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
RouterView: typeof import('vue-router')['RouterView']
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
|
'Van-': typeof import('vant/es')['-']
|
||||||
VanActionSheet: typeof import('vant/es')['ActionSheet']
|
VanActionSheet: typeof import('vant/es')['ActionSheet']
|
||||||
VanButton: typeof import('vant/es')['Button']
|
VanButton: typeof import('vant/es')['Button']
|
||||||
VanCell: typeof import('vant/es')['Cell']
|
VanCell: typeof import('vant/es')['Cell']
|
||||||
|
|||||||
@@ -242,8 +242,7 @@ watch(
|
|||||||
() => questionInfo.value.questions[chooseQuestionIndex.value],
|
() => questionInfo.value.questions[chooseQuestionIndex.value],
|
||||||
(newVal) => {
|
(newVal) => {
|
||||||
if (newVal) {
|
if (newVal) {
|
||||||
console.log(newVal, 232313);
|
// saveQueItem(questionInfo.value.logics, [newVal]);
|
||||||
saveQueItem(questionInfo.value.logics, [newVal]);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
@@ -380,6 +379,7 @@ const updateElement = (newElement) => {
|
|||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
questionInfo.value.questions.splice(index, 1, newElement);
|
questionInfo.value.questions.splice(index, 1, newElement);
|
||||||
}
|
}
|
||||||
|
saveQueItem(questionInfo.value.logics, [newElement]);
|
||||||
};
|
};
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
questionInfo.value = store.questionsInfo.value;
|
questionInfo.value = store.questionsInfo.value;
|
||||||
|
|||||||
@@ -52,16 +52,25 @@
|
|||||||
</van-cell>
|
</van-cell>
|
||||||
<van-divider></van-divider>
|
<van-divider></van-divider>
|
||||||
<!-- 根据不同题型 展示不同的操作-->
|
<!-- 根据不同题型 展示不同的操作-->
|
||||||
|
<!-- 多选-->
|
||||||
<checkbox-question-action
|
<checkbox-question-action
|
||||||
v-if="activeQuestion.question_type === 2"
|
v-if="activeQuestion.question_type === 2"
|
||||||
v-model="activeQuestion"
|
v-model="activeQuestion"
|
||||||
@save-option="saveSettings"
|
@save-option="saveSettings"
|
||||||
></checkbox-question-action>
|
></checkbox-question-action>
|
||||||
<rate-action
|
<!-- 打分-->
|
||||||
|
<rate-question-action
|
||||||
v-if="activeQuestion.question_type === 5"
|
v-if="activeQuestion.question_type === 5"
|
||||||
:config="activeQuestion.config"
|
:config="activeQuestion.config"
|
||||||
@update-config="updateConfig"
|
@update-config="updateConfig"
|
||||||
></rate-action>
|
></rate-question-action>
|
||||||
|
|
||||||
|
<!-- 填空-->
|
||||||
|
<completion-question-action
|
||||||
|
v-if="activeQuestion.question_type === 4"
|
||||||
|
v-model="activeQuestion"
|
||||||
|
@save-option="saveSettings"
|
||||||
|
></completion-question-action>
|
||||||
</van-cell-group>
|
</van-cell-group>
|
||||||
</van-action-sheet>
|
</van-action-sheet>
|
||||||
<!-- 移动 复制-->
|
<!-- 移动 复制-->
|
||||||
@@ -109,7 +118,8 @@ import { ref } from 'vue';
|
|||||||
import { useCounterStore } from '@/stores/counter';
|
import { useCounterStore } from '@/stores/counter';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import QuestionBefore from '@/views/Design/components/ActionCompoents/components/QuestionItemAction/QuestionBefore.vue';
|
import QuestionBefore from '@/views/Design/components/ActionCompoents/components/QuestionItemAction/QuestionBefore.vue';
|
||||||
import RateAction from './components/OptionItemAction/RateAction.vue';
|
import RateQuestionAction from './components/QuestionItemAction/RateQuestionAction.vue';
|
||||||
|
import CompletionQuestionAction from '@/views/Design/components/ActionCompoents/components/QuestionItemAction/CompletionQuestionAction.vue';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
const store = useCounterStore();
|
const store = useCounterStore();
|
||||||
const { questionsInfo } = storeToRefs(store);
|
const { questionsInfo } = storeToRefs(store);
|
||||||
|
|||||||
@@ -0,0 +1,260 @@
|
|||||||
|
<template>
|
||||||
|
<van-field
|
||||||
|
label="内容限制"
|
||||||
|
:border="false"
|
||||||
|
label-align="left"
|
||||||
|
input-align="right"
|
||||||
|
is-link
|
||||||
|
readonly
|
||||||
|
:value="selectText(actionQuestion.config.text_type)"
|
||||||
|
@click="selectTextTypeModel = true"
|
||||||
|
>
|
||||||
|
<template #input>
|
||||||
|
<span>{{ selectText(actionQuestion.config.text_type) }}</span>
|
||||||
|
</template>
|
||||||
|
</van-field>
|
||||||
|
<van-cell-group>
|
||||||
|
<van-field
|
||||||
|
v-if="[2].includes(actionQuestion.config.text_type)"
|
||||||
|
v-model="actionQuestion.config.decimal_few"
|
||||||
|
label="保留小数位"
|
||||||
|
type="number"
|
||||||
|
:border="false"
|
||||||
|
label-align="left"
|
||||||
|
input-align="right"
|
||||||
|
class="action-field"
|
||||||
|
placeholder="不限"
|
||||||
|
max="4"
|
||||||
|
min="0"
|
||||||
|
@blur="emit('saveOption')"
|
||||||
|
@update:model-value="
|
||||||
|
(value) => {
|
||||||
|
actionQuestion.config.line_height = Number(value);
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<template #right-icon>
|
||||||
|
<span>位</span>
|
||||||
|
</template>
|
||||||
|
</van-field>
|
||||||
|
<van-field
|
||||||
|
v-if="[3, 4].includes(actionQuestion.config.text_type)"
|
||||||
|
v-model="actionQuestion.config.decimal_few"
|
||||||
|
label="允许输入标点符号"
|
||||||
|
type="number"
|
||||||
|
:border="false"
|
||||||
|
label-align="left"
|
||||||
|
input-align="right"
|
||||||
|
class="action-field"
|
||||||
|
label-width="8em"
|
||||||
|
placeholder="不限"
|
||||||
|
readonly
|
||||||
|
@blur="emit('saveOption')"
|
||||||
|
@update:model-value="
|
||||||
|
(value) => {
|
||||||
|
actionQuestion.config.line_height = Number(value);
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<template #input></template>
|
||||||
|
<template #right-icon>
|
||||||
|
<van-switch
|
||||||
|
v-model="actionQuestion.config.include_mark"
|
||||||
|
:active-value="1"
|
||||||
|
:inactive-value="0"
|
||||||
|
size="0.5rem"
|
||||||
|
></van-switch>
|
||||||
|
</template>
|
||||||
|
</van-field>
|
||||||
|
</van-cell-group>
|
||||||
|
<van-divider></van-divider>
|
||||||
|
|
||||||
|
<van-cell
|
||||||
|
v-if="![5, 6, 7].includes(actionQuestion.config.text_type)"
|
||||||
|
title="字数限制"
|
||||||
|
:border="false"
|
||||||
|
label-align="left"
|
||||||
|
>
|
||||||
|
</van-cell>
|
||||||
|
<van-cell-group>
|
||||||
|
<van-field
|
||||||
|
v-if="![5, 6, 7].includes(actionQuestion.config.text_type)"
|
||||||
|
v-model="actionQuestion.config.min"
|
||||||
|
label="最少"
|
||||||
|
type="number"
|
||||||
|
:border="false"
|
||||||
|
label-align="left"
|
||||||
|
input-align="right"
|
||||||
|
class="action-field"
|
||||||
|
placeholder="不限"
|
||||||
|
@blur="emit('saveOption')"
|
||||||
|
@update:model-value="
|
||||||
|
(value) => {
|
||||||
|
actionQuestion.config.min = Number(value);
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<template #right-icon>
|
||||||
|
<span>个</span>
|
||||||
|
</template>
|
||||||
|
</van-field>
|
||||||
|
<van-field
|
||||||
|
v-if="![5, 6, 7].includes(actionQuestion.config.text_type)"
|
||||||
|
v-model="actionQuestion.config.max"
|
||||||
|
label="最多"
|
||||||
|
type="number"
|
||||||
|
:border="false"
|
||||||
|
placeholder="不限"
|
||||||
|
input-align="right"
|
||||||
|
class="action-field"
|
||||||
|
@blur="emit('saveOption')"
|
||||||
|
@update:model-value="
|
||||||
|
(value) => {
|
||||||
|
actionQuestion.config.max = Number(value);
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<template #right-icon>
|
||||||
|
<span>个</span>
|
||||||
|
</template>
|
||||||
|
</van-field>
|
||||||
|
</van-cell-group>
|
||||||
|
<van-cell
|
||||||
|
v-if="[0].includes(actionQuestion.config.text_type)"
|
||||||
|
title="文本类型"
|
||||||
|
:border="false"
|
||||||
|
label-align="left"
|
||||||
|
>
|
||||||
|
<template #right-icon>
|
||||||
|
<van-radio-group
|
||||||
|
v-model="actionQuestion.config.line_type"
|
||||||
|
icon-size="0.4rem"
|
||||||
|
direction="horizontal"
|
||||||
|
>
|
||||||
|
<van-radio :name="0">单行</van-radio>
|
||||||
|
<van-radio :name="1">多行</van-radio>
|
||||||
|
</van-radio-group>
|
||||||
|
</template>
|
||||||
|
</van-cell>
|
||||||
|
<van-cell-group>
|
||||||
|
<van-field
|
||||||
|
v-if="[0].includes(actionQuestion.config.text_type)"
|
||||||
|
v-model="actionQuestion.config.line_height"
|
||||||
|
label="文本高度"
|
||||||
|
type="number"
|
||||||
|
:border="false"
|
||||||
|
label-align="left"
|
||||||
|
input-align="right"
|
||||||
|
class="action-field"
|
||||||
|
placeholder="不限"
|
||||||
|
@blur="emit('saveOption')"
|
||||||
|
@update:model-value="
|
||||||
|
(value) => {
|
||||||
|
actionQuestion.config.line_height = Number(value);
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<template #right-icon>
|
||||||
|
<span>行</span>
|
||||||
|
</template>
|
||||||
|
</van-field>
|
||||||
|
<van-field
|
||||||
|
v-model="actionQuestion.config.placeholder"
|
||||||
|
label="输入框提示"
|
||||||
|
:border="false"
|
||||||
|
label-align="left"
|
||||||
|
input-align="right"
|
||||||
|
class="action-field"
|
||||||
|
placeholder="不限"
|
||||||
|
@blur="emit('saveOption')"
|
||||||
|
@update:model-value="
|
||||||
|
(value) => {
|
||||||
|
actionQuestion.config.line_height = Number(value);
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
|
</van-field>
|
||||||
|
</van-cell-group>
|
||||||
|
|
||||||
|
<van-popup v-model:show="selectTextTypeModel" position="bottom" round>
|
||||||
|
<van-picker
|
||||||
|
:columns="textTypeList"
|
||||||
|
@confirm="confirm"
|
||||||
|
@cancel="selectTextTypeModel = false"
|
||||||
|
></van-picker>
|
||||||
|
</van-popup>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { computed, defineEmits, ref } from 'vue';
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const selectTextTypeModel = ref(false);
|
||||||
|
const textTypeList = [
|
||||||
|
{
|
||||||
|
text: '不限',
|
||||||
|
value: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '整数',
|
||||||
|
value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '小数',
|
||||||
|
value: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '字母',
|
||||||
|
value: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '中文',
|
||||||
|
value: 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'email',
|
||||||
|
value: 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '手机号',
|
||||||
|
value: 6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '身份证号',
|
||||||
|
value: 7
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:modelValue', 'saveOption']);
|
||||||
|
//
|
||||||
|
const selectText = (textType) => {
|
||||||
|
return textTypeList.filter((item) => item.value === textType)[0].text;
|
||||||
|
};
|
||||||
|
const confirm = ({ selectedValues }) => {
|
||||||
|
actionQuestion.value.config.text_type = Number(selectedValues[0]);
|
||||||
|
selectTextTypeModel.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
const actionQuestion = computed({
|
||||||
|
get() {
|
||||||
|
return props.modelValue;
|
||||||
|
},
|
||||||
|
set(newValue) {
|
||||||
|
emit('update:modelValue', newValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.action-field {
|
||||||
|
& ::v-deep .van-field__label {
|
||||||
|
color: #bfbfbf;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user