parent
cffe037269
commit
48fdb3138a
@ -39,6 +39,11 @@ http {
|
||||
try_files $uri $uri/ /management.html;
|
||||
}
|
||||
|
||||
location /management/preview/ {
|
||||
try_files $uri $uri/ /render.html;
|
||||
}
|
||||
|
||||
|
||||
location /render/ {
|
||||
try_files $uri $uri/ /render.html;
|
||||
}
|
||||
|
@ -223,6 +223,38 @@ export class SurveyController {
|
||||
};
|
||||
}
|
||||
|
||||
@Get('/getPreviewSchema')
|
||||
@HttpCode(200)
|
||||
async getPreviewSchema(
|
||||
@Query()
|
||||
queryInfo: {
|
||||
surveyPath: string;
|
||||
},
|
||||
@Request()
|
||||
req,
|
||||
) {
|
||||
const { value, error } = Joi.object({
|
||||
surveyId: Joi.string().required(),
|
||||
}).validate({ surveyId: queryInfo.surveyPath });
|
||||
|
||||
if (error) {
|
||||
this.logger.error(error.message, { req });
|
||||
throw new HttpException('参数有误', EXCEPTION_CODE.PARAMETER_ERROR);
|
||||
}
|
||||
const surveyId = value.surveyId;
|
||||
const surveyConf =
|
||||
await this.surveyConfService.getSurveyConfBySurveyId(surveyId);
|
||||
const surveyMeta = await this.surveyMetaService.getSurveyById({ surveyId });
|
||||
return {
|
||||
code: 200,
|
||||
data: {
|
||||
...surveyConf,
|
||||
title: surveyMeta?.title,
|
||||
surveyPath: surveyMeta?.surveyPath,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@Post('/publishSurvey')
|
||||
@HttpCode(200)
|
||||
@UseGuards(SurveyGuard)
|
||||
|
BIN
web/public/imgs/preview-phone.png
Normal file
BIN
web/public/imgs/preview-phone.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.1 KiB |
@ -8,6 +8,7 @@
|
||||
<NavPanel></NavPanel>
|
||||
</div>
|
||||
<div class="right-group">
|
||||
<PreviewPanel></PreviewPanel>
|
||||
<HistoryPanel></HistoryPanel>
|
||||
<SavePanel></SavePanel>
|
||||
<PublishPanel></PublishPanel>
|
||||
@ -23,6 +24,7 @@ import BackPanel from '../modules/generalModule/BackPanel.vue'
|
||||
import TitlePanel from '../modules/generalModule/TitlePanel.vue'
|
||||
import NavPanel from '../modules/generalModule/NavPanel.vue'
|
||||
import HistoryPanel from '../modules/contentModule/HistoryPanel.vue'
|
||||
import PreviewPanel from '../modules/contentModule/PreviewPanel.vue'
|
||||
import SavePanel from '../modules/contentModule/SavePanel.vue'
|
||||
import PublishPanel from '../modules/contentModule/PublishPanel.vue'
|
||||
|
||||
|
@ -0,0 +1,184 @@
|
||||
<template>
|
||||
<div class="preview-panel">
|
||||
<div class="preview-btn" @click="dialogTableVisible = true">
|
||||
<i-ep-view class="view-icon" :size="20" />
|
||||
<span class="btn-txt">预览</span>
|
||||
</div>
|
||||
<el-dialog
|
||||
:z-index="99999"
|
||||
top="50px"
|
||||
class="preview-config-wrapper"
|
||||
:destroy-on-close="true"
|
||||
:show-close="false"
|
||||
@open="openDialog"
|
||||
@closed="closedDialog"
|
||||
v-model="dialogTableVisible"
|
||||
:width="`${previewTab == 1 ? '398' : '1290'}`"
|
||||
>
|
||||
<div class="ml75">
|
||||
<div class="preview-tab">
|
||||
<div :class="`preview-tab-item ${previewTab == 1 ? 'active' : ''}`" @click="previewTab = 1">
|
||||
<i-ep-iphone />
|
||||
</div>
|
||||
<div :class="`preview-tab-item ${previewTab == 2 ? 'active' : ''}`" @click="previewTab = 2">
|
||||
<i-ep-monitor />
|
||||
</div>
|
||||
</div>
|
||||
<div :class="`preview-panel ${previewTab == 1 ? 'phone' : 'pc'}`">
|
||||
<div class="wrapper">
|
||||
<div class="tips-wrapper">
|
||||
<i-ep-WarningFilled /> <span>用户预览模式,数据不保存!</span>
|
||||
</div>
|
||||
<div v-loading="loading" element-loading-text="加载中..." style="height: 100%">
|
||||
<iframe
|
||||
v-loading="loading"
|
||||
id="iframe-preview"
|
||||
:src="`/management/preview/${surveyId}`"
|
||||
frameborder="0"
|
||||
width="100%"
|
||||
height="100%"
|
||||
></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
const route = useRoute()
|
||||
|
||||
const dialogTableVisible = ref(false)
|
||||
const previewTab = ref(1)
|
||||
const surveyId = route.params.id
|
||||
const loading = ref(true)
|
||||
|
||||
const openDialog = () => {
|
||||
const iframePreview = document.getElementById('iframe-preview')
|
||||
if (!iframePreview) return
|
||||
iframePreview.onload = function () {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const closedDialog = () => {
|
||||
loading.value = true
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.preview-panel {
|
||||
:deep(.preview-config-wrapper) {
|
||||
background-color: transparent;
|
||||
box-shadow: none;
|
||||
padding: 0;
|
||||
}
|
||||
.ml75{
|
||||
margin-left: 75px;
|
||||
}
|
||||
|
||||
.preview-btn {
|
||||
width: 50px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
color: #4a4c5b;
|
||||
cursor: pointer;
|
||||
|
||||
i {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.btn-txt {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
.view-icon {
|
||||
font-size: 18px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.preview-tab {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.border-right-none {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.active {
|
||||
border-color: $primary-color;
|
||||
color: $primary-color;
|
||||
}
|
||||
|
||||
.border-left-none {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
&-item {
|
||||
width: 80px;
|
||||
height: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #ffffff;
|
||||
border: 1px solid rgba(227, 228, 232, 1);
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
border-color: $primary-color;
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
.preview-panel {
|
||||
margin-top: 16px;
|
||||
&.pc {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
background: #ffffff;
|
||||
box-shadow: 0px 2px 10px -2px rgba(82, 82, 102, 0.2);
|
||||
height: 726px;
|
||||
.wrapper {
|
||||
width: 636px;
|
||||
height: 704px;
|
||||
}
|
||||
}
|
||||
&.phone {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.wrapper {
|
||||
background: url('/imgs/preview-phone.png') no-repeat;
|
||||
width: 328px;
|
||||
height: 678px;
|
||||
background-size: 100% 100%;
|
||||
padding: 0 14px;
|
||||
padding-top: 58px;
|
||||
padding-bottom: 14px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
iframe {
|
||||
border-radius: 0px 0px 20px 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.tips-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: $primary-bg-color;
|
||||
color: $primary-color;
|
||||
font-size: 12px;
|
||||
padding: 2px 0;
|
||||
padding-left: 9px;
|
||||
|
||||
span {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -20,7 +20,7 @@
|
||||
import { computed, watch, onMounted } from 'vue'
|
||||
import { useStore } from 'vuex'
|
||||
|
||||
import { getPublishedSurveyInfo } from './api/survey'
|
||||
import { getPublishedSurveyInfo, getPreviewSchema } from './api/survey'
|
||||
import useCommandComponent from './hooks/useCommandComponent'
|
||||
|
||||
import EmptyPage from './pages/EmptyPage.vue'
|
||||
@ -65,6 +65,39 @@ const updateSkinConfig = (value: any) => {
|
||||
}
|
||||
}
|
||||
|
||||
const loadData = (res: any, surveyPath: string) => {
|
||||
if (res.code === 200) {
|
||||
const data = res.data
|
||||
const {
|
||||
bannerConf,
|
||||
baseConf,
|
||||
bottomConf,
|
||||
dataConf,
|
||||
skinConf,
|
||||
submitConf,
|
||||
logicConf
|
||||
} = data.code
|
||||
const questionData = {
|
||||
bannerConf,
|
||||
baseConf,
|
||||
bottomConf,
|
||||
dataConf,
|
||||
skinConf,
|
||||
submitConf
|
||||
}
|
||||
|
||||
document.title = data.title
|
||||
|
||||
updateSkinConfig(skinConf)
|
||||
|
||||
store.commit('setSurveyPath', surveyPath)
|
||||
store.dispatch('init', questionData)
|
||||
initRuleEngine(logicConf?.showLogicConf)
|
||||
} else {
|
||||
throw new Error(res.errmsg)
|
||||
}
|
||||
}
|
||||
|
||||
watch(skinConf, (value) => {
|
||||
updateSkinConfig(value)
|
||||
})
|
||||
@ -78,33 +111,14 @@ onMounted(async () => {
|
||||
}
|
||||
|
||||
const alert = useCommandComponent(AlertDialog)
|
||||
|
||||
try {
|
||||
const res: any = await getPublishedSurveyInfo({ surveyPath })
|
||||
|
||||
if (res.code === 200) {
|
||||
const data = res.data
|
||||
const { bannerConf, baseConf, bottomConf, dataConf, skinConf, submitConf, logicConf } =
|
||||
data.code
|
||||
const questionData = {
|
||||
bannerConf,
|
||||
baseConf,
|
||||
bottomConf,
|
||||
dataConf,
|
||||
skinConf,
|
||||
submitConf
|
||||
}
|
||||
|
||||
document.title = data.title
|
||||
|
||||
updateSkinConfig(skinConf)
|
||||
|
||||
store.commit('setSurveyPath', surveyPath)
|
||||
store.dispatch('init', questionData)
|
||||
store.dispatch('getEncryptInfo')
|
||||
initRuleEngine(logicConf?.showLogicConf)
|
||||
if (surveyPath.length > 8) {
|
||||
const res: any = await getPreviewSchema({ surveyPath })
|
||||
loadData(res, surveyPath)
|
||||
} else {
|
||||
throw new Error(res.errmsg)
|
||||
const res: any = await getPublishedSurveyInfo({ surveyPath })
|
||||
loadData(res, surveyPath)
|
||||
store.dispatch('getEncryptInfo')
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.log(error)
|
||||
|
@ -8,6 +8,14 @@ export const getPublishedSurveyInfo = ({ surveyPath }) => {
|
||||
})
|
||||
}
|
||||
|
||||
export const getPreviewSchema = ({ surveyPath }) => {
|
||||
return axios.get('/survey/getPreviewSchema', {
|
||||
params: {
|
||||
surveyPath
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const submitForm = (data) => {
|
||||
return axios.post('/surveyResponse/createResponse', data)
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ const bannerConf = computed(() => store.state?.bannerConf || {})
|
||||
const renderData = computed(() => store.getters.renderData)
|
||||
const submitConf = computed(() => store.state?.submitConf || {})
|
||||
const logoConf = computed(() => store.state?.bottomConf || {})
|
||||
const surveyPath = computed(() => store.state?.surveyPath || '')
|
||||
|
||||
const validate = (cbk: (v: boolean) => void) => {
|
||||
const index = 0
|
||||
@ -70,10 +71,9 @@ const normalizationRequestBody = () => {
|
||||
const enterTime = store.state.enterTime
|
||||
const encryptInfo = store.state.encryptInfo
|
||||
const formValues = store.state.formValues
|
||||
const surveyPath = store.state.surveyPath
|
||||
|
||||
const result: any = {
|
||||
surveyPath,
|
||||
surveyPath: surveyPath.value,
|
||||
data: JSON.stringify(formValues),
|
||||
difTime: Date.now() - enterTime,
|
||||
clientTime: Date.now()
|
||||
@ -96,6 +96,10 @@ const normalizationRequestBody = () => {
|
||||
}
|
||||
|
||||
const submitSurver = async () => {
|
||||
if (surveyPath.value.length > 8) {
|
||||
store.commit('setRouter', 'successPage')
|
||||
return
|
||||
}
|
||||
try {
|
||||
const params = normalizationRequestBody()
|
||||
console.log(params)
|
||||
|
@ -34,6 +34,10 @@ const mpaPlugin = createMpaPlugin({
|
||||
from: /render/,
|
||||
to: () => normalizePath('/src/render/index.html')
|
||||
},
|
||||
{
|
||||
from: /management\/preview/,
|
||||
to: () => normalizePath('/src/render/index.html')
|
||||
},
|
||||
{
|
||||
from: /\/|\/management\/.?/,
|
||||
to: () => normalizePath('/src/management/index.html')
|
||||
|
Loading…
Reference in New Issue
Block a user