feat: 优化分页器结构

This commit is contained in:
sudoooooo 2024-08-06 19:33:11 +08:00
parent fbc654f21b
commit 82c98ec1f5
12 changed files with 594 additions and 484 deletions

View File

@ -4,8 +4,12 @@
<i-ep-ArrowLeft /> <i-ep-ArrowLeft />
</span> </span>
<template v-if="!is_more_filled"> <template v-if="!is_more_filled">
<div v-for="i in firstPagination" :key="i" :class="['com-pagination-item', `page-${i}`, (now_page == i ? 'current' : '')]" <div
@click="changePage(i)"> v-for="i in firstPagination"
:key="i"
:class="['com-pagination-item', `page-${i}`, now_page == i ? 'current' : '']"
@click="changePage(i)"
>
<span>{{ i }}</span> <span>{{ i }}</span>
<div v-if="!props.readonly" :class="['moreControls']" @click.stop="showTooltipVisible(i)"> <div v-if="!props.readonly" :class="['moreControls']" @click.stop="showTooltipVisible(i)">
<i-ep-MoreFilled /> <i-ep-MoreFilled />
@ -13,8 +17,12 @@
</div> </div>
</template> </template>
<template v-else> <template v-else>
<div v-for="i in more_filled_arr.startArr" @click="changePage(i)" :key="i" <div
:class="['com-pagination-item', ` page-${i}`, (now_page == i ? 'current' : '')]"> v-for="i in more_filled_arr.startArr"
@click="changePage(i)"
:key="i"
:class="['com-pagination-item', ` page-${i}`, now_page == i ? 'current' : '']"
>
<span>{{ i }}</span> <span>{{ i }}</span>
<div v-if="!props.readonly" :class="['moreControls']" @click.stop="showTooltipVisible(i)"> <div v-if="!props.readonly" :class="['moreControls']" @click.stop="showTooltipVisible(i)">
<i-ep-MoreFilled /> <i-ep-MoreFilled />
@ -26,14 +34,23 @@
</span> </span>
<template #content> <template #content>
<div class="bubble-wrap"> <div class="bubble-wrap">
<div class="bubble-item" v-for="i in more_filled_arr.bubbleArr" :key="i" @click="changePage(i)"> <div
class="bubble-item"
v-for="i in more_filled_arr.bubbleArr"
:key="i"
@click="changePage(i)"
>
<span>{{ i }}</span> <span>{{ i }}</span>
</div> </div>
</div> </div>
</template> </template>
</el-tooltip> </el-tooltip>
<div v-for="i in more_filled_arr.endArr" :key="i" <div
:class="['com-pagination-item', `page-${i}`, (now_page == i ? 'current' : '')]" @click="changePage(i)"> v-for="i in more_filled_arr.endArr"
:key="i"
:class="['com-pagination-item', `page-${i}`, now_page == i ? 'current' : '']"
@click="changePage(i)"
>
<span>{{ i }}</span> <span>{{ i }}</span>
<div v-if="!props.readonly" :class="['moreControls']" @click.stop="showTooltipVisible(i)"> <div v-if="!props.readonly" :class="['moreControls']" @click.stop="showTooltipVisible(i)">
<i-ep-MoreFilled /> <i-ep-MoreFilled />
@ -43,17 +60,25 @@
<span :class="['com-pagination-item', next_class]" @click="changePage(next_page)"> <span :class="['com-pagination-item', next_class]" @click="changePage(next_page)">
<i-ep-ArrowRight /> <i-ep-ArrowRight />
</span> </span>
<el-tooltip v-if="slot.tooltip && props.readonly==false" :visible="tooltipVisible" :popper-options="{ <el-tooltip
modifiers: [ v-if="slot.tooltip && props.readonly == false"
{ :visible="tooltipVisible"
name: 'computeStyles', :popper-options="{
options: { modifiers: [
adaptive: false, {
enabled: false, name: 'computeStyles',
}, options: {
}, adaptive: false,
], enabled: false
}" :virtual-ref="triggerBtn" virtual-triggering effect="light" popper-class="singleton-tooltip"> }
}
]
}"
:virtual-ref="triggerBtn"
virtual-triggering
effect="light"
popper-class="singleton-tooltip"
>
<template #content> <template #content>
<slot name="tooltip" :index="tooltipIndex"></slot> <slot name="tooltip" :index="tooltipIndex"></slot>
</template> </template>
@ -62,78 +87,77 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { clone } from "lodash-es"; import { clone } from 'lodash-es'
import { withDefaults, reactive, computed, watch, ref, onMounted, onUnmounted, nextTick, useSlots } from "vue"; import { reactive, computed, watch, ref, onMounted, onUnmounted, nextTick, useSlots } from 'vue'
interface Props { interface Props {
modelValue: number // modelValue: number //
totalPage?: number totalPage?: number
intervalCount?: number, intervalCount?: number
readonly?: boolean readonly?: boolean
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
modelValue: 1, modelValue: 1,
totalPage: 1, totalPage: 1,
intervalCount: 8, intervalCount: 8,
readonly:false readonly: false
}); })
const emit = defineEmits(['change-page', 'update:modelValue']); const emit = defineEmits(['change-page', 'update:modelValue'])
const state = reactive({ const state = reactive({
now: props.modelValue, now: props.modelValue,
jump: '' jump: ''
}); })
const slot = useSlots(); const slot = useSlots()
const moreVisible = ref(false) const moreVisible = ref(false)
const tooltipVisible = ref(false) const tooltipVisible = ref(false)
const triggerBtn = ref<EventTarget | null>(null); const triggerBtn = ref<EventTarget | null>(null)
const tooltipIndex = ref(0) const tooltipIndex = ref(0)
const now_page = computed(() => { const now_page = computed(() => {
return state.now * 1; return state.now * 1
}); })
const prev_class = computed(() => { const prev_class = computed(() => {
return now_page.value == 1 ? 'disabled' : ''; return now_page.value == 1 ? 'disabled' : ''
}); })
const next_class = computed(() => { const next_class = computed(() => {
return now_page.value == props.totalPage ? 'disabled' : ''; return now_page.value == props.totalPage ? 'disabled' : ''
}); })
const prev_page = computed(() => { const prev_page = computed(() => {
return now_page.value > 1 ? now_page.value - 1 : 1; return now_page.value > 1 ? now_page.value - 1 : 1
});
const next_page = computed(() => {
return now_page.value < props.totalPage ? now_page.value + 1 : props.totalPage;
});
const is_more_filled = computed(() => {
const intervalNum = props.totalPage - now_page.value + 1;
if (intervalNum >= props.intervalCount+1) {
return true;
}
return false;
}) })
const next_page = computed(() => {
return now_page.value < props.totalPage ? now_page.value + 1 : props.totalPage
})
const is_more_filled = computed(() => {
const intervalNum = props.totalPage - now_page.value + 1
if (intervalNum >= props.intervalCount + 1) {
return true
}
return false
})
const totalArr = computed(() => { const totalArr = computed(() => {
const arr = []; const arr = []
for (let i = 0; i < props.totalPage; i++) { for (let i = 0; i < props.totalPage; i++) {
arr.push(i + 1); arr.push(i + 1)
} }
return arr; return arr
}) })
const more_filled_arr = computed(() => { const more_filled_arr = computed(() => {
let startArr = []; let startArr = []
let bubbleArr = []; let bubbleArr = []
let endArr = []; let endArr = []
const arr = clone(totalArr.value); const arr = clone(totalArr.value)
const intervalNum = Math.round(props.intervalCount/2) const intervalNum = Math.round(props.intervalCount / 2)
startArr = arr.slice(now_page.value - 1, intervalNum+now_page.value - 1); startArr = arr.slice(now_page.value - 1, intervalNum + now_page.value - 1)
endArr = arr.slice(intervalNum*-1) endArr = arr.slice(intervalNum * -1)
bubbleArr = arr.slice(startArr[startArr.length-1], endArr[0]-1); bubbleArr = arr.slice(startArr[startArr.length - 1], endArr[0] - 1)
return { return {
startArr, startArr,
bubbleArr, bubbleArr,
@ -142,32 +166,32 @@ const more_filled_arr = computed(() => {
}) })
const firstPagination = computed(() => { const firstPagination = computed(() => {
const arr = clone(totalArr.value); const arr = clone(totalArr.value)
return arr.splice(props.intervalCount * -1); return arr.splice(props.intervalCount * -1)
}) })
const changePage = (page: number) => { const changePage = (page: number) => {
state.now = page; state.now = page
emit('update:modelValue', state.now); emit('update:modelValue', state.now)
emit('change-page', state.now); emit('change-page', state.now)
}; }
const showTooltipVisible = (index:number) => { const showTooltipVisible = (index: number) => {
if (slot.tooltip) { if (slot.tooltip) {
nextTick(() => { nextTick(() => {
tooltipIndex.value = index; tooltipIndex.value = index
triggerBtn.value = document.getElementsByClassName(`page-${index}`)[0] || null; triggerBtn.value = document.getElementsByClassName(`page-${index}`)[0] || null
tooltipVisible.value = true; tooltipVisible.value = true
}) })
} }
} }
const hideMoreVisible = () => { const hideMoreVisible = () => {
moreVisible.value = false; moreVisible.value = false
} }
const hideTooltipVisible = () => { const hideTooltipVisible = () => {
tooltipVisible.value = false; tooltipVisible.value = false
} }
onMounted(() => { onMounted(() => {
@ -175,20 +199,21 @@ onMounted(() => {
if (slot.tooltip) { if (slot.tooltip) {
document.addEventListener('click', hideTooltipVisible) document.addEventListener('click', hideTooltipVisible)
} }
}); })
onUnmounted(() => { onUnmounted(() => {
document.removeEventListener('click', hideMoreVisible) document.removeEventListener('click', hideMoreVisible)
if (slot.tooltip) { if (slot.tooltip) {
document.removeEventListener('click', hideTooltipVisible) document.removeEventListener('click', hideTooltipVisible)
} }
}); })
watch(() => props.modelValue, () => {
state.now = props.modelValue;
});
watch(
() => props.modelValue,
() => {
state.now = props.modelValue
}
)
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.bubble-wrap { .bubble-wrap {
@ -212,13 +237,13 @@ watch(() => props.modelValue, () => {
align-items: center; align-items: center;
font-size: 0; font-size: 0;
user-select: none; user-select: none;
.moreControls{ .moreControls {
color:#6E707C; color: #6e707c;
display: none; display: none;
position: absolute; position: absolute;
left:22px; left: 22px;
svg{ svg {
transform: rotate(90deg); transform: rotate(90deg);
font-size: 10px; font-size: 10px;
} }
@ -240,14 +265,14 @@ watch(() => props.modelValue, () => {
&:hover { &:hover {
color: $primary-color; color: $primary-color;
.moreControls{ .moreControls {
display: block; display: block;
} }
} }
&.active { &.active {
color: $primary-color; color: $primary-color;
.moreControls{ .moreControls {
display: block; display: block;
} }
} }
@ -267,9 +292,9 @@ watch(() => props.modelValue, () => {
.disabled, .disabled,
.disabled:hover { .disabled:hover {
svg{ svg {
cursor: not-allowed; cursor: not-allowed;
color:#303133 !important; color: #303133 !important;
} }
} }
@ -277,6 +302,5 @@ watch(() => props.modelValue, () => {
.current:hover { .current:hover {
color: $primary-color; color: $primary-color;
} }
} }
</style> </style>

View File

@ -0,0 +1,125 @@
<template>
<div class="pagination-wrap">
<PaginationPanel
v-model="schema.pageEditOne"
:readonly="props.readonly"
:totalPage="pageCount"
@changePage="updatePage"
:intervalCount="10"
>
<template #tooltip="{ index }">
<div>
<div v-if="index != 1" class="controls-wrap-item" @click="movePage(index, 'up')">
前移一页
</div>
<div
v-if="index != pageCount"
class="mt8 controls-wrap-item"
@click="movePage(index, 'down')"
>
后移一页
</div>
<div class="mt8 controls-wrap-item" @click="copyPage(index)">复制</div>
<div class="mt8 controls-wrap-item" @click="deletePage(index)">删除</div>
</div>
</template>
</PaginationPanel>
<i-ep-plus
v-if="!props.readonly"
style="font-size: 12px"
@click="addPageControls"
class="plus-add"
/>
</div>
</template>
<script setup>
import { storeToRefs } from 'pinia'
import { useEditStore } from '@/management/stores/edit'
import { QUESTION_TYPE } from '@/common/typeEnum.ts'
import PaginationPanel from './PaginationPanel.vue'
const props = defineProps({
readonly: {
type: Boolean,
default: false
}
})
const editStore = useEditStore()
const { pageCount, schema, newQuestionIndex } = storeToRefs(editStore)
const {
updatePageEditOne,
addPage,
createNewQuestion,
addQuestion,
setCurrentEditOne,
deletePage,
swapArrayRanges,
copyPage
} = editStore
const updatePage = (index) => {
setCurrentEditOne(null)
updatePageEditOne(index)
}
const movePage = (position, type) => {
setCurrentEditOne(null)
const pageIndex = type === 'up' ? position - 1 : position + 1
updatePageEditOne(pageIndex)
if (type === 'up') {
swapArrayRanges(position, position - 1)
}
if (type === 'down') {
swapArrayRanges(position + 1, position)
}
}
const addPageControls = () => {
const newQuestion = createNewQuestion({ type: QUESTION_TYPE.TEXT })
updatePageEditOne(pageCount.value + 1)
setCurrentEditOne(null)
addQuestion({ question: newQuestion, index: newQuestionIndex.value })
setCurrentEditOne(newQuestionIndex.value)
addPage()
}
</script>
<style lang="scss" scoped>
.mt8 {
margin-top: 8px;
}
.controls-wrap {
&-item {
color: #4a4c5b;
font-size: 12px;
font-weight: 400;
cursor: pointer;
&:hover {
color: $primary-color;
}
}
}
.pagination-wrap {
display: flex;
align-items: center;
background: #ffffff;
box-shadow: 0px 2px 10px -2px rgba(82, 82, 102, 0.2);
border-radius: 4px;
margin-bottom: 12px;
.plus-add {
cursor: pointer;
margin-left: 12px;
&:hover {
color: $primary-color;
}
}
}
</style>

View File

@ -1,101 +0,0 @@
<template>
<div class="pagination-wrap">
<PaginationPanel v-model="schema.pagingEditOne" :readonly="props.readonly" :totalPage="pagingCount" @changePage="updatePageEditOne" :intervalCount="10">
<template #tooltip="{index}">
<div>
<div v-if="index != 1" class="controls-wrap-item" @click="movePaging(index, 'up')">前移一页</div>
<div v-if="index != pagingCount" class="mt8 controls-wrap-item" @click="movePaging(index, 'down')">后移一页</div>
<div class="mt8 controls-wrap-item" @click="copyPaging(index)">复制</div>
<div class="mt8 controls-wrap-item" @click="deletePaging(index)">删除</div>
</div>
</template>
</PaginationPanel>
<i-ep-plus v-if="!props.readonly" style="font-size: 12px;" @click="addPagingControls" class="plus-add" />
</div>
</template>
<script setup>
import PaginationPanel from '../modules/pagingModule/PaginationPanel.vue'
import { useEditStore } from '@/management/stores/edit'
import { storeToRefs } from 'pinia'
import { QUESTION_TYPE } from '@/common/typeEnum.ts'
const props = defineProps({
readonly: {
type: Boolean,
default: false
}
})
const editStore = useEditStore();
const { pagingCount, schema, newQuestionIndex } = storeToRefs(editStore)
const { updatePagingEditOne, addPaging, createNewQuestion, addQuestion, setCurrentEditOne, deletePaging, swapArrayRanges, copyPaging } = editStore;
const updatePageEditOne = (index) => {
setCurrentEditOne(null)
updatePagingEditOne(index);
}
const movePaging = (position, type) => {
setCurrentEditOne(null)
const pagingIndex = type === 'up' ? position - 1 : position + 1;
updatePagingEditOne(pagingIndex)
if (type === 'up') {
swapArrayRanges(position, position - 1)
}
if (type === 'down') {
swapArrayRanges(position + 1, position)
}
}
const addPagingControls = () => {
const newQuestion = createNewQuestion({ type: QUESTION_TYPE.TEXT })
updatePagingEditOne(pagingCount.value + 1)
setCurrentEditOne(null)
addQuestion({ question: newQuestion, index: newQuestionIndex.value })
setCurrentEditOne(newQuestionIndex.value)
addPaging()
}
</script>
<style lang="scss" scoped>
.mt8 {
margin-top: 8px
}
.controls-wrap {
&-item {
color: #4A4C5B;
font-size: 12px;
font-weight: 400;
cursor: pointer;
&:hover {
color: $primary-color;
}
}
}
.pagination-wrap {
display: flex;
align-items: center;
background: #FFFFFF;
box-shadow: 0px 2px 10px -2px rgba(82, 82, 102, 0.2);
border-radius: 4px;
margin-bottom: 12px;
.plus-add {
cursor: pointer;
margin-left: 12px;
&:hover {
color: $primary-color;
}
}
}
</style>

View File

@ -10,7 +10,7 @@ export default function (schema) {
'skinConf', 'skinConf',
'submitConf', 'submitConf',
'questionDataList', 'questionDataList',
"pagingConf", 'pageConf',
'logicConf' 'logicConf'
]) ])
configData.dataConf = { configData.dataConf = {

View File

@ -1,12 +1,12 @@
<template> <template>
<div class="main-operation" @click="onMainClick" ref="mainOperation"> <div class="main-operation" @click="onMainClick" ref="mainOperation">
<div class="pagination-wrapper"> <div class="pagination-wrapper">
<PagingWrapper :readonly="false"/> <PageWrapper :readonly="false" />
</div> </div>
<div class="operation-wrapper" ref="operationWrapper"> <div class="operation-wrapper" ref="operationWrapper">
<div class="box content" ref="box"> <div class="box content" ref="box">
<MainTitle <MainTitle
v-if="pagingEditOne==1" v-if="pageEditOne == 1"
:bannerConf="bannerConf" :bannerConf="bannerConf"
:readonly="false" :readonly="false"
:is-selected="currentEditOne === 'mainTitle'" :is-selected="currentEditOne === 'mainTitle'"
@ -15,7 +15,7 @@
/> />
<MaterialGroup <MaterialGroup
:current-edit-one="parseInt(currentEditOne)" :current-edit-one="parseInt(currentEditOne)"
:questionDataList="pagingQuestionData" :questionDataList="pageQuestionData"
@select="setCurrentEditOne" @select="setCurrentEditOne"
@change="handleChange" @change="handleChange"
@changeSeq="onQuestionOperation" @changeSeq="onQuestionOperation"
@ -37,7 +37,7 @@
<script setup> <script setup>
import { ref, watch, toRefs } from 'vue' import { ref, watch, toRefs } from 'vue'
import communalLoader from '@materials/communals/communalLoader.js' import communalLoader from '@materials/communals/communalLoader.js'
import PagingWrapper from '@/management/pages/edit/components/PagingWrapper.vue' import PageWrapper from '@/management/pages/edit/components/Pagination/PaginationWrapper.vue'
import MaterialGroup from '@/management/pages/edit/components/MaterialGroup.vue' import MaterialGroup from '@/management/pages/edit/components/MaterialGroup.vue'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { useEditStore } from '@/management/stores/edit' import { useEditStore } from '@/management/stores/edit'
@ -46,7 +46,8 @@ const MainTitle = communalLoader.loadComponent('MainTitle')
const SubmitButton = communalLoader.loadComponent('SubmitButton') const SubmitButton = communalLoader.loadComponent('SubmitButton')
const editStore = useEditStore() const editStore = useEditStore()
const { currentEditOne, currentEditKey,pagingQuestionData,isFinallyPage,pagingEditOne } = storeToRefs(editStore) const { currentEditOne, currentEditKey, pageQuestionData, isFinallyPage, pageEditOne } =
storeToRefs(editStore)
const { schema, changeSchema, moveQuestion, copyQuestion, deleteQuestion, setCurrentEditOne } = const { schema, changeSchema, moveQuestion, copyQuestion, deleteQuestion, setCurrentEditOne } =
editStore editStore
const mainOperation = ref(null) const mainOperation = ref(null)
@ -54,7 +55,6 @@ const materialGroup = ref(null)
const { bannerConf, submitConf, skinConf } = toRefs(schema) const { bannerConf, submitConf, skinConf } = toRefs(schema)
// const autoScrollData = computed(() => { // const autoScrollData = computed(() => {
// return { // return {
// currentEditOne: currentEditOne.value, // currentEditOne: currentEditOne.value,
@ -146,13 +146,13 @@ watch(
align-items: center; align-items: center;
background-color: #f6f7f9; background-color: #f6f7f9;
} }
.pagination-wrapper{ .pagination-wrapper {
width: 90%; width: 90%;
padding-right: 30px; padding-right: 30px;
margin-right: -30px; margin-right: -30px;
position: relative; position: relative;
top: 50px; top: 50px;
} }
.toolbar { .toolbar {
width: 100%; width: 100%;

View File

@ -2,20 +2,28 @@
<div class="question-catalog-wrapper"> <div class="question-catalog-wrapper">
<el-collapse> <el-collapse>
<el-collapse-item v-for="(v, i) in renderData" :key="v" :title="`第${i + 1}页`" :name="i + 1"> <el-collapse-item v-for="(v, i) in renderData" :key="v" :title="`第${i + 1}页`" :name="i + 1">
<draggable v-model="renderData[i]" itemKey="field" :group="QUESTION_CATALOG" handle=".draggHandle" <draggable
host-class="catalog-item-ghost"> v-model="renderData[i]"
itemKey="field"
:group="QUESTION_CATALOG"
handle=".draggHandle"
host-class="catalog-item-ghost"
>
<template #item="{ element }"> <template #item="{ element }">
<CatalogItem :title="element.title" :indexNumber="element.indexNumber" :showIndex="element.showIndex" <CatalogItem
@select="setPagingOneEdit(element.qIndex, i + 1)" /> :title="element.title"
:indexNumber="element.indexNumber"
:showIndex="element.showIndex"
@select="setPageOneEdit(element.qIndex, i + 1)"
/>
</template> </template>
</draggable> </draggable>
</el-collapse-item> </el-collapse-item>
</el-collapse> </el-collapse>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { watch, ref } from 'vue' import { watch, ref } from 'vue'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { useEditStore } from '@/management/stores/edit' import { useEditStore } from '@/management/stores/edit'
import draggable from 'vuedraggable' import draggable from 'vuedraggable'
@ -24,43 +32,48 @@ import CatalogItem from './CatalogItem.vue'
import { QUESTION_CATALOG } from '@/management/config/dnd' import { QUESTION_CATALOG } from '@/management/config/dnd'
const editStore = useEditStore() const editStore = useEditStore()
const { questionDataList, pagingConf } = storeToRefs(editStore) const { questionDataList, pageConf } = storeToRefs(editStore)
const { setCurrentEditOne, getPagingQuestionData, updatePagingEditOne,setPaging,compareQuestionSeq } = editStore const { setCurrentEditOne, getPageQuestionData, updatePageEditOne, setPage, compareQuestionSeq } =
editStore
const renderData: any = ref([]) const renderData: any = ref([])
const setPagingOneEdit = (qIndex: number, pagingIndex: number) => { const setPageOneEdit = (qIndex: number, pageIndex: number) => {
updatePagingEditOne(pagingIndex) updatePageEditOne(pageIndex)
setCurrentEditOne(qIndex) setCurrentEditOne(qIndex)
} }
watch(
watch(() => [pagingConf.value,questionDataList.value], () => { () => [pageConf.value, questionDataList.value],
renderData.value = []; () => {
for (let index = 0; index < pagingConf.value.length; index++) { renderData.value = []
renderData.value.push(getPagingQuestionData(index + 1)) for (let index = 0; index < pageConf.value.length; index++) {
renderData.value.push(getPageQuestionData(index + 1))
}
},
{
deep: true,
immediate: true
} }
},{ )
deep: true,
immediate: true
})
watch(() => renderData.value, (newVal) => {
if (newVal.length == 0) return;
let pagingData: Array<number> = [];
let questionList: Array<any> = [];
newVal.map((v:any) => {
pagingData.push(v.length)
questionList.push(...v)
})
setPaging(pagingData)
compareQuestionSeq(questionList)
}, {
deep: true
})
watch(
() => renderData.value,
(newVal) => {
if (newVal.length == 0) return
let pageData: Array<number> = []
let questionList: Array<any> = []
newVal.map((v: any) => {
pageData.push(v.length)
questionList.push(...v)
})
setPage(pageData)
compareQuestionSeq(questionList)
},
{
deep: true
}
)
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.question-catalog-wrapper { .question-catalog-wrapper {
@ -86,7 +99,7 @@ watch(() => renderData.value, (newVal) => {
:deep(.el-collapse-item__header) { :deep(.el-collapse-item__header) {
font-size: 14px; font-size: 14px;
color: #6E707C; color: #6e707c;
font-weight: 500; font-weight: 500;
} }

View File

@ -1,18 +1,32 @@
<template> <template>
<div class="main-operation"> <div class="main-operation">
<div class="pagination-wrapper"> <div class="pagination-wrapper">
<PagingWrapper :readonly="true" /> <PageWrapper :readonly="true" />
</div> </div>
<div class="operation-wrapper"> <div class="operation-wrapper">
<div class="box" ref="box"> <div class="box" ref="box">
<div class="mask"></div> <div class="mask"></div>
<HeaderContent v-if="pagingEditOne==1" :bannerConf="bannerConf" :readonly="false" /> <HeaderContent v-if="pageEditOne == 1" :bannerConf="bannerConf" :readonly="false" />
<div class="content"> <div class="content">
<MainTitle v-if="pagingEditOne==1" :isSelected="false" :bannerConf="bannerConf" :readonly="false" /> <MainTitle
<MaterialGroup :questionDataList="pagingQuestionData" ref="MaterialGroup" /> v-if="pageEditOne == 1"
<SubmitButton :submit-conf="submitConf" :skin-conf="skinConf" :readonly="false" :isSelected="false"
:is-selected="currentEditOne === 'submit'" :is-finally-page="isFinallyPage" /> :bannerConf="bannerConf"
<LogoIcon :logo-conf="bottomConf" :readonly="false" :is-selected="currentEditOne === 'logo'" /> :readonly="false"
/>
<MaterialGroup :questionDataList="pageQuestionData" ref="MaterialGroup" />
<SubmitButton
:submit-conf="submitConf"
:skin-conf="skinConf"
:readonly="false"
:is-selected="currentEditOne === 'submit'"
:is-finally-page="isFinallyPage"
/>
<LogoIcon
:logo-conf="bottomConf"
:readonly="false"
:is-selected="currentEditOne === 'logo'"
/>
</div> </div>
</div> </div>
</div> </div>
@ -21,7 +35,7 @@
<script> <script>
import { defineComponent, toRefs } from 'vue' import { defineComponent, toRefs } from 'vue'
import MaterialGroup from '@/management/pages/edit/components/MaterialGroup.vue' import MaterialGroup from '@/management/pages/edit/components/MaterialGroup.vue'
import PagingWrapper from '@/management/pages/edit/components/PagingWrapper.vue' import PageWrapper from '@/management/pages/edit/components/Pagination/PaginationWrapper.vue'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { useEditStore } from '@/management/stores/edit' import { useEditStore } from '@/management/stores/edit'
import communalLoader from '@materials/communals/communalLoader.js' import communalLoader from '@materials/communals/communalLoader.js'
@ -34,7 +48,7 @@ const LogoIcon = () => communalLoader.loadComponent('LogoIcon')
export default defineComponent({ export default defineComponent({
components: { components: {
MaterialGroup, MaterialGroup,
PagingWrapper, PageWrapper,
HeaderContent: HeaderContent(), HeaderContent: HeaderContent(),
MainTitle: MainTitle(), MainTitle: MainTitle(),
SubmitButton: SubmitButton(), SubmitButton: SubmitButton(),
@ -42,7 +56,8 @@ export default defineComponent({
}, },
setup() { setup() {
const editStore = useEditStore() const editStore = useEditStore()
const { pagingQuestionData, currentEditOne, currentEditKey,isFinallyPage,pagingEditOne } = storeToRefs(editStore) const { pageQuestionData, currentEditOne, currentEditKey, isFinallyPage, pageEditOne } =
storeToRefs(editStore)
const { schema } = editStore const { schema } = editStore
const { bannerConf, submitConf, skinConf, bottomConf } = toRefs(schema) const { bannerConf, submitConf, skinConf, bottomConf } = toRefs(schema)
@ -51,11 +66,11 @@ export default defineComponent({
submitConf, submitConf,
bottomConf, bottomConf,
skinConf, skinConf,
pagingQuestionData, pageQuestionData,
currentEditOne, currentEditOne,
currentEditKey, currentEditKey,
isFinallyPage, isFinallyPage,
pagingEditOne pageEditOne
} }
}, },
watch: { watch: {

View File

@ -1,6 +1,11 @@
import { type Ref, ref, reactive, toRef, computed } from 'vue' import { type Ref, ref, reactive, toRef, computed } from 'vue'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { merge as _merge, cloneDeep as _cloneDeep, set as _set,isNumber as _isNumber } from 'lodash-es' import {
merge as _merge,
cloneDeep as _cloneDeep,
set as _set,
isNumber as _isNumber
} from 'lodash-es'
import { QUESTION_TYPE } from '@/common/typeEnum' import { QUESTION_TYPE } from '@/common/typeEnum'
import { getQuestionByType } from '@/management/utils/index' import { getQuestionByType } from '@/management/utils/index'
import { filterQuestionPreviewData } from '@/management/utils/index' import { filterQuestionPreviewData } from '@/management/utils/index'
@ -74,10 +79,10 @@ function useInitializeSchema(surveyId: Ref<string>) {
link: '' link: ''
}, },
questionDataList: [], questionDataList: [],
pagingEditOne: 1, pageEditOne: 1,
pagingConf:[], // 分页逻辑 pageConf: [], // 分页逻辑
logicConf: { logicConf: {
showLogicConf: [], showLogicConf: []
} }
}) })
@ -89,9 +94,9 @@ function useInitializeSchema(surveyId: Ref<string>) {
schema.baseConf = _merge({}, schema.baseConf, codeData.baseConf) schema.baseConf = _merge({}, schema.baseConf, codeData.baseConf)
schema.submitConf = _merge({}, schema.submitConf, codeData.submitConf) schema.submitConf = _merge({}, schema.submitConf, codeData.submitConf)
schema.questionDataList = codeData.questionDataList || [] schema.questionDataList = codeData.questionDataList || []
schema.logicConf = codeData.logicConf; schema.logicConf = codeData.logicConf
schema.pagingEditOne = 1; schema.pageEditOne = 1
schema.pagingConf = codeData.pagingConf; schema.pageConf = codeData.pageConf
} }
async function getSchemaFromRemote() { async function getSchemaFromRemote() {
@ -101,16 +106,16 @@ function useInitializeSchema(surveyId: Ref<string>) {
document.title = metaData.title document.title = metaData.title
const data = res.data.surveyConfRes.code const data = res.data.surveyConfRes.code
const { const {
bannerConf, bannerConf,
bottomConf, bottomConf,
skinConf, skinConf,
baseConf, baseConf,
submitConf, submitConf,
dataConf, dataConf,
logicConf = {} logicConf = {}
} = data } = data
if (!data.pagingConf || data.pagingConf.length === 0) { if (!data.pageConf || data.pageConf.length === 0) {
data.pagingConf = [dataConf.dataList.length] data.pageConf = [dataConf.dataList.length]
} }
initSchema({ initSchema({
metaData, metaData,
@ -121,7 +126,7 @@ function useInitializeSchema(surveyId: Ref<string>) {
baseConf, baseConf,
submitConf, submitConf,
questionDataList: dataConf.dataList, questionDataList: dataConf.dataList,
pagingConf: data.pagingConf, pageConf: data.pageConf,
logicConf logicConf
} }
}) })
@ -137,7 +142,11 @@ function useInitializeSchema(surveyId: Ref<string>) {
} }
} }
function useQuestionDataListOperations(questionDataList: Ref<any[]>, updateTime: () => void,pagingOperations:(type:string)=>void) { function useQuestionDataListOperations(
questionDataList: Ref<any[]>,
updateTime: () => void,
pageOperations: (type: string) => void
) {
function copyQuestion({ index }: { index: number }) { function copyQuestion({ index }: { index: number }) {
const newQuestion = _cloneDeep(questionDataList.value[index]) const newQuestion = _cloneDeep(questionDataList.value[index])
newQuestion.field = getNewField(questionDataList.value.map((item) => item.field)) newQuestion.field = getNewField(questionDataList.value.map((item) => item.field))
@ -146,12 +155,12 @@ function useQuestionDataListOperations(questionDataList: Ref<any[]>, updateTime:
function addQuestion({ question, index }: { question: any; index: number }) { function addQuestion({ question, index }: { question: any; index: number }) {
questionDataList.value.splice(index, 0, question) questionDataList.value.splice(index, 0, question)
pagingOperations('add') pageOperations('add')
updateTime() updateTime()
} }
function deleteQuestion({ index }: { index: number }) { function deleteQuestion({ index }: { index: number }) {
pagingOperations('remove') pageOperations('remove')
questionDataList.value.splice(index, 1) questionDataList.value.splice(index, 1)
updateTime() updateTime()
} }
@ -280,139 +289,138 @@ function useCurrentEdit({
changeCurrentEditStatus changeCurrentEditStatus
} }
} }
function usePagingEdit({ function usePageEdit(
schema, {
questionDataList schema,
}: { questionDataList
schema: any, }: {
schema: any
questionDataList: Ref<any[]> questionDataList: Ref<any[]>
},updateTime: () => void) { },
const pagingConf = computed(() => schema.pagingConf) updateTime: () => void
const pagingEditOne = computed(() => schema.pagingEditOne) ) {
const pageConf = computed(() => schema.pageConf)
const pageEditOne = computed(() => schema.pageEditOne)
const isFinallyPage = computed(() => { const isFinallyPage = computed(() => {
return pagingEditOne.value === pagingConf.value.length; return pageEditOne.value === pageConf.value.length
}) })
const pagingCount = computed(() => pagingConf.value.length || 0) const pageCount = computed(() => pageConf.value.length || 0)
const pagingQuestionData = computed(() => { const pageQuestionData = computed(() => {
return getPagingQuestionData(pagingEditOne.value) return getPageQuestionData(pageEditOne.value)
}) })
const getPagingQuestionData = (index:number) => { const getPageQuestionData = (index: number) => {
const { startIndex, endIndex } = getSorter(index) const { startIndex, endIndex } = getSorter(index)
return filterQuestionPreviewData(questionDataList.value).slice(startIndex,endIndex) return filterQuestionPreviewData(questionDataList.value).slice(startIndex, endIndex)
} }
const getSorter = (index?:number) => { const getSorter = (index?: number) => {
let startIndex = 0; let startIndex = 0
const newPagingEditOne = index || pagingEditOne.value; const newPageEditOne = index || pageEditOne.value
const endIndex = pagingConf.value[newPagingEditOne - 1]; const endIndex = pageConf.value[newPageEditOne - 1]
for (let index = 0; index < pagingConf.value.length; index++) { for (let index = 0; index < pageConf.value.length; index++) {
const item = pagingConf.value[index]; const item = pageConf.value[index]
if ((newPagingEditOne - 1) == index) { if (newPageEditOne - 1 == index) {
break; break
} }
startIndex+=item startIndex += item
} }
return { return {
startIndex, startIndex,
endIndex:startIndex + endIndex endIndex: startIndex + endIndex
} }
} }
const addPaging = () => { const addPage = () => {
schema.pagingConf.push(1) schema.pageConf.push(1)
} }
const updatePagingEditOne = (index: number) => { const updatePageEditOne = (index: number) => {
schema.pagingEditOne = index; schema.pageEditOne = index
} }
const deletePaging = (index: number) => { const deletePage = (index: number) => {
if (pagingConf.value.length <= 1) return if (pageConf.value.length <= 1) return
const { startIndex, endIndex } = getSorter(index) const { startIndex, endIndex } = getSorter(index)
const newQuestion = _cloneDeep(questionDataList.value) const newQuestion = _cloneDeep(questionDataList.value)
newQuestion.splice(startIndex, endIndex-startIndex) newQuestion.splice(startIndex, endIndex - startIndex)
updatePagingEditOne(1); updatePageEditOne(1)
schema.pagingConf.splice(index-1, 1) schema.pageConf.splice(index - 1, 1)
questionDataList.value = newQuestion questionDataList.value = newQuestion
updateTime(); updateTime()
} }
const swapArrayRanges = (index:number,range:number) => { const swapArrayRanges = (index: number, range: number) => {
const { startIndex:start1,endIndex:end1 } = getSorter(index) const { startIndex: start1, endIndex: end1 } = getSorter(index)
const { startIndex:start2,endIndex:end2 } = getSorter(range) const { startIndex: start2, endIndex: end2 } = getSorter(range)
const newQuestion = _cloneDeep(questionDataList.value) const newQuestion = _cloneDeep(questionDataList.value)
const range1 = newQuestion.slice(start1, end1); const range1 = newQuestion.slice(start1, end1)
const range2 = newQuestion.slice(start2, end2 ); const range2 = newQuestion.slice(start2, end2)
newQuestion.splice(start1, range1.length, ...range2); newQuestion.splice(start1, range1.length, ...range2)
newQuestion.splice(start2, range2.length, ...range1); newQuestion.splice(start2, range2.length, ...range1)
questionDataList.value = newQuestion questionDataList.value = newQuestion
const rangeCount = schema.pagingConf[range-1] const rangeCount = schema.pageConf[range - 1]
schema.pagingConf[range-1] = schema.pagingConf[index-1] schema.pageConf[range - 1] = schema.pageConf[index - 1]
schema.pagingConf[index - 1] = rangeCount; schema.pageConf[index - 1] = rangeCount
updateTime(); updateTime()
} }
const copyPaging = (index: number) => { const copyPage = (index: number) => {
const newQuestionList = _cloneDeep(getPageQuestionData(index))
const newQuestionList = _cloneDeep(getPagingQuestionData(index))
newQuestionList.forEach((item) => { newQuestionList.forEach((item) => {
item.field = getNewField(questionDataList.value.map((item) => item.field)) item.field = getNewField(questionDataList.value.map((item) => item.field))
}) })
schema.pagingConf.splice(index, 0, newQuestionList.length) schema.pageConf.splice(index, 0, newQuestionList.length)
const { endIndex } = getSorter(index) const { endIndex } = getSorter(index)
questionDataList.value.splice(endIndex, 0, ...newQuestionList) questionDataList.value.splice(endIndex, 0, ...newQuestionList)
updateTime(); updateTime()
} }
const pagingOperations = (type:string) => { const pageOperations = (type: string) => {
const count = pagingConf.value[pagingEditOne.value - 1]; const count = pageConf.value[pageEditOne.value - 1]
if (type == 'add') { if (type == 'add') {
if (count!=undefined) { if (count != undefined) {
schema.pagingConf[pagingEditOne.value - 1] = count + 1; ; schema.pageConf[pageEditOne.value - 1] = count + 1
} }
return return
} }
if (type == 'remove') { if (type == 'remove') {
if (count) { if (count) {
schema.pagingConf[pagingEditOne.value - 1] = count - 1; schema.pageConf[pageEditOne.value - 1] = count - 1
} }
} }
} }
const setPaging = (data: Array<number>) => { const setPage = (data: Array<number>) => {
for (let index = 0; index < pagingConf.value.length; index++) { for (let index = 0; index < pageConf.value.length; index++) {
const newIndex = data[index]; const newIndex = data[index]
const oldIndex = pagingConf.value[index]; const oldIndex = pageConf.value[index]
if (newIndex != oldIndex) { if (newIndex != oldIndex) {
schema.pagingConf[index] = newIndex; schema.pageConf[index] = newIndex
} }
} }
} }
return { return {
pagingEditOne, pageEditOne,
pagingConf, pageConf,
isFinallyPage, isFinallyPage,
pagingCount, pageCount,
pagingQuestionData, pageQuestionData,
getSorter, getSorter,
updatePagingEditOne, updatePageEditOne,
deletePaging, deletePage,
addPaging, addPage,
copyPaging, copyPage,
getPagingQuestionData, getPageQuestionData,
pagingOperations, pageOperations,
swapArrayRanges, swapArrayRanges,
setPaging setPage
} }
} }
type IBannerItem = { type IBannerItem = {
name: string name: string
key: string key: string
@ -471,54 +479,73 @@ export const useEditStore = defineStore('edit', () => {
schemaUpdateTime.value = Date.now() schemaUpdateTime.value = Date.now()
} }
const { pagingEditOne, pagingConf, isFinallyPage, pagingCount, pagingQuestionData, getSorter, const {
updatePagingEditOne, deletePaging,pagingOperations,addPaging,getPagingQuestionData,copyPaging,swapArrayRanges,setPaging }= usePagingEdit({ schema, questionDataList },updateTime) pageEditOne,
pageConf,
isFinallyPage,
pageCount,
pageQuestionData,
getSorter,
updatePageEditOne,
deletePage,
pageOperations,
addPage,
getPageQuestionData,
copyPage,
swapArrayRanges,
setPage
} = usePageEdit({ schema, questionDataList }, updateTime)
const { copyQuestion, addQuestion, deleteQuestion, moveQuestion} = useQuestionDataListOperations( const { copyQuestion, addQuestion, deleteQuestion, moveQuestion } = useQuestionDataListOperations(
questionDataList, questionDataList,
updateTime, updateTime,
pagingOperations pageOperations
) )
function moveQuestionDataList(data: any) { function moveQuestionDataList(data: any) {
const { startIndex, endIndex } = getSorter() const { startIndex, endIndex } = getSorter()
const newData = [...questionDataList.value.slice(0, startIndex), ...data, ...questionDataList.value.slice(endIndex)]; const newData = [
const countTotal:number = (schema.pagingConf as Array<number>).reduce((v:number, i:number) => v + i) ...questionDataList.value.slice(0, startIndex),
...data,
...questionDataList.value.slice(endIndex)
]
const countTotal: number = (schema.pageConf as Array<number>).reduce(
(v: number, i: number) => v + i
)
if (countTotal != newData.length) { if (countTotal != newData.length) {
schema.pagingConf[pagingEditOne.value - 1] = schema.pagingConf[pagingEditOne.value - 1] + 1 as never; schema.pageConf[pageEditOne.value - 1] = (schema.pageConf[pageEditOne.value - 1] + 1) as never
} }
setQuestionDataList(newData) setQuestionDataList(newData)
} }
const compareQuestionSeq = (val:Array<any>) => { const compareQuestionSeq = (val: Array<any>) => {
const newSeq: Array<string> = []; const newSeq: Array<string> = []
const oldSeq: Array<string> = []; const oldSeq: Array<string> = []
let status = false; let status = false
val.map(v => { val.map((v) => {
newSeq.push(v.field) newSeq.push(v.field)
}); })
(questionDataList.value as Array<any>).map(v => { ;(questionDataList.value as Array<any>).map((v) => {
oldSeq.push(v.field) oldSeq.push(v.field)
}) })
for (let index = 0; index < newSeq.length; index++) { for (let index = 0; index < newSeq.length; index++) {
if (newSeq[index] !== oldSeq[index]) { if (newSeq[index] !== oldSeq[index]) {
status = true; status = true
break; break
} }
} }
if (status) { if (status) {
setQuestionDataList(val); setQuestionDataList(val)
} }
} }
const newQuestionIndex = computed(() => { const newQuestionIndex = computed(() => {
if (_isNumber(currentEditOne.value)) { if (_isNumber(currentEditOne.value)) {
return currentEditOne.value + 1 return currentEditOne.value + 1
} else { } else {
const pagingConf = schema.pagingConf const pageConf = schema.pageConf
const questCount = pagingConf[schema.pagingEditOne - 1]; const questCount = pageConf[schema.pageEditOne - 1]
const { startIndex,endIndex } = getSorter(); const { startIndex, endIndex } = getSorter()
if (!questCount) { if (!questCount) {
return startIndex return startIndex
} }
@ -526,8 +553,8 @@ export const useEditStore = defineStore('edit', () => {
} }
}) })
const createNewQuestion = ({type}:{type:QUESTION_TYPE}) => { const createNewQuestion = ({ type }: { type: QUESTION_TYPE }) => {
const fields = questionDataList.value.map((item:any) => item.field) const fields = questionDataList.value.map((item: any) => item.field)
const newQuestion = getQuestionByType(type, fields) const newQuestion = getQuestionByType(type, fields)
newQuestion.title = newQuestion.title = `标题${newQuestionIndex.value + 1}` newQuestion.title = newQuestion.title = `标题${newQuestionIndex.value + 1}`
if (type === QUESTION_TYPE.VOTE) { if (type === QUESTION_TYPE.VOTE) {
@ -536,7 +563,6 @@ export const useEditStore = defineStore('edit', () => {
return newQuestion return newQuestion
} }
function changeSchema({ key, value }: { key: string; value: any }) { function changeSchema({ key, value }: { key: string; value: any }) {
_set(schema, key, value) _set(schema, key, value)
updateTime() updateTime()
@ -564,19 +590,19 @@ export const useEditStore = defineStore('edit', () => {
newQuestionIndex, newQuestionIndex,
setCurrentEditOne, setCurrentEditOne,
changeCurrentEditStatus, changeCurrentEditStatus,
pagingEditOne, pageEditOne,
pagingConf, pageConf,
isFinallyPage, isFinallyPage,
pagingCount, pageCount,
pagingQuestionData, pageQuestionData,
getSorter, getSorter,
updatePagingEditOne, updatePageEditOne,
deletePaging, deletePage,
addPaging, addPage,
getPagingQuestionData, getPageQuestionData,
copyPaging, copyPage,
swapArrayRanges, swapArrayRanges,
setPaging, setPage,
schemaUpdateTime, schemaUpdateTime,
schema, schema,
questionDataList, questionDataList,

View File

@ -16,8 +16,16 @@ const surveyStore = useSurveyStore()
const loadData = (res: any, surveyPath: string) => { const loadData = (res: any, surveyPath: string) => {
if (res.code === 200) { if (res.code === 200) {
const data = res.data const data = res.data
const { bannerConf, baseConf, bottomConf, dataConf, skinConf, submitConf, logicConf,pagingConf } = const {
data.code bannerConf,
baseConf,
bottomConf,
dataConf,
skinConf,
submitConf,
logicConf,
pageConf
} = data.code
const questionData = { const questionData = {
bannerConf, bannerConf,
baseConf, baseConf,
@ -25,11 +33,11 @@ const loadData = (res: any, surveyPath: string) => {
dataConf, dataConf,
skinConf, skinConf,
submitConf, submitConf,
pagingConf pageConf
} }
if(!pagingConf || pagingConf?.length == 0){ if (!pageConf || pageConf?.length == 0) {
questionData.pagingConf = [dataConf.dataList.length] questionData.pageConf = [dataConf.dataList.length]
} }
document.title = data.title document.title = data.title

View File

@ -2,9 +2,9 @@
<div class="index"> <div class="index">
<ProgressBar /> <ProgressBar />
<div class="wrapper" ref="boxRef"> <div class="wrapper" ref="boxRef">
<HeaderContent v-if="pagingIndex==1" :bannerConf="bannerConf" :readonly="true" /> <HeaderContent v-if="pageIndex == 1" :bannerConf="bannerConf" :readonly="true" />
<div class="content"> <div class="content">
<MainTitle v-if="pagingIndex==1" :bannerConf="bannerConf" :readonly="true"></MainTitle> <MainTitle v-if="pageIndex == 1" :bannerConf="bannerConf" :readonly="true"></MainTitle>
<MainRenderer ref="mainRef"></MainRenderer> <MainRenderer ref="mainRef"></MainRenderer>
<SubmitButton <SubmitButton
:validate="validate" :validate="validate"
@ -20,114 +20,114 @@
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref } from "vue"; import { computed, ref } from 'vue'
import { storeToRefs } from "pinia"; import { storeToRefs } from 'pinia'
import { useRouter } from "vue-router"; import { useRouter } from 'vue-router'
// @ts-ignore // @ts-ignore
import communalLoader from "@materials/communals/communalLoader.js"; import communalLoader from '@materials/communals/communalLoader.js'
import MainRenderer from "../components/MainRenderer.vue"; import MainRenderer from '../components/MainRenderer.vue'
import AlertDialog from "../components/AlertDialog.vue"; import AlertDialog from '../components/AlertDialog.vue'
import ConfirmDialog from "../components/ConfirmDialog.vue"; import ConfirmDialog from '../components/ConfirmDialog.vue'
import ProgressBar from "../components/ProgressBar.vue"; import ProgressBar from '../components/ProgressBar.vue'
import { useSurveyStore } from "../stores/survey"; import { useSurveyStore } from '../stores/survey'
import { useQuestionStore } from "../stores/question"; import { useQuestionStore } from '../stores/question'
import { submitForm } from "../api/survey"; import { submitForm } from '../api/survey'
import encrypt from "../utils/encrypt"; import encrypt from '../utils/encrypt'
import useCommandComponent from "../hooks/useCommandComponent"; import useCommandComponent from '../hooks/useCommandComponent'
interface Props { interface Props {
questionInfo?: any; questionInfo?: any
isMobile?: boolean; isMobile?: boolean
} }
withDefaults(defineProps<Props>(), { withDefaults(defineProps<Props>(), {
questionInfo: {}, questionInfo: {},
isMobile: false, isMobile: false
}); })
const HeaderContent = communalLoader.loadComponent("HeaderContent"); const HeaderContent = communalLoader.loadComponent('HeaderContent')
const MainTitle = communalLoader.loadComponent("MainTitle"); const MainTitle = communalLoader.loadComponent('MainTitle')
const SubmitButton = communalLoader.loadComponent("SubmitButton"); const SubmitButton = communalLoader.loadComponent('SubmitButton')
const LogoIcon = communalLoader.loadComponent("LogoIcon"); const LogoIcon = communalLoader.loadComponent('LogoIcon')
const mainRef = ref<any>(); const mainRef = ref<any>()
const boxRef = ref<HTMLElement>(); const boxRef = ref<HTMLElement>()
const alert = useCommandComponent(AlertDialog); const alert = useCommandComponent(AlertDialog)
const confirm = useCommandComponent(ConfirmDialog); const confirm = useCommandComponent(ConfirmDialog)
const router = useRouter(); const router = useRouter()
const surveyStore = useSurveyStore(); const surveyStore = useSurveyStore()
const questionStore = useQuestionStore(); const questionStore = useQuestionStore()
const renderData = computed(() => questionStore.renderData) const renderData = computed(() => questionStore.renderData)
const isFinallyPage = computed(() => questionStore.isFinallyPage) const isFinallyPage = computed(() => questionStore.isFinallyPage)
const pagingIndex = computed(() => questionStore.pagingIndex) const pageIndex = computed(() => questionStore.pageIndex)
const { bannerConf, submitConf, bottomConf: logoConf, whiteData } = storeToRefs(surveyStore) const { bannerConf, submitConf, bottomConf: logoConf, whiteData } = storeToRefs(surveyStore)
const surveyPath = computed(() => surveyStore.surveyPath || '') const surveyPath = computed(() => surveyStore.surveyPath || '')
const validate = (cbk: (v: boolean) => void) => { const validate = (cbk: (v: boolean) => void) => {
const index = 0; const index = 0
mainRef.value.$refs.formGroup[index].validate(cbk); mainRef.value.$refs.formGroup[index].validate(cbk)
}; }
const normalizationRequestBody = () => { const normalizationRequestBody = () => {
const enterTime = surveyStore.enterTime; const enterTime = surveyStore.enterTime
const encryptInfo = surveyStore.encryptInfo as any; const encryptInfo = surveyStore.encryptInfo as any
const formValues = surveyStore.formValues; const formValues = surveyStore.formValues
const result: any = { const result: any = {
surveyPath: surveyPath.value, surveyPath: surveyPath.value,
data: JSON.stringify(formValues), data: JSON.stringify(formValues),
diffTime: Date.now() - enterTime, diffTime: Date.now() - enterTime,
clientTime: Date.now(), clientTime: Date.now(),
...whiteData.value, ...whiteData.value
};
if (encryptInfo?.encryptType) {
result.encryptType = encryptInfo.encryptType;
result.data = encrypt[result.encryptType as "rsa"]({
data: result.data,
secretKey: encryptInfo?.data?.secretKey,
});
if (encryptInfo?.data?.sessionId) {
result.sessionId = encryptInfo.data.sessionId;
}
} else {
result.data = JSON.stringify(result.data);
} }
return result; if (encryptInfo?.encryptType) {
}; result.encryptType = encryptInfo.encryptType
result.data = encrypt[result.encryptType as 'rsa']({
data: result.data,
secretKey: encryptInfo?.data?.secretKey
})
if (encryptInfo?.data?.sessionId) {
result.sessionId = encryptInfo.data.sessionId
}
} else {
result.data = JSON.stringify(result.data)
}
return result
}
const submitSurver = async () => { const submitSurver = async () => {
if (surveyPath.value.length > 8) { if (surveyPath.value.length > 8) {
router.push({ name: "successPage" }); router.push({ name: 'successPage' })
return; return
} }
try { try {
const params = normalizationRequestBody(); const params = normalizationRequestBody()
console.log(params); console.log(params)
const res: any = await submitForm(params); const res: any = await submitForm(params)
if (res.code === 200) { if (res.code === 200) {
router.push({ name: "successPage" }); router.push({ name: 'successPage' })
} else { } else {
alert({ alert({
title: res.errmsg || "提交失败", title: res.errmsg || '提交失败'
}); })
} }
} catch (error) { } catch (error) {
console.log(error); console.log(error)
} }
}; }
const handleSubmit = () => { const handleSubmit = () => {
const confirmAgain = (surveyStore.submitConf as any).confirmAgain const confirmAgain = (surveyStore.submitConf as any).confirmAgain
const { again_text, is_again } = confirmAgain const { again_text, is_again } = confirmAgain
if (!isFinallyPage.value) { if (!isFinallyPage.value) {
questionStore.addPagingIndex(); questionStore.addPageIndex()
return return
} }
if (is_again) { if (is_again) {
@ -135,18 +135,18 @@ const handleSubmit = () => {
title: again_text, title: again_text,
onConfirm: async () => { onConfirm: async () => {
try { try {
submitSurver(); submitSurver()
} catch (error) { } catch (error) {
console.log(error); console.log(error)
} finally { } finally {
confirm.close(); confirm.close()
} }
}, }
}); })
} else { } else {
submitSurver(); submitSurver()
} }
}; }
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.index { .index {

View File

@ -10,7 +10,7 @@ export const useQuestionStore = defineStore('question', () => {
const voteMap = ref({}) const voteMap = ref({})
const questionData = ref(null) const questionData = ref(null)
const questionSeq = ref([]) // 题目的顺序,因为可能会有分页的情况,所以是一个二维数组[[qid1, qid2], [qid3,qid4]] const questionSeq = ref([]) // 题目的顺序,因为可能会有分页的情况,所以是一个二维数组[[qid1, qid2], [qid3,qid4]]
const pagingIndex = ref(1) // 当前分页的索引 const pageIndex = ref(1) // 当前分页的索引
// 题目列表 // 题目列表
const questionList = computed(() => { const questionList = computed(() => {
@ -41,36 +41,36 @@ export const useQuestionStore = defineStore('question', () => {
const renderData = computed(() => { const renderData = computed(() => {
const { startIndex, endIndex } = getSorter() const { startIndex, endIndex } = getSorter()
const data = questionList.value[0]; const data = questionList.value[0]
if(!data || !Array.isArray(data) ||data.length === 0) return [] if (!data || !Array.isArray(data) || data.length === 0) return []
return [data.slice(startIndex,endIndex)] return [data.slice(startIndex, endIndex)]
}) })
const isFinallyPage = computed(() => { const isFinallyPage = computed(() => {
const surveyStore = useSurveyStore() const surveyStore = useSurveyStore()
return pagingIndex.value === surveyStore.pagingConf.length; return pageIndex.value === surveyStore.pageConf.length
}) })
const addPagingIndex = () => { const addPageIndex = () => {
pagingIndex.value++ pageIndex.value++
} }
const getSorter = () => { const getSorter = () => {
let startIndex = 0; let startIndex = 0
const surveyStore = useSurveyStore() const surveyStore = useSurveyStore()
const newPagingEditOne = pagingIndex.value; const newPageEditOne = pageIndex.value
const endIndex = surveyStore.pagingConf[newPagingEditOne - 1]; const endIndex = surveyStore.pageConf[newPageEditOne - 1]
for (let index = 0; index < surveyStore.pagingConf.length; index++) { for (let index = 0; index < surveyStore.pageConf.length; index++) {
const item = surveyStore.pagingConf[index]; const item = surveyStore.pageConf[index]
if ((newPagingEditOne - 1) == index) { if (newPageEditOne - 1 == index) {
break; break
} }
startIndex+=item startIndex += item
} }
return { return {
startIndex, startIndex,
endIndex:startIndex + endIndex endIndex: startIndex + endIndex
} }
} }
@ -183,8 +183,8 @@ export const useQuestionStore = defineStore('question', () => {
questionSeq, questionSeq,
renderData, renderData,
isFinallyPage, isFinallyPage,
pagingIndex, pageIndex,
addPagingIndex, addPageIndex,
setQuestionData, setQuestionData,
changeSelectMoreData, changeSelectMoreData,
setQuestionSeq, setQuestionSeq,

View File

@ -38,7 +38,7 @@ export const useSurveyStore = defineStore('survey', () => {
const submitConf = ref({}) const submitConf = ref({})
const formValues = ref({}) const formValues = ref({})
const whiteData = ref({}) const whiteData = ref({})
const pagingConf = ref([]) const pageConf = ref([])
const router = useRouter() const router = useRouter()
const questionStore = useQuestionStore() const questionStore = useQuestionStore()
@ -129,7 +129,7 @@ export const useSurveyStore = defineStore('survey', () => {
'skinConf', 'skinConf',
'submitConf', 'submitConf',
'whiteData', 'whiteData',
"pagingConf" 'pageConf'
]) ])
) )
questionStore.questionData = questionData questionStore.questionData = questionData
@ -145,7 +145,7 @@ export const useSurveyStore = defineStore('survey', () => {
submitConf.value = option.submitConf submitConf.value = option.submitConf
formValues.value = _formValues formValues.value = _formValues
whiteData.value = option.whiteData whiteData.value = option.whiteData
pagingConf.value = option.pagingConf pageConf.value = option.pageConf
// 获取已投票数据 // 获取已投票数据
questionStore.initVoteData() questionStore.initVoteData()
} }
@ -172,7 +172,7 @@ export const useSurveyStore = defineStore('survey', () => {
submitConf, submitConf,
formValues, formValues,
whiteData, whiteData,
pagingConf, pageConf,
initSurvey, initSurvey,
changeData, changeData,