feat: 完成预览界面
- 调整 preview 组件 - 增加问卷提交成功的 success 组件 - 为 design 组件设置预览时取消调整选题设置 - 建立 axios 工具库 - 配置相关的代理内容 - 增加 lodash-es 和 axios 库 - design 页面添加获取远程题目
This commit is contained in:
@@ -14,8 +14,10 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
"axios": "^1.8.2",
|
||||
"element-plus": "^2.7.8",
|
||||
"lodash": "^4.17.21",
|
||||
"lodash-es": "^4.17.21",
|
||||
"pinia": "^2.1.7",
|
||||
"sortablejs": "^1.15.6",
|
||||
"uuid": "^11.1.0",
|
||||
|
||||
11
src/config.ts
Normal file
11
src/config.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
export default {
|
||||
proxyUrl: process.env.VUE_APP_BASEURL,
|
||||
proxyUrlDelivery: process.env.VUE_APP_DELiVERY_BASEURL,
|
||||
proxyUrlMessageCenter: process.env.VUE_APP_MESSAGE_CENTER,
|
||||
baseOss: process.env.VUE_APP_BASEOSS,
|
||||
loginUrl: process.env.VUE_APP_LOGIN,
|
||||
socketUrl: process.env.VUE_APP_SOCKETURL,
|
||||
jsonpUrl: process.env.VUE_APP_JSONPURL,
|
||||
jqrUrl: process.env.VUE_APP_YQRURL,
|
||||
currentMode: process.env.VUE_APP_CURRENTMODE
|
||||
};
|
||||
1
src/request/api/modules/survey.ts
Normal file
1
src/request/api/modules/survey.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const surveyQuestion = '/api/api/console/surveys/RWNK9BYp/questions';
|
||||
81
src/request/axios/index.ts
Normal file
81
src/request/axios/index.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
import axios from 'axios';
|
||||
// import router from '@/router/index';
|
||||
// import { A_COMMON_CLEAR_TOKEN } from '@/stores/constance/constance.common.js';
|
||||
|
||||
// const baseURL = process.env.NODE_ENV === 'production' ? proxyUrl : '/api';
|
||||
|
||||
// axios.defaults.withCredentials = true;
|
||||
|
||||
// create an axios instance
|
||||
const service = axios.create({
|
||||
// baseURL: `${baseURL}`, // url = base url + request url
|
||||
// withCredentials: true, // send cookies when cross-domain requests
|
||||
timeout: 30000 // request timeout
|
||||
});
|
||||
|
||||
// request interceptor
|
||||
service.interceptors.request.use(
|
||||
(config) => {
|
||||
if (!config.headers) {
|
||||
config.headers.Accept = 'application/json';
|
||||
}
|
||||
config.headers.Authorization = `${localStorage.getItem('plantToken')}`;
|
||||
// if (!config.headers.remoteIp) {
|
||||
// config.baseURL += '/api';
|
||||
// }
|
||||
// config.headers.remoteIp = localStorage.getItem('plantIp') || '127.0.0.1';
|
||||
// if (store.state.common.token) {
|
||||
// config.headers['Login-Type'] = 'pc';
|
||||
// config.headers.Authorization = `Bearer ${store.state.common.token}`;
|
||||
// }
|
||||
return config;
|
||||
},
|
||||
(error) => Promise.reject(error)
|
||||
);
|
||||
|
||||
// response interceptor
|
||||
service.interceptors.response.use(
|
||||
(response) => {
|
||||
if (response.status === 200 || response.status === 201 || response.status === 202 || response.status === 204) {
|
||||
if (response.config.method === 'put') {
|
||||
// message.success('保存中...');
|
||||
}
|
||||
return Promise.resolve(response);
|
||||
}
|
||||
// return Promise.reject(/* new Error(response.message || 'Error') */);
|
||||
}
|
||||
// (error) => {
|
||||
// // for debug
|
||||
// if (error.response.status === 401) {
|
||||
// const query = router.currentRoute.value.query;
|
||||
// //关闭已弹出的所有弹框,防止弹框重叠
|
||||
// // Modal.destroyAll();
|
||||
// store.dispatch(A_COMMON_CLEAR_TOKEN);
|
||||
// window.parent.postMessage(
|
||||
// {
|
||||
// code: '301',
|
||||
// params: {}
|
||||
// },
|
||||
// '*'
|
||||
// );
|
||||
// store.commit('common/M_COMMON_SET_TOKEN_UNAUTHORIZED', false);
|
||||
// } else if (error.response.status === 403) {
|
||||
// router.push({
|
||||
// path: '/error/403'
|
||||
// });
|
||||
// } else if (error.response.status === 404) {
|
||||
// router.push({
|
||||
// path: '/error/404'
|
||||
// });
|
||||
// } else if (error.response.status === 500) {
|
||||
// router.push({
|
||||
// path: '/error/500'
|
||||
// });
|
||||
// } else {
|
||||
// // message.error(error.response.data?.message || '服务器错误');
|
||||
// }
|
||||
// return Promise.reject(error.response);
|
||||
// }
|
||||
);
|
||||
|
||||
export { service as http };
|
||||
@@ -4,6 +4,8 @@ import { defineStore } from 'pinia';
|
||||
// 如果没有现成的 uid 函数,可以引入一个 UUID 库
|
||||
// 或者使用其他 UUID 库
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { http } from '@/request/axios';
|
||||
import { surveyQuestion } from '@/request/api/modules/survey';
|
||||
|
||||
export const useCommonStore = defineStore('common', {
|
||||
state: () => ({
|
||||
@@ -257,19 +259,18 @@ export const useCommonStore = defineStore('common', {
|
||||
question_id: '17852294'
|
||||
}
|
||||
],
|
||||
|
||||
questions: [],
|
||||
cycle_pages: null
|
||||
}
|
||||
} as QuestionsInfo
|
||||
}),
|
||||
actions: {
|
||||
async fetchQuestionInfo(questionInfo) {
|
||||
async fetchQuestionInfo(questionInfo: string) {
|
||||
try {
|
||||
if (!questionInfo) return;
|
||||
|
||||
const info = JSON.parse(questionInfo);
|
||||
if (info?.questions?.length) {
|
||||
info.questions.forEach((page) => {
|
||||
info.questions.forEach((page:any) => {
|
||||
// 使用 UUID 生成唯一 ID
|
||||
if (page?.page) {
|
||||
page.pageId = page.pageId || uuidv4();
|
||||
@@ -281,8 +282,21 @@ export const useCommonStore = defineStore('common', {
|
||||
// 未来扩展
|
||||
}
|
||||
},
|
||||
setQuestionInfo(questionInfo) {
|
||||
setQuestionInfo(questionInfo: QuestionsInfo) {
|
||||
this.questionsInfo = questionInfo;
|
||||
},
|
||||
/**
|
||||
* web 端测试问卷地址 `/api/api/console/surveys/RWNK9BYp/questions`
|
||||
* 做了个测试,后面再改
|
||||
*/
|
||||
fetchSurveyQuestion() {
|
||||
http.get(surveyQuestion).then(res => {
|
||||
// console.log('http get request:',res.data.data);
|
||||
this.setQuestionInfo(res.data.data);
|
||||
});/* .catch(res=>{
|
||||
// console.log('catch',res);
|
||||
this.setQuestionInfo(res);
|
||||
}) */
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
|
||||
82
src/stores/modules/types/survey.d.ts
vendored
Normal file
82
src/stores/modules/types/survey.d.ts
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
interface QuestionLogic {
|
||||
value?: string;
|
||||
location?: number;
|
||||
date?: string;
|
||||
time?: string;
|
||||
type?: number;
|
||||
row_type?: number;
|
||||
cell_type?: number;
|
||||
logic?: string;
|
||||
operator?: string;
|
||||
is_answer?: number;
|
||||
is_select?: number;
|
||||
row_index?: number;
|
||||
cell_index?: number;
|
||||
question_type?: number;
|
||||
question_index?: number;
|
||||
relation_question_index?: number;
|
||||
relation_question_row_index?: number;
|
||||
relation_question_cell_index?: number;
|
||||
is_option_group?: number;
|
||||
option_index?: number;
|
||||
skip_type?: null | number;
|
||||
question_id?: null | string;
|
||||
}
|
||||
|
||||
interface Logic {
|
||||
logic?: QuestionLogic[];
|
||||
skip_question_index?: number;
|
||||
skip_type?: number;
|
||||
id?: number | string;
|
||||
question_index?: number;
|
||||
question_id?: string;
|
||||
}
|
||||
|
||||
interface LocalPage {
|
||||
pages?: number[];
|
||||
is_short_time?: number;
|
||||
short_time?: string;
|
||||
is_show?: number;
|
||||
use_type?: number;
|
||||
}
|
||||
|
||||
interface Survey {
|
||||
id?: number;
|
||||
introduction?: string;
|
||||
pages?: number[][];
|
||||
sn?: string;
|
||||
status?: number;
|
||||
title?: string;
|
||||
detail_pages?: number[][];
|
||||
group_pages?: number[][];
|
||||
is_one_page_one_question?: number;
|
||||
last_question_index?: number;
|
||||
is_three_d_permissions?: number;
|
||||
is_dept?: number;
|
||||
last_title?: string;
|
||||
project_name?: string;
|
||||
quota_end_content?: string;
|
||||
quota_end_url?: string;
|
||||
quota_end_url_select?: number;
|
||||
quota_standing_time?: number;
|
||||
screening_end_content?: string;
|
||||
screening_end_url?: string;
|
||||
screening_end_url_select?: number;
|
||||
screening_standing_time?: number;
|
||||
end_jump_url?: string;
|
||||
end_jump_status?: number;
|
||||
end_jump_standing_time?: number;
|
||||
success_end_content?: string;
|
||||
success_end_url?: string;
|
||||
success_end_url_select?: number;
|
||||
success_standing_time?: number;
|
||||
template_type?: number;
|
||||
local_pages?: LocalPage[];
|
||||
}
|
||||
|
||||
interface QuestionsInfo {
|
||||
survey?: Survey;
|
||||
logics?: Logic[];
|
||||
questions?: any[];
|
||||
cycle_pages?: null | any;
|
||||
}
|
||||
@@ -14,6 +14,8 @@
|
||||
:questions="questionInfo.questions"
|
||||
:index="index"
|
||||
:chooseQuestionId="chooseQuestionId"
|
||||
:show-actions="!preview"
|
||||
style="margin: 10px 0"
|
||||
@get-choose-question-id="getChooseQuestionId"
|
||||
>
|
||||
<!-- 选择题 -->
|
||||
@@ -102,7 +104,7 @@
|
||||
|
||||
<!-- {{ element.question_type }}-->
|
||||
<!-- {{questionInfo.survey.pages.length}}-->
|
||||
<div v-if="!filterGap">
|
||||
<div v-if="!preview">
|
||||
<paging
|
||||
v-if="!element.question_type && questionInfo.survey.pages.length > 1" :info="element" :index="index"
|
||||
:active="pageIsActive(activeIndex, questionInfo.questions, element.page)" @click.stop=""
|
||||
@@ -128,8 +130,10 @@ import TextWithImages from '@/views/Design/components/Questions/TextWithImages.v
|
||||
import SignQuestion from './components/Questions/SignQuestion.vue';
|
||||
import FileUpload from './components/Questions/FileUpload.vue';
|
||||
import NPS from '@/views/Design/components/Questions/NPS.vue';
|
||||
import { useCommonStore } from '@/stores/modules/common';
|
||||
|
||||
const activeIndex = ref(-1);
|
||||
|
||||
/**
|
||||
* 工具函数
|
||||
*/
|
||||
@@ -176,9 +180,13 @@ function util() {
|
||||
};
|
||||
}
|
||||
|
||||
// 获取所有的 question 列表内容
|
||||
const { filterGap } = defineProps({
|
||||
filterGap: {
|
||||
/**
|
||||
* 该组件用于展示和操作问卷中的问题。
|
||||
* @description 过滤Gap栏
|
||||
* @type {boolean} 默认为 false
|
||||
*/
|
||||
const { preview } = defineProps({
|
||||
preview: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
@@ -188,18 +196,23 @@ const { filterGap } = defineProps({
|
||||
const { pageIsActive } = util();
|
||||
// 获取 Store 实例
|
||||
const counterStore = useCounterStore();
|
||||
const store = storeToRefs(counterStore);
|
||||
const { questionsInfo: questionInfo } = storeToRefs(counterStore);
|
||||
|
||||
const chooseQuestionId = ref('');
|
||||
const questionInfo = ref(store.questionsInfo.value);
|
||||
// const questionInfo = ref(store.questionsInfo.value);
|
||||
|
||||
// 开始获取 http 请求,添加数据
|
||||
useCommonStore().fetchSurveyQuestion();
|
||||
|
||||
const emit = defineEmits(['getActiveQuestion']);
|
||||
|
||||
// 获取选中的题目的ID
|
||||
const getChooseQuestionId = (questionItem) => {
|
||||
chooseQuestionId.value = questionItem.id;
|
||||
// 向外传出选中的题目
|
||||
emit('getActiveQuestion', questionItem);
|
||||
};
|
||||
|
||||
// 组件对应的操作
|
||||
const actionOptions = [
|
||||
{
|
||||
@@ -233,6 +246,7 @@ const actionOptions = [
|
||||
const actionEvent = (item, el) => {
|
||||
actionFun[item.fun](el);
|
||||
};
|
||||
|
||||
// 总事件注册
|
||||
const actionFun = {
|
||||
// 单选事件 添加选项
|
||||
@@ -277,7 +291,8 @@ const actionFun = {
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
questionInfo.value = store.questionsInfo.value;
|
||||
// questionInfo.value = store.questionsInfo.value;
|
||||
|
||||
});
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
@@ -287,7 +302,7 @@ onMounted(() => {
|
||||
|
||||
.design-create {
|
||||
//min-height: calc(100vh);
|
||||
background-color: #e9eef3;
|
||||
//background-color: #e9eef3;
|
||||
color: #333;
|
||||
|
||||
.slot-actions {
|
||||
|
||||
@@ -1,16 +1,40 @@
|
||||
<script setup lang="ts">
|
||||
import PreviewIndex from './Index.vue';
|
||||
import { useCommonStore } from '@/stores/modules/common';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { ref } from 'vue';
|
||||
|
||||
import Success from '@/views/Survey/views/Success/Index.vue';
|
||||
|
||||
const { getQuestionsInfo: questionsInfo } = storeToRefs(useCommonStore());
|
||||
// 是否提交?如果提交则把组件展示出来
|
||||
const isSubmit = ref(true);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<van-nav-bar title="预览" left-arrow>
|
||||
<template #right>
|
||||
<van-icon name="search" />
|
||||
</template>
|
||||
<!-- <template #right>-->
|
||||
<!-- <van-icon name="search" />-->
|
||||
<!-- </template>-->
|
||||
</van-nav-bar>
|
||||
|
||||
<preview-index :filterGap="true"></preview-index>
|
||||
<div class="survey-preview">
|
||||
<div v-if="isSubmit" style="display: flex; flex-flow: column nowrap;align-items: center;">
|
||||
<div style=" width: 97%;background: white; ">
|
||||
<div v-html="questionsInfo?.survey?.title"></div>
|
||||
<p>为优化活动服务品质,烦请完成问卷,感谢配合!您的反馈至关重要</p>
|
||||
</div>
|
||||
<preview-index :preview="true"></preview-index>
|
||||
<van-button color="#70b936" style=" width: 100px;height: 30px" @click="isSubmit = !isSubmit">提交</van-button>
|
||||
</div>
|
||||
<!-- 提交成功展示页面 -->
|
||||
<Component :is="Success" v-else />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style lang="scss" scoped>
|
||||
.survey-preview{
|
||||
padding: 15px 0;
|
||||
background: linear-gradient(0deg, rgba(245,245,245,1) 80%, rgba(112,185,54,0.5) 100%) white;
|
||||
}
|
||||
</style>
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div class="choose-question-container">
|
||||
<div
|
||||
v-if="showActions"
|
||||
class="choose-question-context"
|
||||
:class="chooseQuestionId === element.id ? 'choose-question-active' : ''"
|
||||
@click="chooseItem"
|
||||
@@ -33,11 +34,15 @@
|
||||
<!-- </div>-->
|
||||
</van-cell>
|
||||
</div>
|
||||
<div v-else>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import QuestionAction from '@/views/Design/components/ActionCompoents/QuestionAction.vue';
|
||||
import { ref } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
element: {
|
||||
type: Object,
|
||||
@@ -56,6 +61,10 @@ const props = defineProps({
|
||||
chooseQuestionId: {
|
||||
type: String,
|
||||
default: '0'
|
||||
},
|
||||
showActions: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
});
|
||||
const element = ref(props.element);
|
||||
|
||||
18
src/views/Survey/views/Success/Index.vue
Normal file
18
src/views/Survey/views/Success/Index.vue
Normal file
@@ -0,0 +1,18 @@
|
||||
<template>
|
||||
<div class="survey-submit">
|
||||
<van-image :src="successImg" width="200" />
|
||||
<div>您已完成本次调研,感谢您的参与!</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
const successImg = 'https://files.axshare.com/gsc/DR6075/c7/5a/53/c75a534148d349f1bb8e185629f784ac/images/%E9%A2%84%E8%A7%88/u123.png?pageId=18fb9d8a-b9b7-465f-9bd7-625b1b78f72e';
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.survey-submit{
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
@@ -13,6 +13,21 @@ export default defineConfig({
|
||||
server: {
|
||||
host: '0.0.0.0', // 监听所有网络接口
|
||||
port: 3000, // 你也可以指定端口
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://yls-api-uat.dctest.digitalyili.com/',
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/api/, ''),
|
||||
},
|
||||
// '/api': {
|
||||
// target: 'http://yls-api-uat.dctest.digitalyili.com/',
|
||||
// changeOrigin: true,
|
||||
// pathRewrite: {
|
||||
// '^/api': 'http://yls-api-uat.dctest.digitalyili.com/', // 路径重写
|
||||
// },
|
||||
// cookieDomainRewrite: 'localhost',
|
||||
// }
|
||||
}
|
||||
},
|
||||
css: {
|
||||
postcss:{
|
||||
|
||||
Reference in New Issue
Block a user