feat(Design): 新增填空题组件并优化问卷发布功能- 新增 CompletionQuestionAction 组件用于填空题配置

-重命名 RateAction 为 RateQuestionAction,优化打分题配置- 更新 QuestionAction 组件,支持多选、打分和填空题型
- 改进问卷发布页面,增加复制链接和下载二维码功能
- 优化代码结构,提高可维护性和可读性
This commit is contained in:
陈昱达
2025-03-12 18:10:11 +08:00
parent 5182307840
commit 0b5d08e3b9
5 changed files with 276 additions and 5 deletions

1
components.d.ts vendored
View File

@@ -10,6 +10,7 @@ declare module 'vue' {
Contenteditable: typeof import('./src/components/contenteditable.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
'Van-': typeof import('vant/es')['-']
VanActionSheet: typeof import('vant/es')['ActionSheet']
VanButton: typeof import('vant/es')['Button']
VanCell: typeof import('vant/es')['Cell']

View File

@@ -242,8 +242,7 @@ watch(
() => questionInfo.value.questions[chooseQuestionIndex.value],
(newVal) => {
if (newVal) {
console.log(newVal, 232313);
saveQueItem(questionInfo.value.logics, [newVal]);
// saveQueItem(questionInfo.value.logics, [newVal]);
}
},
{ deep: true }
@@ -380,6 +379,7 @@ const updateElement = (newElement) => {
if (index !== -1) {
questionInfo.value.questions.splice(index, 1, newElement);
}
saveQueItem(questionInfo.value.logics, [newElement]);
};
onMounted(() => {
questionInfo.value = store.questionsInfo.value;

View File

@@ -52,16 +52,25 @@
</van-cell>
<van-divider></van-divider>
<!-- 根据不同题型 展示不同的操作-->
<!-- 多选-->
<checkbox-question-action
v-if="activeQuestion.question_type === 2"
v-model="activeQuestion"
@save-option="saveSettings"
></checkbox-question-action>
<rate-action
<!-- 打分-->
<rate-question-action
v-if="activeQuestion.question_type === 5"
:config="activeQuestion.config"
@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-action-sheet>
<!-- 移动 复制-->
@@ -109,7 +118,8 @@ import { ref } from 'vue';
import { useCounterStore } from '@/stores/counter';
import { storeToRefs } from 'pinia';
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';
const store = useCounterStore();
const { questionsInfo } = storeToRefs(store);

View File

@@ -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>