feat(home): 新增创建问卷功能并优化首页样式
- 新增 CreateQuestion 组件,用于创建新问卷 - 在首页添加创建问卷入口 - 优化首页样式,调整背景图显示方式 - 在 QuestionAction 组件中添加题目移动逻辑
This commit is contained in:
3
components.d.ts
vendored
3
components.d.ts
vendored
@@ -11,7 +11,6 @@ declare module 'vue' {
|
|||||||
ElInput: typeof import('element-plus/es')['ElInput']
|
ElInput: typeof import('element-plus/es')['ElInput']
|
||||||
ElOption: typeof import('element-plus/es')['ElOption']
|
ElOption: typeof import('element-plus/es')['ElOption']
|
||||||
ElSelect: typeof import('element-plus/es')['ElSelect']
|
ElSelect: typeof import('element-plus/es')['ElSelect']
|
||||||
ElText: typeof import('element-plus/es')['ElText']
|
|
||||||
RichText: typeof import('./src/components/RichText.vue')['default']
|
RichText: typeof import('./src/components/RichText.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']
|
||||||
@@ -35,6 +34,8 @@ declare module 'vue' {
|
|||||||
VanRow: typeof import('vant/es')['Row']
|
VanRow: typeof import('vant/es')['Row']
|
||||||
VanStepper: typeof import('vant/es')['Stepper']
|
VanStepper: typeof import('vant/es')['Stepper']
|
||||||
VanSwitch: typeof import('vant/es')['Switch']
|
VanSwitch: typeof import('vant/es')['Switch']
|
||||||
|
VanTab: typeof import('vant/es')['Tab']
|
||||||
|
VanTabs: typeof import('vant/es')['Tabs']
|
||||||
YLCascader: typeof import('./src/components/YLCascader.vue')['default']
|
YLCascader: typeof import('./src/components/YLCascader.vue')['default']
|
||||||
YLInput: typeof import('./src/components/YLInput.vue')['default']
|
YLInput: typeof import('./src/components/YLInput.vue')['default']
|
||||||
YLPicker: typeof import('./src/components/YLPicker.vue')['default']
|
YLPicker: typeof import('./src/components/YLPicker.vue')['default']
|
||||||
|
|||||||
@@ -144,7 +144,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import checkboxQuestionAction from './components/QuestionItemAction/CheckboxQuestionAction.vue';
|
import checkboxQuestionAction from './components/QuestionItemAction/CheckboxQuestionAction.vue';
|
||||||
import { showConfirmDialog } from 'vant';
|
import { showConfirmDialog } from 'vant';
|
||||||
import { toRefs, ref } from 'vue';
|
import { toRefs, ref, watch } from 'vue';
|
||||||
import QuestionBefore from '@/views/Design/components/ActionCompoents/components/QuestionItemAction/QuestionBefore.vue';
|
import QuestionBefore from '@/views/Design/components/ActionCompoents/components/QuestionItemAction/QuestionBefore.vue';
|
||||||
import RateQuestionAction from './components/QuestionItemAction/RateQuestionAction.vue';
|
import RateQuestionAction from './components/QuestionItemAction/RateQuestionAction.vue';
|
||||||
import CompletionQuestionAction from '@/views/Design/components/ActionCompoents/components/QuestionItemAction/CompletionQuestionAction.vue';
|
import CompletionQuestionAction from '@/views/Design/components/ActionCompoents/components/QuestionItemAction/CompletionQuestionAction.vue';
|
||||||
@@ -171,15 +171,15 @@ const props = defineProps({
|
|||||||
questions: {
|
questions: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default: () => []
|
default: () => []
|
||||||
},
|
|
||||||
questionIndex: {
|
|
||||||
type: Number,
|
|
||||||
default: 0
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const { questionsInfo } = toRefs(props);
|
const { questionsInfo } = toRefs(props);
|
||||||
const logics = questionsInfo.value.logics;
|
const logics = questionsInfo.value.logics;
|
||||||
const questions = ref(props.questions);
|
const questions = ref(props.questions);
|
||||||
|
const questionIndex = defineModel('questionIndex', {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
});
|
||||||
// emit
|
// emit
|
||||||
const emit = defineEmits(['move', 'copy', 'delete', 'setting', 'logics']);
|
const emit = defineEmits(['move', 'copy', 'delete', 'setting', 'logics']);
|
||||||
|
|
||||||
@@ -197,11 +197,11 @@ const activeQuestion = ref(props.data);
|
|||||||
const show = ref(false);
|
const show = ref(false);
|
||||||
const questionShow = ref(false);
|
const questionShow = ref(false);
|
||||||
const questionBeforeShow = ref(false);
|
const questionBeforeShow = ref(false);
|
||||||
const actions = [
|
const actions = ref([
|
||||||
{ name: '上移题目', action: 'up' },
|
{ name: '上移题目', action: 'up' },
|
||||||
{ name: '下移题目', action: 'down' },
|
{ name: '下移题目', action: 'down' },
|
||||||
{ name: '复制题目', action: 'copy' }
|
{ name: '复制题目', action: 'copy' }
|
||||||
];
|
]);
|
||||||
const deleteQuestion = () => {
|
const deleteQuestion = () => {
|
||||||
showConfirmDialog({
|
showConfirmDialog({
|
||||||
title: '提示',
|
title: '提示',
|
||||||
@@ -209,14 +209,48 @@ const deleteQuestion = () => {
|
|||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// on confirm
|
// on confirm
|
||||||
const index = props.questionIndex;
|
const index = questionIndex.value;
|
||||||
questions.value.splice(props.questionIndex, 1);
|
questions.value.splice(questionIndex.value, 1);
|
||||||
emit('delete', index);
|
emit('delete', index);
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
// on cancel
|
// on cancel
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* @name 监听当前题目是否可以移动
|
||||||
|
* @created_date 2025/3/19
|
||||||
|
* @description
|
||||||
|
**/
|
||||||
|
watch(
|
||||||
|
() => questionIndex.value,
|
||||||
|
(newVal) => {
|
||||||
|
if (newVal === questions.value.length - 1) {
|
||||||
|
actions.value = [
|
||||||
|
{ name: '上移题目', action: 'up' },
|
||||||
|
{ name: '下移题目', action: 'down', disabled: true },
|
||||||
|
{ name: '复制题目', action: 'copy' }
|
||||||
|
];
|
||||||
|
}
|
||||||
|
if (newVal === 0) {
|
||||||
|
actions.value = [
|
||||||
|
{ name: '上移题目', action: 'up', disabled: true },
|
||||||
|
{ name: '下移题目', action: 'down' },
|
||||||
|
{ name: '复制题目', action: 'copy' }
|
||||||
|
];
|
||||||
|
}
|
||||||
|
if (newVal > 0 && newVal < questions.value.length - 1) {
|
||||||
|
actions.value = [
|
||||||
|
{ name: '上移题目', action: 'up' },
|
||||||
|
{ name: '下移题目', action: 'down' },
|
||||||
|
{ name: '复制题目', action: 'copy' }
|
||||||
|
];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// 打开题目弹窗
|
// 打开题目弹窗
|
||||||
const openQuestionActionModel = () => {
|
const openQuestionActionModel = () => {
|
||||||
@@ -229,30 +263,38 @@ const openQuestionSettingModel = () => {
|
|||||||
// 题目上下移动
|
// 题目上下移动
|
||||||
const questionMove = (action) => {
|
const questionMove = (action) => {
|
||||||
if (action.action === 'down') {
|
if (action.action === 'down') {
|
||||||
if (props.questionIndex === questions.value.length - 1) {
|
if (questionIndex.value === questions.value.length - 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const temp = questions.value[props.questionIndex];
|
const temp = questions.value[questionIndex.value];
|
||||||
questions.value.splice(props.questionIndex, 1);
|
questions.value.splice(questionIndex.value, 1);
|
||||||
questions.value.splice(props.questionIndex + 1, 0, temp);
|
questions.value.splice(questionIndex.value + 1, 0, temp);
|
||||||
emit('move', 'down');
|
emit('move', 'down');
|
||||||
|
|
||||||
|
questionIndex.value += 1;
|
||||||
} else if (action.action === 'up') {
|
} else if (action.action === 'up') {
|
||||||
if (props.questionIndex === 0) {
|
if (questionIndex.value === 0) {
|
||||||
|
actions.value = [
|
||||||
|
{ name: '上移题目', action: 'up', disabled: true },
|
||||||
|
{ name: '下移题目', action: 'down' },
|
||||||
|
{ name: '复制题目', action: 'copy' }
|
||||||
|
];
|
||||||
|
questionShow.value = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const temp = questions.value[props.questionIndex];
|
const temp = questions.value[questionIndex.value];
|
||||||
questions.value.splice(props.questionIndex, 1);
|
questions.value.splice(questionIndex.value, 1);
|
||||||
questions.value.splice(props.questionIndex - 1, 0, temp);
|
questions.value.splice(questionIndex.value - 1, 0, temp);
|
||||||
emit('move', 'up');
|
emit('move', 'up');
|
||||||
} else {
|
} else {
|
||||||
// 复制 题目 生成新的id 更新最新的 last index
|
// 复制 题目 生成新的id 更新最新的 last index
|
||||||
const temp = JSON.parse(JSON.stringify(questions.value[props.questionIndex]));
|
const temp = JSON.parse(JSON.stringify(questions.value[questionIndex.value]));
|
||||||
const newQuestion = {
|
const newQuestion = {
|
||||||
...temp,
|
...temp,
|
||||||
id: uuidv4(),
|
id: uuidv4(),
|
||||||
question_index: questionsInfo.value.survey.last_question_index + 1
|
question_index: questionsInfo.value.survey.last_question_index + 1
|
||||||
};
|
};
|
||||||
questions.value.splice(props.questionIndex + 1, 0, newQuestion);
|
questions.value.splice(questionIndex.value + 1, 0, newQuestion);
|
||||||
questionsInfo.value.survey.last_question_index += 1;
|
questionsInfo.value.survey.last_question_index += 1;
|
||||||
emit('copy', newQuestion);
|
emit('copy', newQuestion);
|
||||||
questionShow.value = false;
|
questionShow.value = false;
|
||||||
@@ -265,8 +307,8 @@ const getSkipTypeText = (skipType) => {
|
|||||||
const ls = [];
|
const ls = [];
|
||||||
logics.map((item) => {
|
logics.map((item) => {
|
||||||
if (
|
if (
|
||||||
item.skip_type === skipType
|
item.skip_type === skipType &&
|
||||||
&& item.question_index === activeQuestion.value.question_index
|
item.question_index === activeQuestion.value.question_index
|
||||||
) {
|
) {
|
||||||
ls.push(item);
|
ls.push(item);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import LastSurvey from './components/LastSurvey/Index.vue';
|
import LastSurvey from './components/LastSurvey/Index.vue';
|
||||||
import Market from './components/Market/Index.vue';
|
import Market from './components/Market/Index.vue';
|
||||||
import CreateSurvey from './components/CreateSurvey/Index.vue';
|
import CreateSurvey from './components/CreateSurvey/Index.vue';
|
||||||
|
import CreateQuestion from './components/CreateSurvey/CreateQuestion.vue';
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
import utils from '@/assets/js/common';
|
import utils from '@/assets/js/common';
|
||||||
import { getUserInfo } from '@/api/common/index.js';
|
import { getUserInfo } from '@/api/common/index.js';
|
||||||
@@ -10,7 +11,7 @@ import appBridge from '@/assets/js/appBridge';
|
|||||||
const contentShow = ref(false);
|
const contentShow = ref(false);
|
||||||
const show = ref(false);
|
const show = ref(false);
|
||||||
|
|
||||||
onMounted(async() => {
|
onMounted(async () => {
|
||||||
if (appBridge.isInReactNative()) {
|
if (appBridge.isInReactNative()) {
|
||||||
const appToken = utils.getSessionStorage('xToken');
|
const appToken = utils.getSessionStorage('xToken');
|
||||||
getUserInfo(appToken)
|
getUserInfo(appToken)
|
||||||
@@ -60,7 +61,8 @@ function create() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<van-popup v-model:show="show" round closeable position="bottom">
|
<van-popup v-model:show="show" round closeable position="bottom">
|
||||||
<CreateSurvey :createdNewPage="true"></CreateSurvey>
|
<!-- <CreateSurvey :createdNewPage="true"></CreateSurvey>-->
|
||||||
|
<create-question :createdNewPage="true"></create-question>
|
||||||
</van-popup>
|
</van-popup>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -96,7 +98,7 @@ function create() {
|
|||||||
|
|
||||||
//background: linear-gradient(0deg, #f5f5f5 0%, #f5f5f5 84%, #a5d380 100%);
|
//background: linear-gradient(0deg, #f5f5f5 0%, #f5f5f5 84%, #a5d380 100%);
|
||||||
|
|
||||||
&> :first-child {
|
& > :first-child {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
|
|
||||||
@@ -107,7 +109,7 @@ function create() {
|
|||||||
//justify-content: space-around;
|
//justify-content: space-around;
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
|
|
||||||
&>div {
|
& > div {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 50px;
|
width: 50px;
|
||||||
|
|||||||
191
src/views/Home/components/CreateSurvey/CreateQuestion.vue
Normal file
191
src/views/Home/components/CreateSurvey/CreateQuestion.vue
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
<script setup>
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { consoleSurveys, getQuestionList, useTemplate } from '@/api/home/index.js';
|
||||||
|
import { snQuestions, saveQuestions } from '@/api/design/index.js';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import { useCounterStore } from '@/stores/counter';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
// 获取 Store 实例
|
||||||
|
const counterStore = useCounterStore();
|
||||||
|
const store = storeToRefs(counterStore);
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
const surveys = ref([]);
|
||||||
|
|
||||||
|
const createdNewPage = defineModel('createdNewPage', {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
});
|
||||||
|
const createdQuestion = (item) => {
|
||||||
|
const query = {
|
||||||
|
group_id: 0,
|
||||||
|
source: 1,
|
||||||
|
project_name: `${item.title}问卷 `,
|
||||||
|
remarks: '为优化活动服务品质,烦请完成问卷,感谢配合',
|
||||||
|
scene_code: item.parentCode,
|
||||||
|
scene_code_info: item.code,
|
||||||
|
// 很迷茫 模板新增 tag 空数组 非模板 就是k
|
||||||
|
tags: ''
|
||||||
|
};
|
||||||
|
if (createdNewPage.value) {
|
||||||
|
query.scene_code = item.parentCode;
|
||||||
|
query.tags = '';
|
||||||
|
} else {
|
||||||
|
if (item.sn) {
|
||||||
|
query.scene_code = null;
|
||||||
|
query.tags = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果放在了底部 当作新增组件
|
||||||
|
if (createdNewPage.value) {
|
||||||
|
consoleSurveys(query).then((res) => {
|
||||||
|
if (res.data) {
|
||||||
|
createdApx(res);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (item.sn) {
|
||||||
|
useTemplate(item.sn, query).then((temp) => {
|
||||||
|
if (temp.data) {
|
||||||
|
createdApx(temp);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
consoleSurveys(query).then((res) => {
|
||||||
|
if (res.data) {
|
||||||
|
createdApx(res);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const createdApx = (res) => {
|
||||||
|
snQuestions({ sn: res.data.data.sn }).then((ques) => {
|
||||||
|
if (ques.data) {
|
||||||
|
ques.data.data.survey.introduction = `<p>为优化活动服务品质,烦请完成问卷,感谢配合!您的反馈至关重要!(此提示语为默认提示语,您可选择自行输入本问卷的提示语)</p>`;
|
||||||
|
store.questionsInfo.value = ques.data.data;
|
||||||
|
saveQuestions({
|
||||||
|
sn: res.data.data.sn,
|
||||||
|
introduction: ques.data.data.survey.introduction,
|
||||||
|
title: ques.data.data.survey.title
|
||||||
|
}).then(() => {
|
||||||
|
router.push({
|
||||||
|
path: '/create',
|
||||||
|
query: {
|
||||||
|
sn: res.data.data.sn
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 添加获取问卷列表的方法
|
||||||
|
const getList = () => {
|
||||||
|
getQuestionList().then((res) => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
if (res.data.data) {
|
||||||
|
res.data.data.forEach((item) => {
|
||||||
|
// if (item.parentCode && item.parentCode === 1) {
|
||||||
|
surveys.value.push(item);
|
||||||
|
// }
|
||||||
|
});
|
||||||
|
|
||||||
|
// surveys.value.push({});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 在组件挂载时调用
|
||||||
|
onMounted(() => {
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<!-- <div class="home-pen">-->
|
||||||
|
<!-- <img :src="homePen" alt="" />-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<div class="create_survey">
|
||||||
|
<div class="create_survey_title" style="color: #000; text-align: left">新建问卷</div>
|
||||||
|
<div class="flex align-center space-between warp">
|
||||||
|
<div
|
||||||
|
v-for="survey in surveys"
|
||||||
|
:key="survey.title"
|
||||||
|
span="6"
|
||||||
|
class="survey"
|
||||||
|
@click="createdQuestion(survey)"
|
||||||
|
>
|
||||||
|
<img :src="survey.h5Image" alt="" width="40" />
|
||||||
|
<span>{{ survey.h5Title }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.home-pen {
|
||||||
|
//height: 200px;
|
||||||
|
position: absolute;
|
||||||
|
top: -10px;
|
||||||
|
left: 0;
|
||||||
|
z-index: 8;
|
||||||
|
|
||||||
|
//width: 100%;
|
||||||
|
background: #fff;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
//height: 200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.create_survey {
|
||||||
|
overflow: hidden;
|
||||||
|
//border-radius: 16px;
|
||||||
|
background: #fff;
|
||||||
|
|
||||||
|
//padding: 15px;
|
||||||
|
|
||||||
|
color: #000;
|
||||||
|
|
||||||
|
.create_survey_title {
|
||||||
|
margin: 16px;
|
||||||
|
color: #000;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 15px;
|
||||||
|
font-family: PingFangSC, 'PingFang SC';
|
||||||
|
}
|
||||||
|
|
||||||
|
& .warp {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.survey {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
//margin-right: 30px;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
//flex: 1;
|
||||||
|
width: 25%;
|
||||||
|
|
||||||
|
//margin: 0 16px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
//justify-content: space-around;
|
||||||
|
|
||||||
|
span {
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 18px;
|
||||||
|
color: #000;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 0.34rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -148,7 +148,7 @@ onMounted(() => {
|
|||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
background-image: url('@/assets/img/home/home-back.png');
|
background-image: url('@/assets/img/home/home-back.png');
|
||||||
background-position: center; /* 确保图片居中显示 */
|
background-position: center; /* 确保图片居中显示 */
|
||||||
background-size: contain; /* 或者使用具体的尺寸,如 100% 100% */
|
background-size: cover; /* 或者使用具体的尺寸,如 100% 100% */
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
|
|
||||||
//padding: 15px;
|
//padding: 15px;
|
||||||
|
|||||||
Reference in New Issue
Block a user