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']
|
||||
ElOption: typeof import('element-plus/es')['ElOption']
|
||||
ElSelect: typeof import('element-plus/es')['ElSelect']
|
||||
ElText: typeof import('element-plus/es')['ElText']
|
||||
RichText: typeof import('./src/components/RichText.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
@@ -35,6 +34,8 @@ declare module 'vue' {
|
||||
VanRow: typeof import('vant/es')['Row']
|
||||
VanStepper: typeof import('vant/es')['Stepper']
|
||||
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']
|
||||
YLInput: typeof import('./src/components/YLInput.vue')['default']
|
||||
YLPicker: typeof import('./src/components/YLPicker.vue')['default']
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
<script setup>
|
||||
import checkboxQuestionAction from './components/QuestionItemAction/CheckboxQuestionAction.vue';
|
||||
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 RateQuestionAction from './components/QuestionItemAction/RateQuestionAction.vue';
|
||||
import CompletionQuestionAction from '@/views/Design/components/ActionCompoents/components/QuestionItemAction/CompletionQuestionAction.vue';
|
||||
@@ -171,15 +171,15 @@ const props = defineProps({
|
||||
questions: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
questionIndex: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
});
|
||||
const { questionsInfo } = toRefs(props);
|
||||
const logics = questionsInfo.value.logics;
|
||||
const questions = ref(props.questions);
|
||||
const questionIndex = defineModel('questionIndex', {
|
||||
type: Number,
|
||||
default: 0
|
||||
});
|
||||
// emit
|
||||
const emit = defineEmits(['move', 'copy', 'delete', 'setting', 'logics']);
|
||||
|
||||
@@ -197,11 +197,11 @@ const activeQuestion = ref(props.data);
|
||||
const show = ref(false);
|
||||
const questionShow = ref(false);
|
||||
const questionBeforeShow = ref(false);
|
||||
const actions = [
|
||||
const actions = ref([
|
||||
{ name: '上移题目', action: 'up' },
|
||||
{ name: '下移题目', action: 'down' },
|
||||
{ name: '复制题目', action: 'copy' }
|
||||
];
|
||||
]);
|
||||
const deleteQuestion = () => {
|
||||
showConfirmDialog({
|
||||
title: '提示',
|
||||
@@ -209,14 +209,48 @@ const deleteQuestion = () => {
|
||||
})
|
||||
.then(() => {
|
||||
// on confirm
|
||||
const index = props.questionIndex;
|
||||
questions.value.splice(props.questionIndex, 1);
|
||||
const index = questionIndex.value;
|
||||
questions.value.splice(questionIndex.value, 1);
|
||||
emit('delete', index);
|
||||
})
|
||||
.catch(() => {
|
||||
// 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 = () => {
|
||||
@@ -229,30 +263,38 @@ const openQuestionSettingModel = () => {
|
||||
// 题目上下移动
|
||||
const questionMove = (action) => {
|
||||
if (action.action === 'down') {
|
||||
if (props.questionIndex === questions.value.length - 1) {
|
||||
if (questionIndex.value === questions.value.length - 1) {
|
||||
return;
|
||||
}
|
||||
const temp = questions.value[props.questionIndex];
|
||||
questions.value.splice(props.questionIndex, 1);
|
||||
questions.value.splice(props.questionIndex + 1, 0, temp);
|
||||
const temp = questions.value[questionIndex.value];
|
||||
questions.value.splice(questionIndex.value, 1);
|
||||
questions.value.splice(questionIndex.value + 1, 0, temp);
|
||||
emit('move', 'down');
|
||||
|
||||
questionIndex.value += 1;
|
||||
} 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;
|
||||
}
|
||||
const temp = questions.value[props.questionIndex];
|
||||
questions.value.splice(props.questionIndex, 1);
|
||||
questions.value.splice(props.questionIndex - 1, 0, temp);
|
||||
const temp = questions.value[questionIndex.value];
|
||||
questions.value.splice(questionIndex.value, 1);
|
||||
questions.value.splice(questionIndex.value - 1, 0, temp);
|
||||
emit('move', 'up');
|
||||
} else {
|
||||
// 复制 题目 生成新的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 = {
|
||||
...temp,
|
||||
id: uuidv4(),
|
||||
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;
|
||||
emit('copy', newQuestion);
|
||||
questionShow.value = false;
|
||||
@@ -265,8 +307,8 @@ const getSkipTypeText = (skipType) => {
|
||||
const ls = [];
|
||||
logics.map((item) => {
|
||||
if (
|
||||
item.skip_type === skipType
|
||||
&& item.question_index === activeQuestion.value.question_index
|
||||
item.skip_type === skipType &&
|
||||
item.question_index === activeQuestion.value.question_index
|
||||
) {
|
||||
ls.push(item);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import LastSurvey from './components/LastSurvey/Index.vue';
|
||||
import Market from './components/Market/Index.vue';
|
||||
import CreateSurvey from './components/CreateSurvey/Index.vue';
|
||||
import CreateQuestion from './components/CreateSurvey/CreateQuestion.vue';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import utils from '@/assets/js/common';
|
||||
import { getUserInfo } from '@/api/common/index.js';
|
||||
@@ -10,7 +11,7 @@ import appBridge from '@/assets/js/appBridge';
|
||||
const contentShow = ref(false);
|
||||
const show = ref(false);
|
||||
|
||||
onMounted(async() => {
|
||||
onMounted(async () => {
|
||||
if (appBridge.isInReactNative()) {
|
||||
const appToken = utils.getSessionStorage('xToken');
|
||||
getUserInfo(appToken)
|
||||
@@ -60,7 +61,8 @@ function create() {
|
||||
</div>
|
||||
</div>
|
||||
<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>
|
||||
</template>
|
||||
|
||||
@@ -96,7 +98,7 @@ function create() {
|
||||
|
||||
//background: linear-gradient(0deg, #f5f5f5 0%, #f5f5f5 84%, #a5d380 100%);
|
||||
|
||||
&> :first-child {
|
||||
& > :first-child {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
|
||||
@@ -107,7 +109,7 @@ function create() {
|
||||
//justify-content: space-around;
|
||||
border-radius: 16px;
|
||||
|
||||
&>div {
|
||||
& > div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
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;
|
||||
background-image: url('@/assets/img/home/home-back.png');
|
||||
background-position: center; /* 确保图片居中显示 */
|
||||
background-size: contain; /* 或者使用具体的尺寸,如 100% 100% */
|
||||
background-size: cover; /* 或者使用具体的尺寸,如 100% 100% */
|
||||
background-repeat: no-repeat;
|
||||
|
||||
//padding: 15px;
|
||||
|
||||
Reference in New Issue
Block a user