feat: 优化分页器结构
This commit is contained in:
parent
c330e6000d
commit
4a158ae6e8
@ -4,8 +4,12 @@
|
||||
<i-ep-ArrowLeft />
|
||||
</span>
|
||||
<template v-if="!is_more_filled">
|
||||
<div v-for="i in firstPagination" :key="i" :class="['com-pagination-item', `page-${i}`, (now_page == i ? 'current' : '')]"
|
||||
@click="changePage(i)">
|
||||
<div
|
||||
v-for="i in firstPagination"
|
||||
:key="i"
|
||||
:class="['com-pagination-item', `page-${i}`, now_page == i ? 'current' : '']"
|
||||
@click="changePage(i)"
|
||||
>
|
||||
<span>{{ i }}</span>
|
||||
<div v-if="!props.readonly" :class="['moreControls']" @click.stop="showTooltipVisible(i)">
|
||||
<i-ep-MoreFilled />
|
||||
@ -13,8 +17,12 @@
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div v-for="i in more_filled_arr.startArr" @click="changePage(i)" :key="i"
|
||||
:class="['com-pagination-item', ` page-${i}`, (now_page == i ? 'current' : '')]">
|
||||
<div
|
||||
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>
|
||||
<div v-if="!props.readonly" :class="['moreControls']" @click.stop="showTooltipVisible(i)">
|
||||
<i-ep-MoreFilled />
|
||||
@ -26,14 +34,23 @@
|
||||
</span>
|
||||
<template #content>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-tooltip>
|
||||
<div v-for="i in more_filled_arr.endArr" :key="i"
|
||||
:class="['com-pagination-item', `page-${i}`, (now_page == i ? 'current' : '')]" @click="changePage(i)">
|
||||
<div
|
||||
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>
|
||||
<div v-if="!props.readonly" :class="['moreControls']" @click.stop="showTooltipVisible(i)">
|
||||
<i-ep-MoreFilled />
|
||||
@ -43,17 +60,25 @@
|
||||
<span :class="['com-pagination-item', next_class]" @click="changePage(next_page)">
|
||||
<i-ep-ArrowRight />
|
||||
</span>
|
||||
<el-tooltip v-if="slot.tooltip && props.readonly==false" :visible="tooltipVisible" :popper-options="{
|
||||
modifiers: [
|
||||
{
|
||||
name: 'computeStyles',
|
||||
options: {
|
||||
adaptive: false,
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
}" :virtual-ref="triggerBtn" virtual-triggering effect="light" popper-class="singleton-tooltip">
|
||||
<el-tooltip
|
||||
v-if="slot.tooltip && props.readonly == false"
|
||||
:visible="tooltipVisible"
|
||||
:popper-options="{
|
||||
modifiers: [
|
||||
{
|
||||
name: 'computeStyles',
|
||||
options: {
|
||||
adaptive: false,
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
]
|
||||
}"
|
||||
:virtual-ref="triggerBtn"
|
||||
virtual-triggering
|
||||
effect="light"
|
||||
popper-class="singleton-tooltip"
|
||||
>
|
||||
<template #content>
|
||||
<slot name="tooltip" :index="tooltipIndex"></slot>
|
||||
</template>
|
||||
@ -62,78 +87,77 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { clone } from "lodash-es";
|
||||
import { withDefaults, reactive, computed, watch, ref, onMounted, onUnmounted, nextTick, useSlots } from "vue";
|
||||
import { clone } from 'lodash-es'
|
||||
import { reactive, computed, watch, ref, onMounted, onUnmounted, nextTick, useSlots } from 'vue'
|
||||
|
||||
interface Props {
|
||||
modelValue: number // 页码
|
||||
totalPage?: number
|
||||
intervalCount?: number,
|
||||
intervalCount?: number
|
||||
readonly?: boolean
|
||||
}
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
modelValue: 1,
|
||||
totalPage: 1,
|
||||
intervalCount: 8,
|
||||
readonly:false
|
||||
});
|
||||
const emit = defineEmits(['change-page', 'update:modelValue']);
|
||||
readonly: false
|
||||
})
|
||||
const emit = defineEmits(['change-page', 'update:modelValue'])
|
||||
|
||||
const state = reactive({
|
||||
now: props.modelValue,
|
||||
jump: ''
|
||||
});
|
||||
})
|
||||
|
||||
const slot = useSlots();
|
||||
const slot = useSlots()
|
||||
|
||||
const moreVisible = ref(false)
|
||||
const tooltipVisible = ref(false)
|
||||
const triggerBtn = ref<EventTarget | null>(null);
|
||||
const triggerBtn = ref<EventTarget | null>(null)
|
||||
const tooltipIndex = ref(0)
|
||||
|
||||
const now_page = computed(() => {
|
||||
return state.now * 1;
|
||||
});
|
||||
return state.now * 1
|
||||
})
|
||||
const prev_class = computed(() => {
|
||||
return now_page.value == 1 ? 'disabled' : '';
|
||||
});
|
||||
return now_page.value == 1 ? 'disabled' : ''
|
||||
})
|
||||
const next_class = computed(() => {
|
||||
return now_page.value == props.totalPage ? 'disabled' : '';
|
||||
});
|
||||
return now_page.value == props.totalPage ? 'disabled' : ''
|
||||
})
|
||||
const prev_page = computed(() => {
|
||||
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;
|
||||
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 totalArr = computed(() => {
|
||||
const arr = [];
|
||||
const arr = []
|
||||
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(() => {
|
||||
let startArr = [];
|
||||
let bubbleArr = [];
|
||||
let endArr = [];
|
||||
const arr = clone(totalArr.value);
|
||||
const intervalNum = Math.round(props.intervalCount/2)
|
||||
startArr = arr.slice(now_page.value - 1, intervalNum+now_page.value - 1);
|
||||
endArr = arr.slice(intervalNum*-1)
|
||||
bubbleArr = arr.slice(startArr[startArr.length-1], endArr[0]-1);
|
||||
let startArr = []
|
||||
let bubbleArr = []
|
||||
let endArr = []
|
||||
const arr = clone(totalArr.value)
|
||||
const intervalNum = Math.round(props.intervalCount / 2)
|
||||
startArr = arr.slice(now_page.value - 1, intervalNum + now_page.value - 1)
|
||||
endArr = arr.slice(intervalNum * -1)
|
||||
bubbleArr = arr.slice(startArr[startArr.length - 1], endArr[0] - 1)
|
||||
return {
|
||||
startArr,
|
||||
bubbleArr,
|
||||
@ -142,32 +166,32 @@ const more_filled_arr = computed(() => {
|
||||
})
|
||||
|
||||
const firstPagination = computed(() => {
|
||||
const arr = clone(totalArr.value);
|
||||
return arr.splice(props.intervalCount * -1);
|
||||
const arr = clone(totalArr.value)
|
||||
return arr.splice(props.intervalCount * -1)
|
||||
})
|
||||
|
||||
const changePage = (page: number) => {
|
||||
state.now = page;
|
||||
emit('update:modelValue', state.now);
|
||||
emit('change-page', state.now);
|
||||
};
|
||||
state.now = page
|
||||
emit('update:modelValue', state.now)
|
||||
emit('change-page', state.now)
|
||||
}
|
||||
|
||||
const showTooltipVisible = (index:number) => {
|
||||
const showTooltipVisible = (index: number) => {
|
||||
if (slot.tooltip) {
|
||||
nextTick(() => {
|
||||
tooltipIndex.value = index;
|
||||
triggerBtn.value = document.getElementsByClassName(`page-${index}`)[0] || null;
|
||||
tooltipVisible.value = true;
|
||||
tooltipIndex.value = index
|
||||
triggerBtn.value = document.getElementsByClassName(`page-${index}`)[0] || null
|
||||
tooltipVisible.value = true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const hideMoreVisible = () => {
|
||||
moreVisible.value = false;
|
||||
moreVisible.value = false
|
||||
}
|
||||
|
||||
const hideTooltipVisible = () => {
|
||||
tooltipVisible.value = false;
|
||||
tooltipVisible.value = false
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
@ -175,20 +199,21 @@ onMounted(() => {
|
||||
if (slot.tooltip) {
|
||||
document.addEventListener('click', hideTooltipVisible)
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
document.removeEventListener('click', hideMoreVisible)
|
||||
if (slot.tooltip) {
|
||||
document.removeEventListener('click', hideTooltipVisible)
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
watch(() => props.modelValue, () => {
|
||||
state.now = props.modelValue;
|
||||
});
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
() => {
|
||||
state.now = props.modelValue
|
||||
}
|
||||
)
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.bubble-wrap {
|
||||
@ -212,13 +237,13 @@ watch(() => props.modelValue, () => {
|
||||
align-items: center;
|
||||
font-size: 0;
|
||||
user-select: none;
|
||||
.moreControls{
|
||||
color:#6E707C;
|
||||
.moreControls {
|
||||
color: #6e707c;
|
||||
display: none;
|
||||
|
||||
position: absolute;
|
||||
left:22px;
|
||||
svg{
|
||||
left: 22px;
|
||||
svg {
|
||||
transform: rotate(90deg);
|
||||
font-size: 10px;
|
||||
}
|
||||
@ -240,14 +265,14 @@ watch(() => props.modelValue, () => {
|
||||
|
||||
&:hover {
|
||||
color: $primary-color;
|
||||
.moreControls{
|
||||
.moreControls {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: $primary-color;
|
||||
.moreControls{
|
||||
.moreControls {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
@ -267,9 +292,9 @@ watch(() => props.modelValue, () => {
|
||||
|
||||
.disabled,
|
||||
.disabled:hover {
|
||||
svg{
|
||||
svg {
|
||||
cursor: not-allowed;
|
||||
color:#303133 !important;
|
||||
color: #303133 !important;
|
||||
}
|
||||
}
|
||||
|
||||
@ -277,6 +302,5 @@ watch(() => props.modelValue, () => {
|
||||
.current:hover {
|
||||
color: $primary-color;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
</style>
|
@ -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>
|
@ -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>
|
@ -10,7 +10,7 @@ export default function (schema) {
|
||||
'skinConf',
|
||||
'submitConf',
|
||||
'questionDataList',
|
||||
"pagingConf",
|
||||
'pageConf',
|
||||
'logicConf'
|
||||
])
|
||||
configData.dataConf = {
|
||||
|
@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<div class="main-operation" @click="onMainClick" ref="mainOperation">
|
||||
<div class="pagination-wrapper">
|
||||
<PagingWrapper :readonly="false"/>
|
||||
<PageWrapper :readonly="false" />
|
||||
</div>
|
||||
<div class="operation-wrapper" ref="operationWrapper">
|
||||
<div class="box content" ref="box">
|
||||
<MainTitle
|
||||
v-if="pagingEditOne==1"
|
||||
v-if="pageEditOne == 1"
|
||||
:bannerConf="bannerConf"
|
||||
:readonly="false"
|
||||
:is-selected="currentEditOne === 'mainTitle'"
|
||||
@ -15,7 +15,7 @@
|
||||
/>
|
||||
<MaterialGroup
|
||||
:current-edit-one="parseInt(currentEditOne)"
|
||||
:questionDataList="pagingQuestionData"
|
||||
:questionDataList="pageQuestionData"
|
||||
@select="setCurrentEditOne"
|
||||
@change="handleChange"
|
||||
@changeSeq="onQuestionOperation"
|
||||
@ -37,7 +37,7 @@
|
||||
<script setup>
|
||||
import { ref, watch, toRefs } from 'vue'
|
||||
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 { storeToRefs } from 'pinia'
|
||||
import { useEditStore } from '@/management/stores/edit'
|
||||
@ -46,7 +46,8 @@ const MainTitle = communalLoader.loadComponent('MainTitle')
|
||||
const SubmitButton = communalLoader.loadComponent('SubmitButton')
|
||||
|
||||
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 } =
|
||||
editStore
|
||||
const mainOperation = ref(null)
|
||||
@ -54,7 +55,6 @@ const materialGroup = ref(null)
|
||||
|
||||
const { bannerConf, submitConf, skinConf } = toRefs(schema)
|
||||
|
||||
|
||||
// const autoScrollData = computed(() => {
|
||||
// return {
|
||||
// currentEditOne: currentEditOne.value,
|
||||
@ -146,13 +146,13 @@ watch(
|
||||
align-items: center;
|
||||
background-color: #f6f7f9;
|
||||
}
|
||||
.pagination-wrapper{
|
||||
width: 90%;
|
||||
padding-right: 30px;
|
||||
margin-right: -30px;
|
||||
position: relative;
|
||||
top: 50px;
|
||||
}
|
||||
.pagination-wrapper {
|
||||
width: 90%;
|
||||
padding-right: 30px;
|
||||
margin-right: -30px;
|
||||
position: relative;
|
||||
top: 50px;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
width: 100%;
|
||||
|
@ -2,20 +2,28 @@
|
||||
<div class="question-catalog-wrapper">
|
||||
<el-collapse>
|
||||
<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"
|
||||
host-class="catalog-item-ghost">
|
||||
<draggable
|
||||
v-model="renderData[i]"
|
||||
itemKey="field"
|
||||
:group="QUESTION_CATALOG"
|
||||
handle=".draggHandle"
|
||||
host-class="catalog-item-ghost"
|
||||
>
|
||||
<template #item="{ element }">
|
||||
<CatalogItem :title="element.title" :indexNumber="element.indexNumber" :showIndex="element.showIndex"
|
||||
@select="setPagingOneEdit(element.qIndex, i + 1)" />
|
||||
<CatalogItem
|
||||
:title="element.title"
|
||||
:indexNumber="element.indexNumber"
|
||||
:showIndex="element.showIndex"
|
||||
@select="setPageOneEdit(element.qIndex, i + 1)"
|
||||
/>
|
||||
</template>
|
||||
</draggable>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { watch, ref } from 'vue'
|
||||
import { watch, ref } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useEditStore } from '@/management/stores/edit'
|
||||
import draggable from 'vuedraggable'
|
||||
@ -24,43 +32,48 @@ import CatalogItem from './CatalogItem.vue'
|
||||
import { QUESTION_CATALOG } from '@/management/config/dnd'
|
||||
|
||||
const editStore = useEditStore()
|
||||
const { questionDataList, pagingConf } = storeToRefs(editStore)
|
||||
const { setCurrentEditOne, getPagingQuestionData, updatePagingEditOne,setPaging,compareQuestionSeq } = editStore
|
||||
const { questionDataList, pageConf } = storeToRefs(editStore)
|
||||
const { setCurrentEditOne, getPageQuestionData, updatePageEditOne, setPage, compareQuestionSeq } =
|
||||
editStore
|
||||
|
||||
const renderData: any = ref([])
|
||||
|
||||
const setPagingOneEdit = (qIndex: number, pagingIndex: number) => {
|
||||
updatePagingEditOne(pagingIndex)
|
||||
const setPageOneEdit = (qIndex: number, pageIndex: number) => {
|
||||
updatePageEditOne(pageIndex)
|
||||
setCurrentEditOne(qIndex)
|
||||
}
|
||||
|
||||
|
||||
watch(() => [pagingConf.value,questionDataList.value], () => {
|
||||
renderData.value = [];
|
||||
for (let index = 0; index < pagingConf.value.length; index++) {
|
||||
renderData.value.push(getPagingQuestionData(index + 1))
|
||||
watch(
|
||||
() => [pageConf.value, questionDataList.value],
|
||||
() => {
|
||||
renderData.value = []
|
||||
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>
|
||||
<style lang="scss" scoped>
|
||||
.question-catalog-wrapper {
|
||||
@ -86,7 +99,7 @@ watch(() => renderData.value, (newVal) => {
|
||||
|
||||
:deep(.el-collapse-item__header) {
|
||||
font-size: 14px;
|
||||
color: #6E707C;
|
||||
color: #6e707c;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
|
@ -1,18 +1,32 @@
|
||||
<template>
|
||||
<div class="main-operation">
|
||||
<div class="pagination-wrapper">
|
||||
<PagingWrapper :readonly="true" />
|
||||
<PageWrapper :readonly="true" />
|
||||
</div>
|
||||
<div class="operation-wrapper">
|
||||
<div class="box" ref="box">
|
||||
<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">
|
||||
<MainTitle v-if="pagingEditOne==1" :isSelected="false" :bannerConf="bannerConf" :readonly="false" />
|
||||
<MaterialGroup :questionDataList="pagingQuestionData" 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'" />
|
||||
<MainTitle
|
||||
v-if="pageEditOne == 1"
|
||||
:isSelected="false"
|
||||
:bannerConf="bannerConf"
|
||||
: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>
|
||||
@ -21,7 +35,7 @@
|
||||
<script>
|
||||
import { defineComponent, toRefs } from '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 { useEditStore } from '@/management/stores/edit'
|
||||
import communalLoader from '@materials/communals/communalLoader.js'
|
||||
@ -34,7 +48,7 @@ const LogoIcon = () => communalLoader.loadComponent('LogoIcon')
|
||||
export default defineComponent({
|
||||
components: {
|
||||
MaterialGroup,
|
||||
PagingWrapper,
|
||||
PageWrapper,
|
||||
HeaderContent: HeaderContent(),
|
||||
MainTitle: MainTitle(),
|
||||
SubmitButton: SubmitButton(),
|
||||
@ -42,7 +56,8 @@ export default defineComponent({
|
||||
},
|
||||
setup() {
|
||||
const editStore = useEditStore()
|
||||
const { pagingQuestionData, currentEditOne, currentEditKey,isFinallyPage,pagingEditOne } = storeToRefs(editStore)
|
||||
const { pageQuestionData, currentEditOne, currentEditKey, isFinallyPage, pageEditOne } =
|
||||
storeToRefs(editStore)
|
||||
const { schema } = editStore
|
||||
const { bannerConf, submitConf, skinConf, bottomConf } = toRefs(schema)
|
||||
|
||||
@ -51,11 +66,11 @@ export default defineComponent({
|
||||
submitConf,
|
||||
bottomConf,
|
||||
skinConf,
|
||||
pagingQuestionData,
|
||||
pageQuestionData,
|
||||
currentEditOne,
|
||||
currentEditKey,
|
||||
isFinallyPage,
|
||||
pagingEditOne
|
||||
pageEditOne
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@ -1,6 +1,11 @@
|
||||
import { type Ref, ref, reactive, toRef, computed } from 'vue'
|
||||
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 { getQuestionByType } from '@/management/utils/index'
|
||||
import { filterQuestionPreviewData } from '@/management/utils/index'
|
||||
@ -74,10 +79,10 @@ function useInitializeSchema(surveyId: Ref<string>) {
|
||||
link: ''
|
||||
},
|
||||
questionDataList: [],
|
||||
pagingEditOne: 1,
|
||||
pagingConf:[], // 分页逻辑
|
||||
pageEditOne: 1,
|
||||
pageConf: [], // 分页逻辑
|
||||
logicConf: {
|
||||
showLogicConf: [],
|
||||
showLogicConf: []
|
||||
}
|
||||
})
|
||||
|
||||
@ -89,9 +94,9 @@ function useInitializeSchema(surveyId: Ref<string>) {
|
||||
schema.baseConf = _merge({}, schema.baseConf, codeData.baseConf)
|
||||
schema.submitConf = _merge({}, schema.submitConf, codeData.submitConf)
|
||||
schema.questionDataList = codeData.questionDataList || []
|
||||
schema.logicConf = codeData.logicConf;
|
||||
schema.pagingEditOne = 1;
|
||||
schema.pagingConf = codeData.pagingConf;
|
||||
schema.logicConf = codeData.logicConf
|
||||
schema.pageEditOne = 1
|
||||
schema.pageConf = codeData.pageConf
|
||||
}
|
||||
|
||||
async function getSchemaFromRemote() {
|
||||
@ -101,16 +106,16 @@ function useInitializeSchema(surveyId: Ref<string>) {
|
||||
document.title = metaData.title
|
||||
const data = res.data.surveyConfRes.code
|
||||
const {
|
||||
bannerConf,
|
||||
bottomConf,
|
||||
skinConf,
|
||||
baseConf,
|
||||
submitConf,
|
||||
dataConf,
|
||||
logicConf = {}
|
||||
} = data
|
||||
if (!data.pagingConf || data.pagingConf.length === 0) {
|
||||
data.pagingConf = [dataConf.dataList.length]
|
||||
bannerConf,
|
||||
bottomConf,
|
||||
skinConf,
|
||||
baseConf,
|
||||
submitConf,
|
||||
dataConf,
|
||||
logicConf = {}
|
||||
} = data
|
||||
if (!data.pageConf || data.pageConf.length === 0) {
|
||||
data.pageConf = [dataConf.dataList.length]
|
||||
}
|
||||
initSchema({
|
||||
metaData,
|
||||
@ -121,7 +126,7 @@ function useInitializeSchema(surveyId: Ref<string>) {
|
||||
baseConf,
|
||||
submitConf,
|
||||
questionDataList: dataConf.dataList,
|
||||
pagingConf: data.pagingConf,
|
||||
pageConf: data.pageConf,
|
||||
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 }) {
|
||||
const newQuestion = _cloneDeep(questionDataList.value[index])
|
||||
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 }) {
|
||||
questionDataList.value.splice(index, 0, question)
|
||||
pagingOperations('add')
|
||||
pageOperations('add')
|
||||
updateTime()
|
||||
}
|
||||
|
||||
function deleteQuestion({ index }: { index: number }) {
|
||||
pagingOperations('remove')
|
||||
pageOperations('remove')
|
||||
questionDataList.value.splice(index, 1)
|
||||
updateTime()
|
||||
}
|
||||
@ -280,139 +289,138 @@ function useCurrentEdit({
|
||||
changeCurrentEditStatus
|
||||
}
|
||||
}
|
||||
function usePagingEdit({
|
||||
schema,
|
||||
questionDataList
|
||||
}: {
|
||||
schema: any,
|
||||
function usePageEdit(
|
||||
{
|
||||
schema,
|
||||
questionDataList
|
||||
}: {
|
||||
schema: any
|
||||
questionDataList: Ref<any[]>
|
||||
},updateTime: () => void) {
|
||||
const pagingConf = computed(() => schema.pagingConf)
|
||||
const pagingEditOne = computed(() => schema.pagingEditOne)
|
||||
const isFinallyPage = computed(() => {
|
||||
return pagingEditOne.value === pagingConf.value.length;
|
||||
},
|
||||
updateTime: () => void
|
||||
) {
|
||||
const pageConf = computed(() => schema.pageConf)
|
||||
const pageEditOne = computed(() => schema.pageEditOne)
|
||||
const isFinallyPage = computed(() => {
|
||||
return pageEditOne.value === pageConf.value.length
|
||||
})
|
||||
const pagingCount = computed(() => pagingConf.value.length || 0)
|
||||
const pageCount = computed(() => pageConf.value.length || 0)
|
||||
|
||||
const pagingQuestionData = computed(() => {
|
||||
return getPagingQuestionData(pagingEditOne.value)
|
||||
const pageQuestionData = computed(() => {
|
||||
return getPageQuestionData(pageEditOne.value)
|
||||
})
|
||||
|
||||
const getPagingQuestionData = (index:number) => {
|
||||
const getPageQuestionData = (index: number) => {
|
||||
const { startIndex, endIndex } = getSorter(index)
|
||||
return filterQuestionPreviewData(questionDataList.value).slice(startIndex,endIndex)
|
||||
return filterQuestionPreviewData(questionDataList.value).slice(startIndex, endIndex)
|
||||
}
|
||||
|
||||
const getSorter = (index?:number) => {
|
||||
let startIndex = 0;
|
||||
const newPagingEditOne = index || pagingEditOne.value;
|
||||
const endIndex = pagingConf.value[newPagingEditOne - 1];
|
||||
const getSorter = (index?: number) => {
|
||||
let startIndex = 0
|
||||
const newPageEditOne = index || pageEditOne.value
|
||||
const endIndex = pageConf.value[newPageEditOne - 1]
|
||||
|
||||
for (let index = 0; index < pagingConf.value.length; index++) {
|
||||
const item = pagingConf.value[index];
|
||||
if ((newPagingEditOne - 1) == index) {
|
||||
break;
|
||||
for (let index = 0; index < pageConf.value.length; index++) {
|
||||
const item = pageConf.value[index]
|
||||
if (newPageEditOne - 1 == index) {
|
||||
break
|
||||
}
|
||||
startIndex+=item
|
||||
startIndex += item
|
||||
}
|
||||
return {
|
||||
startIndex,
|
||||
endIndex:startIndex + endIndex
|
||||
endIndex: startIndex + endIndex
|
||||
}
|
||||
}
|
||||
|
||||
const addPaging = () => {
|
||||
schema.pagingConf.push(1)
|
||||
const addPage = () => {
|
||||
schema.pageConf.push(1)
|
||||
}
|
||||
|
||||
const updatePagingEditOne = (index: number) => {
|
||||
schema.pagingEditOne = index;
|
||||
const updatePageEditOne = (index: number) => {
|
||||
schema.pageEditOne = index
|
||||
}
|
||||
|
||||
const deletePaging = (index: number) => {
|
||||
if (pagingConf.value.length <= 1) return
|
||||
const deletePage = (index: number) => {
|
||||
if (pageConf.value.length <= 1) return
|
||||
const { startIndex, endIndex } = getSorter(index)
|
||||
const newQuestion = _cloneDeep(questionDataList.value)
|
||||
newQuestion.splice(startIndex, endIndex-startIndex)
|
||||
updatePagingEditOne(1);
|
||||
schema.pagingConf.splice(index-1, 1)
|
||||
newQuestion.splice(startIndex, endIndex - startIndex)
|
||||
updatePageEditOne(1)
|
||||
schema.pageConf.splice(index - 1, 1)
|
||||
questionDataList.value = newQuestion
|
||||
updateTime();
|
||||
updateTime()
|
||||
}
|
||||
|
||||
const swapArrayRanges = (index:number,range:number) => {
|
||||
const { startIndex:start1,endIndex:end1 } = getSorter(index)
|
||||
const { startIndex:start2,endIndex:end2 } = getSorter(range)
|
||||
const swapArrayRanges = (index: number, range: number) => {
|
||||
const { startIndex: start1, endIndex: end1 } = getSorter(index)
|
||||
const { startIndex: start2, endIndex: end2 } = getSorter(range)
|
||||
const newQuestion = _cloneDeep(questionDataList.value)
|
||||
const range1 = newQuestion.slice(start1, end1);
|
||||
const range2 = newQuestion.slice(start2, end2 );
|
||||
newQuestion.splice(start1, range1.length, ...range2);
|
||||
newQuestion.splice(start2, range2.length, ...range1);
|
||||
const range1 = newQuestion.slice(start1, end1)
|
||||
const range2 = newQuestion.slice(start2, end2)
|
||||
newQuestion.splice(start1, range1.length, ...range2)
|
||||
newQuestion.splice(start2, range2.length, ...range1)
|
||||
questionDataList.value = newQuestion
|
||||
const rangeCount = schema.pagingConf[range-1]
|
||||
schema.pagingConf[range-1] = schema.pagingConf[index-1]
|
||||
schema.pagingConf[index - 1] = rangeCount;
|
||||
updateTime();
|
||||
const rangeCount = schema.pageConf[range - 1]
|
||||
schema.pageConf[range - 1] = schema.pageConf[index - 1]
|
||||
schema.pageConf[index - 1] = rangeCount
|
||||
updateTime()
|
||||
}
|
||||
|
||||
const copyPaging = (index: number) => {
|
||||
|
||||
const newQuestionList = _cloneDeep(getPagingQuestionData(index))
|
||||
newQuestionList.forEach((item) => {
|
||||
const copyPage = (index: number) => {
|
||||
const newQuestionList = _cloneDeep(getPageQuestionData(index))
|
||||
newQuestionList.forEach((item) => {
|
||||
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)
|
||||
questionDataList.value.splice(endIndex, 0, ...newQuestionList)
|
||||
updateTime();
|
||||
updateTime()
|
||||
}
|
||||
|
||||
const pagingOperations = (type:string) => {
|
||||
const count = pagingConf.value[pagingEditOne.value - 1];
|
||||
const pageOperations = (type: string) => {
|
||||
const count = pageConf.value[pageEditOne.value - 1]
|
||||
if (type == 'add') {
|
||||
if (count!=undefined) {
|
||||
schema.pagingConf[pagingEditOne.value - 1] = count + 1; ;
|
||||
if (count != undefined) {
|
||||
schema.pageConf[pageEditOne.value - 1] = count + 1
|
||||
}
|
||||
return
|
||||
}
|
||||
if (type == 'remove') {
|
||||
if (count) {
|
||||
schema.pagingConf[pagingEditOne.value - 1] = count - 1;
|
||||
if (count) {
|
||||
schema.pageConf[pageEditOne.value - 1] = count - 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const setPaging = (data: Array<number>) => {
|
||||
for (let index = 0; index < pagingConf.value.length; index++) {
|
||||
const newIndex = data[index];
|
||||
const oldIndex = pagingConf.value[index];
|
||||
const setPage = (data: Array<number>) => {
|
||||
for (let index = 0; index < pageConf.value.length; index++) {
|
||||
const newIndex = data[index]
|
||||
const oldIndex = pageConf.value[index]
|
||||
if (newIndex != oldIndex) {
|
||||
schema.pagingConf[index] = newIndex;
|
||||
schema.pageConf[index] = newIndex
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
pagingEditOne,
|
||||
pagingConf,
|
||||
pageEditOne,
|
||||
pageConf,
|
||||
isFinallyPage,
|
||||
pagingCount,
|
||||
pagingQuestionData,
|
||||
pageCount,
|
||||
pageQuestionData,
|
||||
getSorter,
|
||||
updatePagingEditOne,
|
||||
deletePaging,
|
||||
addPaging,
|
||||
copyPaging,
|
||||
getPagingQuestionData,
|
||||
pagingOperations,
|
||||
updatePageEditOne,
|
||||
deletePage,
|
||||
addPage,
|
||||
copyPage,
|
||||
getPageQuestionData,
|
||||
pageOperations,
|
||||
swapArrayRanges,
|
||||
setPaging
|
||||
setPage
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
type IBannerItem = {
|
||||
name: string
|
||||
key: string
|
||||
@ -471,63 +479,82 @@ export const useEditStore = defineStore('edit', () => {
|
||||
schemaUpdateTime.value = Date.now()
|
||||
}
|
||||
|
||||
const { pagingEditOne, pagingConf, isFinallyPage, pagingCount, pagingQuestionData, getSorter,
|
||||
updatePagingEditOne, deletePaging,pagingOperations,addPaging,getPagingQuestionData,copyPaging,swapArrayRanges,setPaging }= usePagingEdit({ schema, questionDataList },updateTime)
|
||||
const {
|
||||
pageEditOne,
|
||||
pageConf,
|
||||
isFinallyPage,
|
||||
pageCount,
|
||||
pageQuestionData,
|
||||
getSorter,
|
||||
updatePageEditOne,
|
||||
deletePage,
|
||||
pageOperations,
|
||||
addPage,
|
||||
getPageQuestionData,
|
||||
copyPage,
|
||||
swapArrayRanges,
|
||||
setPage
|
||||
} = usePageEdit({ schema, questionDataList }, updateTime)
|
||||
|
||||
const { copyQuestion, addQuestion, deleteQuestion, moveQuestion} = useQuestionDataListOperations(
|
||||
questionDataList,
|
||||
updateTime,
|
||||
pagingOperations
|
||||
const { copyQuestion, addQuestion, deleteQuestion, moveQuestion } = useQuestionDataListOperations(
|
||||
questionDataList,
|
||||
updateTime,
|
||||
pageOperations
|
||||
)
|
||||
|
||||
|
||||
function moveQuestionDataList(data: any) {
|
||||
const { startIndex, endIndex } = getSorter()
|
||||
const newData = [...questionDataList.value.slice(0, startIndex), ...data, ...questionDataList.value.slice(endIndex)];
|
||||
const countTotal:number = (schema.pagingConf as Array<number>).reduce((v:number, i:number) => v + i)
|
||||
const newData = [
|
||||
...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) {
|
||||
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)
|
||||
}
|
||||
|
||||
const compareQuestionSeq = (val:Array<any>) => {
|
||||
const newSeq: Array<string> = [];
|
||||
const oldSeq: Array<string> = [];
|
||||
let status = false;
|
||||
val.map(v => {
|
||||
const compareQuestionSeq = (val: Array<any>) => {
|
||||
const newSeq: Array<string> = []
|
||||
const oldSeq: Array<string> = []
|
||||
let status = false
|
||||
val.map((v) => {
|
||||
newSeq.push(v.field)
|
||||
});
|
||||
(questionDataList.value as Array<any>).map(v => {
|
||||
})
|
||||
;(questionDataList.value as Array<any>).map((v) => {
|
||||
oldSeq.push(v.field)
|
||||
})
|
||||
for (let index = 0; index < newSeq.length; index++) {
|
||||
if (newSeq[index] !== oldSeq[index]) {
|
||||
status = true;
|
||||
break;
|
||||
status = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (status) {
|
||||
setQuestionDataList(val);
|
||||
setQuestionDataList(val)
|
||||
}
|
||||
}
|
||||
|
||||
const newQuestionIndex = computed(() => {
|
||||
if (_isNumber(currentEditOne.value)) {
|
||||
return currentEditOne.value + 1
|
||||
return currentEditOne.value + 1
|
||||
} else {
|
||||
const pagingConf = schema.pagingConf
|
||||
const questCount = pagingConf[schema.pagingEditOne - 1];
|
||||
const { startIndex,endIndex } = getSorter();
|
||||
const pageConf = schema.pageConf
|
||||
const questCount = pageConf[schema.pageEditOne - 1]
|
||||
const { startIndex, endIndex } = getSorter()
|
||||
if (!questCount) {
|
||||
return startIndex
|
||||
}
|
||||
return endIndex
|
||||
}
|
||||
})
|
||||
|
||||
const createNewQuestion = ({type}:{type:QUESTION_TYPE}) => {
|
||||
const fields = questionDataList.value.map((item:any) => item.field)
|
||||
|
||||
const createNewQuestion = ({ type }: { type: QUESTION_TYPE }) => {
|
||||
const fields = questionDataList.value.map((item: any) => item.field)
|
||||
const newQuestion = getQuestionByType(type, fields)
|
||||
newQuestion.title = newQuestion.title = `标题${newQuestionIndex.value + 1}`
|
||||
if (type === QUESTION_TYPE.VOTE) {
|
||||
@ -536,7 +563,6 @@ export const useEditStore = defineStore('edit', () => {
|
||||
return newQuestion
|
||||
}
|
||||
|
||||
|
||||
function changeSchema({ key, value }: { key: string; value: any }) {
|
||||
_set(schema, key, value)
|
||||
updateTime()
|
||||
@ -564,19 +590,19 @@ export const useEditStore = defineStore('edit', () => {
|
||||
newQuestionIndex,
|
||||
setCurrentEditOne,
|
||||
changeCurrentEditStatus,
|
||||
pagingEditOne,
|
||||
pagingConf,
|
||||
pageEditOne,
|
||||
pageConf,
|
||||
isFinallyPage,
|
||||
pagingCount,
|
||||
pagingQuestionData,
|
||||
pageCount,
|
||||
pageQuestionData,
|
||||
getSorter,
|
||||
updatePagingEditOne,
|
||||
deletePaging,
|
||||
addPaging,
|
||||
getPagingQuestionData,
|
||||
copyPaging,
|
||||
updatePageEditOne,
|
||||
deletePage,
|
||||
addPage,
|
||||
getPageQuestionData,
|
||||
copyPage,
|
||||
swapArrayRanges,
|
||||
setPaging,
|
||||
setPage,
|
||||
schemaUpdateTime,
|
||||
schema,
|
||||
questionDataList,
|
||||
|
@ -16,8 +16,16 @@ const surveyStore = useSurveyStore()
|
||||
const loadData = (res: any, surveyPath: string) => {
|
||||
if (res.code === 200) {
|
||||
const data = res.data
|
||||
const { bannerConf, baseConf, bottomConf, dataConf, skinConf, submitConf, logicConf,pagingConf } =
|
||||
data.code
|
||||
const {
|
||||
bannerConf,
|
||||
baseConf,
|
||||
bottomConf,
|
||||
dataConf,
|
||||
skinConf,
|
||||
submitConf,
|
||||
logicConf,
|
||||
pageConf
|
||||
} = data.code
|
||||
const questionData = {
|
||||
bannerConf,
|
||||
baseConf,
|
||||
@ -25,11 +33,11 @@ const loadData = (res: any, surveyPath: string) => {
|
||||
dataConf,
|
||||
skinConf,
|
||||
submitConf,
|
||||
pagingConf
|
||||
pageConf
|
||||
}
|
||||
|
||||
if(!pagingConf || pagingConf?.length == 0){
|
||||
questionData.pagingConf = [dataConf.dataList.length]
|
||||
if (!pageConf || pageConf?.length == 0) {
|
||||
questionData.pageConf = [dataConf.dataList.length]
|
||||
}
|
||||
|
||||
document.title = data.title
|
||||
|
@ -2,9 +2,9 @@
|
||||
<div class="index">
|
||||
<ProgressBar />
|
||||
<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">
|
||||
<MainTitle v-if="pagingIndex==1" :bannerConf="bannerConf" :readonly="true"></MainTitle>
|
||||
<MainTitle v-if="pageIndex == 1" :bannerConf="bannerConf" :readonly="true"></MainTitle>
|
||||
<MainRenderer ref="mainRef"></MainRenderer>
|
||||
<SubmitButton
|
||||
:validate="validate"
|
||||
@ -20,114 +20,114 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from "vue";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { useRouter } from "vue-router";
|
||||
import { computed, ref } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useRouter } from 'vue-router'
|
||||
// @ts-ignore
|
||||
import communalLoader from "@materials/communals/communalLoader.js";
|
||||
import MainRenderer from "../components/MainRenderer.vue";
|
||||
import AlertDialog from "../components/AlertDialog.vue";
|
||||
import ConfirmDialog from "../components/ConfirmDialog.vue";
|
||||
import ProgressBar from "../components/ProgressBar.vue";
|
||||
import communalLoader from '@materials/communals/communalLoader.js'
|
||||
import MainRenderer from '../components/MainRenderer.vue'
|
||||
import AlertDialog from '../components/AlertDialog.vue'
|
||||
import ConfirmDialog from '../components/ConfirmDialog.vue'
|
||||
import ProgressBar from '../components/ProgressBar.vue'
|
||||
|
||||
import { useSurveyStore } from "../stores/survey";
|
||||
import { useQuestionStore } from "../stores/question";
|
||||
import { submitForm } from "../api/survey";
|
||||
import encrypt from "../utils/encrypt";
|
||||
import { useSurveyStore } from '../stores/survey'
|
||||
import { useQuestionStore } from '../stores/question'
|
||||
import { submitForm } from '../api/survey'
|
||||
import encrypt from '../utils/encrypt'
|
||||
|
||||
import useCommandComponent from "../hooks/useCommandComponent";
|
||||
import useCommandComponent from '../hooks/useCommandComponent'
|
||||
|
||||
interface Props {
|
||||
questionInfo?: any;
|
||||
isMobile?: boolean;
|
||||
questionInfo?: any
|
||||
isMobile?: boolean
|
||||
}
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
questionInfo: {},
|
||||
isMobile: false,
|
||||
});
|
||||
isMobile: false
|
||||
})
|
||||
|
||||
const HeaderContent = communalLoader.loadComponent("HeaderContent");
|
||||
const MainTitle = communalLoader.loadComponent("MainTitle");
|
||||
const SubmitButton = communalLoader.loadComponent("SubmitButton");
|
||||
const LogoIcon = communalLoader.loadComponent("LogoIcon");
|
||||
const HeaderContent = communalLoader.loadComponent('HeaderContent')
|
||||
const MainTitle = communalLoader.loadComponent('MainTitle')
|
||||
const SubmitButton = communalLoader.loadComponent('SubmitButton')
|
||||
const LogoIcon = communalLoader.loadComponent('LogoIcon')
|
||||
|
||||
const mainRef = ref<any>();
|
||||
const boxRef = ref<HTMLElement>();
|
||||
const mainRef = ref<any>()
|
||||
const boxRef = ref<HTMLElement>()
|
||||
|
||||
const alert = useCommandComponent(AlertDialog);
|
||||
const confirm = useCommandComponent(ConfirmDialog);
|
||||
const alert = useCommandComponent(AlertDialog)
|
||||
const confirm = useCommandComponent(ConfirmDialog)
|
||||
|
||||
const router = useRouter();
|
||||
const surveyStore = useSurveyStore();
|
||||
const questionStore = useQuestionStore();
|
||||
const router = useRouter()
|
||||
const surveyStore = useSurveyStore()
|
||||
const questionStore = useQuestionStore()
|
||||
|
||||
const renderData = computed(() => questionStore.renderData)
|
||||
const isFinallyPage = computed(() => questionStore.isFinallyPage)
|
||||
const pagingIndex = computed(() => questionStore.pagingIndex)
|
||||
const pageIndex = computed(() => questionStore.pageIndex)
|
||||
const { bannerConf, submitConf, bottomConf: logoConf, whiteData } = storeToRefs(surveyStore)
|
||||
const surveyPath = computed(() => surveyStore.surveyPath || '')
|
||||
|
||||
const validate = (cbk: (v: boolean) => void) => {
|
||||
const index = 0;
|
||||
mainRef.value.$refs.formGroup[index].validate(cbk);
|
||||
};
|
||||
const index = 0
|
||||
mainRef.value.$refs.formGroup[index].validate(cbk)
|
||||
}
|
||||
|
||||
const normalizationRequestBody = () => {
|
||||
const enterTime = surveyStore.enterTime;
|
||||
const encryptInfo = surveyStore.encryptInfo as any;
|
||||
const formValues = surveyStore.formValues;
|
||||
const enterTime = surveyStore.enterTime
|
||||
const encryptInfo = surveyStore.encryptInfo as any
|
||||
const formValues = surveyStore.formValues
|
||||
|
||||
const result: any = {
|
||||
surveyPath: surveyPath.value,
|
||||
data: JSON.stringify(formValues),
|
||||
diffTime: Date.now() - enterTime,
|
||||
clientTime: Date.now(),
|
||||
...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);
|
||||
...whiteData.value
|
||||
}
|
||||
|
||||
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 () => {
|
||||
if (surveyPath.value.length > 8) {
|
||||
router.push({ name: "successPage" });
|
||||
return;
|
||||
router.push({ name: 'successPage' })
|
||||
return
|
||||
}
|
||||
try {
|
||||
const params = normalizationRequestBody();
|
||||
console.log(params);
|
||||
const res: any = await submitForm(params);
|
||||
const params = normalizationRequestBody()
|
||||
console.log(params)
|
||||
const res: any = await submitForm(params)
|
||||
if (res.code === 200) {
|
||||
router.push({ name: "successPage" });
|
||||
router.push({ name: 'successPage' })
|
||||
} else {
|
||||
alert({
|
||||
title: res.errmsg || "提交失败",
|
||||
});
|
||||
title: res.errmsg || '提交失败'
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
console.log(error)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const handleSubmit = () => {
|
||||
const confirmAgain = (surveyStore.submitConf as any).confirmAgain
|
||||
const { again_text, is_again } = confirmAgain
|
||||
if (!isFinallyPage.value) {
|
||||
questionStore.addPagingIndex();
|
||||
questionStore.addPageIndex()
|
||||
return
|
||||
}
|
||||
if (is_again) {
|
||||
@ -135,18 +135,18 @@ const handleSubmit = () => {
|
||||
title: again_text,
|
||||
onConfirm: async () => {
|
||||
try {
|
||||
submitSurver();
|
||||
submitSurver()
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
console.log(error)
|
||||
} finally {
|
||||
confirm.close();
|
||||
confirm.close()
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
})
|
||||
} else {
|
||||
submitSurver();
|
||||
submitSurver()
|
||||
}
|
||||
};
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.index {
|
||||
|
@ -10,7 +10,7 @@ export const useQuestionStore = defineStore('question', () => {
|
||||
const voteMap = ref({})
|
||||
const questionData = ref(null)
|
||||
const questionSeq = ref([]) // 题目的顺序,因为可能会有分页的情况,所以是一个二维数组[[qid1, qid2], [qid3,qid4]]
|
||||
const pagingIndex = ref(1) // 当前分页的索引
|
||||
const pageIndex = ref(1) // 当前分页的索引
|
||||
|
||||
// 题目列表
|
||||
const questionList = computed(() => {
|
||||
@ -41,36 +41,36 @@ export const useQuestionStore = defineStore('question', () => {
|
||||
|
||||
const renderData = computed(() => {
|
||||
const { startIndex, endIndex } = getSorter()
|
||||
const data = questionList.value[0];
|
||||
if(!data || !Array.isArray(data) ||data.length === 0) return []
|
||||
return [data.slice(startIndex,endIndex)]
|
||||
const data = questionList.value[0]
|
||||
if (!data || !Array.isArray(data) || data.length === 0) return []
|
||||
return [data.slice(startIndex, endIndex)]
|
||||
})
|
||||
|
||||
const isFinallyPage = computed(() => {
|
||||
const isFinallyPage = computed(() => {
|
||||
const surveyStore = useSurveyStore()
|
||||
return pagingIndex.value === surveyStore.pagingConf.length;
|
||||
return pageIndex.value === surveyStore.pageConf.length
|
||||
})
|
||||
|
||||
const addPagingIndex = () => {
|
||||
pagingIndex.value++
|
||||
const addPageIndex = () => {
|
||||
pageIndex.value++
|
||||
}
|
||||
|
||||
const getSorter = () => {
|
||||
let startIndex = 0;
|
||||
let startIndex = 0
|
||||
const surveyStore = useSurveyStore()
|
||||
const newPagingEditOne = pagingIndex.value;
|
||||
const endIndex = surveyStore.pagingConf[newPagingEditOne - 1];
|
||||
const newPageEditOne = pageIndex.value
|
||||
const endIndex = surveyStore.pageConf[newPageEditOne - 1]
|
||||
|
||||
for (let index = 0; index < surveyStore.pagingConf.length; index++) {
|
||||
const item = surveyStore.pagingConf[index];
|
||||
if ((newPagingEditOne - 1) == index) {
|
||||
break;
|
||||
for (let index = 0; index < surveyStore.pageConf.length; index++) {
|
||||
const item = surveyStore.pageConf[index]
|
||||
if (newPageEditOne - 1 == index) {
|
||||
break
|
||||
}
|
||||
startIndex+=item
|
||||
startIndex += item
|
||||
}
|
||||
return {
|
||||
startIndex,
|
||||
endIndex:startIndex + endIndex
|
||||
endIndex: startIndex + endIndex
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,8 +183,8 @@ export const useQuestionStore = defineStore('question', () => {
|
||||
questionSeq,
|
||||
renderData,
|
||||
isFinallyPage,
|
||||
pagingIndex,
|
||||
addPagingIndex,
|
||||
pageIndex,
|
||||
addPageIndex,
|
||||
setQuestionData,
|
||||
changeSelectMoreData,
|
||||
setQuestionSeq,
|
||||
|
@ -38,7 +38,7 @@ export const useSurveyStore = defineStore('survey', () => {
|
||||
const submitConf = ref({})
|
||||
const formValues = ref({})
|
||||
const whiteData = ref({})
|
||||
const pagingConf = ref([])
|
||||
const pageConf = ref([])
|
||||
|
||||
const router = useRouter()
|
||||
const questionStore = useQuestionStore()
|
||||
@ -129,7 +129,7 @@ export const useSurveyStore = defineStore('survey', () => {
|
||||
'skinConf',
|
||||
'submitConf',
|
||||
'whiteData',
|
||||
"pagingConf"
|
||||
'pageConf'
|
||||
])
|
||||
)
|
||||
questionStore.questionData = questionData
|
||||
@ -145,7 +145,7 @@ export const useSurveyStore = defineStore('survey', () => {
|
||||
submitConf.value = option.submitConf
|
||||
formValues.value = _formValues
|
||||
whiteData.value = option.whiteData
|
||||
pagingConf.value = option.pagingConf
|
||||
pageConf.value = option.pageConf
|
||||
// 获取已投票数据
|
||||
questionStore.initVoteData()
|
||||
}
|
||||
@ -172,7 +172,7 @@ export const useSurveyStore = defineStore('survey', () => {
|
||||
submitConf,
|
||||
formValues,
|
||||
whiteData,
|
||||
pagingConf,
|
||||
pageConf,
|
||||
|
||||
initSurvey,
|
||||
changeData,
|
||||
|
Loading…
Reference in New Issue
Block a user