feat: 新增选项操作功能并优化问卷设计页面
- 新增 OptionAction 组件用于选项操作 - 更新 BaseSelect 组件,集成 OptionAction 功能 - 优化 Paging 组件样式 - 调整 Design 页面布局和样式
This commit is contained in:
3
components.d.ts
vendored
3
components.d.ts
vendored
@@ -14,12 +14,15 @@ declare module 'vue' {
|
||||
VanCellGroup: typeof import('vant/es')['CellGroup']
|
||||
VanCheckbox: typeof import('vant/es')['Checkbox']
|
||||
VanCheckboxGroup: typeof import('vant/es')['CheckboxGroup']
|
||||
VanDialog: typeof import('vant/es')['Dialog']
|
||||
VanDivider: typeof import('vant/es')['Divider']
|
||||
VanField: typeof import('vant/es')['Field']
|
||||
VanIcon: typeof import('vant/es')['Icon']
|
||||
VanPopup: typeof import('vant/es')['Popup']
|
||||
VanSearch: typeof import('vant/es')['Search']
|
||||
VanSwitch: typeof import('vant/es')['Switch']
|
||||
VanTabbar: typeof import('vant/es')['Tabbar']
|
||||
VanTabbarItem: typeof import('vant/es')['TabbarItem']
|
||||
YLSelect: typeof import('./src/components/YLSelect.vue')['default']
|
||||
}
|
||||
}
|
||||
|
||||
97
src/components/YLSelect.vue
Normal file
97
src/components/YLSelect.vue
Normal file
@@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<el-select v-model="selectedValue" class="yl-select-wrapper" @change="handleChange">
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
:disabled="item.disabled"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent, ref, watch } from 'vue';
|
||||
import 'element-plus/dist/index.css';
|
||||
import { ElSelect, ElOption } from 'element-plus';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'YLSelect',
|
||||
components: {
|
||||
ElSelect,
|
||||
ElOption
|
||||
},
|
||||
props: {
|
||||
modelValue: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
options: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '请选择'
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const selectedValue = ref(props.modelValue);
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(newVal) => {
|
||||
selectedValue.value = newVal;
|
||||
}
|
||||
);
|
||||
|
||||
const handleChange = (event) => {
|
||||
emit('update:modelValue', event);
|
||||
emit('change', event);
|
||||
};
|
||||
|
||||
return {
|
||||
selectedValue,
|
||||
handleChange
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.yl-select-wrapper {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
font-size: 16px; /* 增加字体大小 */
|
||||
line-height: 1.5; /* 增加行高 */
|
||||
}
|
||||
|
||||
.yl-select {
|
||||
height: 44px; /* 增加高度以适应触摸 */
|
||||
padding: 10px; /* 增加内边距 */
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
background-color: #fff;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
appearance: none;
|
||||
|
||||
&:disabled {
|
||||
background-color: #f5f5f5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '\25BC'; /* 添加下拉箭头 */
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 10px;
|
||||
color: #999;
|
||||
pointer-events: none;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -181,6 +181,50 @@ export const useCommonStore = defineStore('common', {
|
||||
cell_indexs: []
|
||||
},
|
||||
hide_option_index: []
|
||||
},
|
||||
{
|
||||
id: 472152,
|
||||
question_index: 24,
|
||||
sample_number: 0,
|
||||
skip_question_index: 0,
|
||||
skip_type: 1,
|
||||
question_id: '17852294',
|
||||
logic: [
|
||||
{
|
||||
value: '',
|
||||
location: 0,
|
||||
date: '',
|
||||
time: '',
|
||||
type: 0,
|
||||
row_type: 0,
|
||||
cell_type: 0,
|
||||
logic: 'if',
|
||||
operator: '=',
|
||||
is_answer: 1,
|
||||
is_select: 0,
|
||||
row_index: 0,
|
||||
cell_index: 0,
|
||||
question_type: 1,
|
||||
question_index: 0,
|
||||
relation_question_index: 0,
|
||||
relation_question_row_index: 0,
|
||||
relation_question_cell_index: 0,
|
||||
is_option_group: 0,
|
||||
option_index: 0,
|
||||
skip_type: null,
|
||||
question_id: null
|
||||
}
|
||||
],
|
||||
autofill: {
|
||||
value: '',
|
||||
date: '',
|
||||
time: '',
|
||||
question_type: 1,
|
||||
option_indexs: [],
|
||||
row_indexs: [],
|
||||
cell_indexs: []
|
||||
},
|
||||
hide_option_index: []
|
||||
}
|
||||
],
|
||||
questions: [
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="design-create">
|
||||
<draggable
|
||||
v-model:data="questionInfo.questions"
|
||||
item-key="id"
|
||||
@@ -115,4 +115,10 @@ onMounted(() => {
|
||||
questionInfo.value = store.questionsInfo.value;
|
||||
});
|
||||
</script>
|
||||
<style scoped lang="scss"></style>
|
||||
<style scoped lang="scss">
|
||||
.design-create {
|
||||
min-height: calc(100vh);
|
||||
background-color: #e9eef3;
|
||||
color: #333;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -33,12 +33,12 @@
|
||||
</template>
|
||||
</van-cell>
|
||||
<van-divider></van-divider>
|
||||
<van-cell title="题前隐藏" :border="false">
|
||||
<van-cell title="题前隐藏" :border="false" @click="questionSetting('before')">
|
||||
<template #right-icon>
|
||||
<span> {{ getSkipTypeText(0) }} <van-icon name="arrow"></van-icon></span>
|
||||
</template>
|
||||
</van-cell>
|
||||
<van-cell title="题后跳转" :border="false">
|
||||
<van-cell title="题后跳转" :border="false" @click="questionSetting('after')">
|
||||
<template #right-icon>
|
||||
<span> {{ getSkipTypeText(1) }} <van-icon name="arrow"></van-icon></span>
|
||||
</template>
|
||||
@@ -50,6 +50,30 @@
|
||||
</van-action-sheet>
|
||||
|
||||
<!-- 题目操作 题前 题后-->
|
||||
|
||||
<van-popup
|
||||
v-model:show="questionBeforeShow"
|
||||
title="题前隐藏逻辑"
|
||||
position="bottom"
|
||||
round
|
||||
:style="{ minHeight: '60%' }"
|
||||
>
|
||||
<template v-for="(item, index) in logics" :key="index">
|
||||
<div
|
||||
v-if="item.skip_type === skipType && item.question_index === activeQuestion.question_index"
|
||||
class="mv10 question-setting"
|
||||
>
|
||||
<template v-for="(log, logIndex) in item.logic" :key="logIndex">
|
||||
<yl-select
|
||||
v-model="log.logic"
|
||||
:options="settingIfOption"
|
||||
class="question-setting-if"
|
||||
></yl-select>
|
||||
<yl-select v-model="log.logic" :options="settingIfOption"></yl-select>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</van-popup>
|
||||
</template>
|
||||
<script setup>
|
||||
import { showConfirmDialog } from 'vant';
|
||||
@@ -57,10 +81,17 @@ import { ref } from 'vue';
|
||||
import { useCounterStore } from '@/stores/counter';
|
||||
import { storeToRefs } from 'pinia';
|
||||
|
||||
import YlSelect from '@/components/YLSelect.vue';
|
||||
|
||||
const store = useCounterStore();
|
||||
const { questionsInfo } = storeToRefs(store);
|
||||
const logics = questionsInfo.value.logics;
|
||||
|
||||
const settingIfOption = [
|
||||
{ label: 'if', value: 'if' },
|
||||
{ label: 'always', value: 'always' }
|
||||
];
|
||||
|
||||
const props = defineProps({
|
||||
index: {
|
||||
type: Number,
|
||||
@@ -87,6 +118,7 @@ const questions = ref(props.questions);
|
||||
const activeQuestion = ref(props.data);
|
||||
|
||||
const show = ref(false);
|
||||
const questionBeforeShow = ref(false);
|
||||
const deleteQuestion = () => {
|
||||
showConfirmDialog({
|
||||
title: '提示',
|
||||
@@ -124,6 +156,7 @@ const questionMove = (action) => {
|
||||
}
|
||||
};
|
||||
|
||||
const skipType = ref(-1);
|
||||
// 获取题前隐藏 和题后 跳转 文字
|
||||
const getSkipTypeText = (skipType) => {
|
||||
const ls = [];
|
||||
@@ -141,12 +174,41 @@ const getSkipTypeText = (skipType) => {
|
||||
}
|
||||
return text;
|
||||
};
|
||||
|
||||
// 题前 题后逻辑配置
|
||||
|
||||
const questionSetting = (type) => {
|
||||
switch (type) {
|
||||
case 'before':
|
||||
questionBeforeShow.value = true;
|
||||
|
||||
break;
|
||||
case 'after':
|
||||
questionBeforeShow.value = true;
|
||||
break;
|
||||
}
|
||||
skipType.value = type === 'before' ? 0 : 1;
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.ml10 {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.mv10 {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.y-select {
|
||||
min-width: 10vw;
|
||||
|
||||
//max-width: 90vw;
|
||||
}
|
||||
|
||||
.question-setting-if {
|
||||
width: 140px;
|
||||
}
|
||||
|
||||
.question-action-container {
|
||||
font-size: 20px;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user