feat:新增分页功能 (#382)
* feat:新增分页功能 * 修复type-check检查 * fix: server type-check * fix:修改服务端测试用例 * fix:修复分页bug
This commit is contained in:
parent
d9e9770eb8
commit
c330e6000d
@ -106,12 +106,13 @@ describe('DataStatisticController', () => {
|
|||||||
field: 'xxx',
|
field: 'xxx',
|
||||||
title: 'xxx',
|
title: 'xxx',
|
||||||
type: 'xxx',
|
type: 'xxx',
|
||||||
|
diffTime: 'xxx',
|
||||||
othersCode: 'xxx',
|
othersCode: 'xxx',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
listBody: [
|
listBody: [
|
||||||
{ difTime: '0.5', createDate: '2024-02-11' },
|
{ diffTime: '0.5', createDate: '2024-02-11' },
|
||||||
{ difTime: '0.5', createDate: '2024-02-11' },
|
{ diffTime: '0.5', createDate: '2024-02-11' },
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -151,12 +152,13 @@ describe('DataStatisticController', () => {
|
|||||||
field: 'xxx',
|
field: 'xxx',
|
||||||
title: 'xxx',
|
title: 'xxx',
|
||||||
type: 'xxx',
|
type: 'xxx',
|
||||||
|
diffTime: 'xxx',
|
||||||
othersCode: 'xxx',
|
othersCode: 'xxx',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
listBody: [
|
listBody: [
|
||||||
{ difTime: '0.5', createDate: '2024-02-11', data123: '15200000000' },
|
{ diffTime: '0.5', createDate: '2024-02-11', data123: '15200000000' },
|
||||||
{ difTime: '0.5', createDate: '2024-02-11', data123: '13800000000' },
|
{ diffTime: '0.5', createDate: '2024-02-11', data123: '13800000000' },
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ describe('DataStatisticService', () => {
|
|||||||
data413: 3,
|
data413: 3,
|
||||||
data863: '109239',
|
data863: '109239',
|
||||||
},
|
},
|
||||||
difTime: 21278,
|
diffTime: 21278,
|
||||||
clientTime: 1710340862733.0,
|
clientTime: 1710340862733.0,
|
||||||
secretKeys: [],
|
secretKeys: [],
|
||||||
optionTextAndId: {
|
optionTextAndId: {
|
||||||
@ -197,7 +197,7 @@ describe('DataStatisticService', () => {
|
|||||||
data413_3: expect.any(String),
|
data413_3: expect.any(String),
|
||||||
data413: expect.any(Number),
|
data413: expect.any(Number),
|
||||||
data863: expect.any(String),
|
data863: expect.any(String),
|
||||||
difTime: expect.any(String),
|
diffTime: expect.any(String),
|
||||||
createDate: expect.any(String),
|
createDate: expect.any(String),
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
@ -220,7 +220,7 @@ describe('DataStatisticService', () => {
|
|||||||
'U2FsdGVkX19bRmf3uEmXAJ/6zXd1Znr3cZsD5v4Nocr2v5XG1taXluz8cohFkDyH',
|
'U2FsdGVkX19bRmf3uEmXAJ/6zXd1Znr3cZsD5v4Nocr2v5XG1taXluz8cohFkDyH',
|
||||||
data770: 'U2FsdGVkX18ldQMhJjFXO8aerjftZLpFnRQ4/FVcCLI=',
|
data770: 'U2FsdGVkX18ldQMhJjFXO8aerjftZLpFnRQ4/FVcCLI=',
|
||||||
},
|
},
|
||||||
difTime: 806707,
|
diffTime: 806707,
|
||||||
clientTime: 1710400229573.0,
|
clientTime: 1710400229573.0,
|
||||||
secretKeys: ['data458', 'data450', 'data405', 'data770'],
|
secretKeys: ['data458', 'data450', 'data405', 'data770'],
|
||||||
optionTextAndId: {
|
optionTextAndId: {
|
||||||
@ -303,7 +303,7 @@ describe('DataStatisticService', () => {
|
|||||||
data458: expect.any(String),
|
data458: expect.any(String),
|
||||||
data515: expect.any(String),
|
data515: expect.any(String),
|
||||||
data770: expect.any(String),
|
data770: expect.any(String),
|
||||||
difTime: expect.any(String),
|
diffTime: expect.any(String),
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
"opacity": 100
|
"opacity": 100
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"pagingConf":[],
|
||||||
"logicConf": {
|
"logicConf": {
|
||||||
"showLogicConf": []
|
"showLogicConf": []
|
||||||
}
|
}
|
||||||
|
@ -32,11 +32,11 @@ const mockDecryptErrorBody = {
|
|||||||
'SkyfsbS6MDvFrrxFJQDMxsvm53G3PTURktfZikJP2fKilC8wPW5ZdfX29Fixor5ldHBBNyILsDtxhbNahEbNCDw8n1wS8IIckFuQcaJtn6MLOD+h+Iuywka3ig4ecTN87RpdcfEQe7f38rSSx0zoFU8j37eojjSF7eETBSrz5m9WaNesQo4hhC6p7wmAo1jggkdbG8PVrFqrZPbkHN5jOBrzQEqdqYu9A5wHMM7nUteqlPpkiogEDYmBIccqmPdtO54y7LoPslXgXj6jNja8oVNaYlnp7UsisT+i5cuQ7lbDukEhrfpAIFRsT2IUwVlLjWHtFQm4/4I5HyvVBirTng==',
|
'SkyfsbS6MDvFrrxFJQDMxsvm53G3PTURktfZikJP2fKilC8wPW5ZdfX29Fixor5ldHBBNyILsDtxhbNahEbNCDw8n1wS8IIckFuQcaJtn6MLOD+h+Iuywka3ig4ecTN87RpdcfEQe7f38rSSx0zoFU8j37eojjSF7eETBSrz5m9WaNesQo4hhC6p7wmAo1jggkdbG8PVrFqrZPbkHN5jOBrzQEqdqYu9A5wHMM7nUteqlPpkiogEDYmBIccqmPdtO54y7LoPslXgXj6jNja8oVNaYlnp7UsisT+i5cuQ7lbDukEhrfpAIFRsT2IUwVlLjWHtFQm4/4I5HyvVBirTng==',
|
||||||
'IMn0E7R6cYCQPI497mz3x99CPA4cImAFEfIv8Q98Gm5bFcgKJX6KFYS7PF/VtIuI1leKwwNYexQy7+2HnF40by/huVugoPYnPd4pTpUdG6f1kh8EpzIir2+8P98Dcz2+NZ/khP2RIAM8nOr+KSC99TNGhuKaKQCItyLFDkr80s3zv+INieGc8wULIrGoWDJGN2KdU/jSq+hkV0QXypd81N5IyAoNhZLkZeM/FU6grGFPnGRtcDDc5W8YWVHO87VymlxPCTRawXRTDcvGIUqb3GuZfxvA7AULqbspmN9kzt3rktuZLNb2TFQDsJfqUuCmi+b28qP/G4OrT9/VAHhYKw==',
|
'IMn0E7R6cYCQPI497mz3x99CPA4cImAFEfIv8Q98Gm5bFcgKJX6KFYS7PF/VtIuI1leKwwNYexQy7+2HnF40by/huVugoPYnPd4pTpUdG6f1kh8EpzIir2+8P98Dcz2+NZ/khP2RIAM8nOr+KSC99TNGhuKaKQCItyLFDkr80s3zv+INieGc8wULIrGoWDJGN2KdU/jSq+hkV0QXypd81N5IyAoNhZLkZeM/FU6grGFPnGRtcDDc5W8YWVHO87VymlxPCTRawXRTDcvGIUqb3GuZfxvA7AULqbspmN9kzt3rktuZLNb2TFQDsJfqUuCmi+b28qP/G4OrT9/VAHhYKw==',
|
||||||
],
|
],
|
||||||
difTime: 806707,
|
diffTime: 806707,
|
||||||
clientTime: 1710400229573,
|
clientTime: 1710400229573,
|
||||||
encryptType: 'rsa',
|
encryptType: 'rsa',
|
||||||
sessionId: '65f2664c92862d6a9067ad18',
|
sessionId: '65f2664c92862d6a9067ad18',
|
||||||
sign: '8c9ca8804c9d94de6055d68a1f3c423fe50c95b4bd69f809ee2da8fcd82fd960.1710400229589',
|
sign: '95d6ff5dd3d9ddc205cbab88defe40ebe889952961f1d60e760fa411e2cb39fe.1710400229589',
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockSubmitData = {
|
const mockSubmitData = {
|
||||||
@ -45,11 +45,11 @@ const mockSubmitData = {
|
|||||||
'SkyfsbS6MDvFrrxFJQDMxsvm53G3PTURktfZikJP2fKilC8wPW5ZdfX29Fixor5ldHBBNyILsDtxhbNahEbNCDw8n1wS8IIckFuQcaJtn6MLOD+h+Iuywka3ig4ecTN87RpdcfEQe7f38rSSx0zoFU8j37eojjSF7eETBSrz5m9WaNesQo4hhC6p7wmAo1jggkdbG8PVrFqrZPbkHN5jOBrzQEqdqYu9A5wHMM7nUteqlPpkiogEDYmBIccqmPdtO54y7LoPslXgXj6jNja8oVNaYlnp7UsisT+i5cuQ7lbDukEhrfpAIFRsT2IUwVlLjWHtFQm4/4I5HyvVBirTng==',
|
'SkyfsbS6MDvFrrxFJQDMxsvm53G3PTURktfZikJP2fKilC8wPW5ZdfX29Fixor5ldHBBNyILsDtxhbNahEbNCDw8n1wS8IIckFuQcaJtn6MLOD+h+Iuywka3ig4ecTN87RpdcfEQe7f38rSSx0zoFU8j37eojjSF7eETBSrz5m9WaNesQo4hhC6p7wmAo1jggkdbG8PVrFqrZPbkHN5jOBrzQEqdqYu9A5wHMM7nUteqlPpkiogEDYmBIccqmPdtO54y7LoPslXgXj6jNja8oVNaYlnp7UsisT+i5cuQ7lbDukEhrfpAIFRsT2IUwVlLjWHtFQm4/4I5HyvVBirTng==',
|
||||||
'IMn0E7R6cYCQPI497mz3x99CPA4cImAFEfIv8Q98Gm5bFcgKJX6KFYS7PF/VtIuI1leKwwNYexQy7+2HnF40by/huVugoPYnPd4pTpUdG6f1kh8EpzIir2+8P98Dcz2+NZ/khP2RIAM8nOr+KSC99TNGhuKaKQCItyLFDkr80s3zv+INieGc8wULIrGoWDJGN2KdU/jSq+hkV0QXypd81N5IyAoNhZLkZeM/FU6grGFPnGRtcDDc5W8YWVHO87VymlxPCTRawXRTDcvGIUqb3GuZfxvA7AULqbspmN9kzt3rktuZLNb2TFQDsJfqUuCmi+b28qP/G4OrT9/VAHhYKw==',
|
'IMn0E7R6cYCQPI497mz3x99CPA4cImAFEfIv8Q98Gm5bFcgKJX6KFYS7PF/VtIuI1leKwwNYexQy7+2HnF40by/huVugoPYnPd4pTpUdG6f1kh8EpzIir2+8P98Dcz2+NZ/khP2RIAM8nOr+KSC99TNGhuKaKQCItyLFDkr80s3zv+INieGc8wULIrGoWDJGN2KdU/jSq+hkV0QXypd81N5IyAoNhZLkZeM/FU6grGFPnGRtcDDc5W8YWVHO87VymlxPCTRawXRTDcvGIUqb3GuZfxvA7AULqbspmN9kzt3rktuZLNb2TFQDsJfqUuCmi+b28qP/G4OrT9/VAHhYKw==',
|
||||||
],
|
],
|
||||||
difTime: 806707,
|
diffTime: 806707,
|
||||||
clientTime: 1710400229573,
|
clientTime: 1710400229573,
|
||||||
encryptType: 'rsa',
|
encryptType: 'rsa',
|
||||||
sessionId: '65f29fc192862d6a9067ad28',
|
sessionId: '65f29fc192862d6a9067ad28',
|
||||||
sign: '8c9ca8804c9d94de6055d68a1f3c423fe50c95b4bd69f809ee2da8fcd82fd960.1710400229589',
|
sign: '95d6ff5dd3d9ddc205cbab88defe40ebe889952961f1d60e760fa411e2cb39fe.1710400229589',
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockClientEncryptInfo = {
|
const mockClientEncryptInfo = {
|
||||||
@ -185,7 +185,7 @@ describe('SurveyResponseController', () => {
|
|||||||
status: RECORD_STATUS.NEW,
|
status: RECORD_STATUS.NEW,
|
||||||
date: 1711025113146,
|
date: 1711025113146,
|
||||||
},
|
},
|
||||||
difTime: 30518,
|
diffTime: 30518,
|
||||||
data: {
|
data: {
|
||||||
data458: '15000000000',
|
data458: '15000000000',
|
||||||
data515: '115019',
|
data515: '115019',
|
||||||
@ -220,7 +220,6 @@ describe('SurveyResponseController', () => {
|
|||||||
jest
|
jest
|
||||||
.spyOn(clientEncryptService, 'deleteEncryptInfo')
|
.spyOn(clientEncryptService, 'deleteEncryptInfo')
|
||||||
.mockResolvedValueOnce(undefined);
|
.mockResolvedValueOnce(undefined);
|
||||||
|
|
||||||
const result = await controller.createResponse(reqBody, {});
|
const result = await controller.createResponse(reqBody, {});
|
||||||
|
|
||||||
expect(result).toEqual({ code: 200, msg: '提交成功' });
|
expect(result).toEqual({ code: 200, msg: '提交成功' });
|
||||||
@ -240,7 +239,7 @@ describe('SurveyResponseController', () => {
|
|||||||
data770: '123456@qq.com',
|
data770: '123456@qq.com',
|
||||||
},
|
},
|
||||||
clientTime: reqBody.clientTime,
|
clientTime: reqBody.clientTime,
|
||||||
difTime: reqBody.difTime,
|
diffTime: reqBody.diffTime,
|
||||||
surveyId: mockResponseSchema.pageId,
|
surveyId: mockResponseSchema.pageId,
|
||||||
optionTextAndId: {
|
optionTextAndId: {
|
||||||
data515: [
|
data515: [
|
||||||
@ -327,7 +326,7 @@ describe('SurveyResponseController', () => {
|
|||||||
const reqBody = {
|
const reqBody = {
|
||||||
...mockSubmitData,
|
...mockSubmitData,
|
||||||
password: '123457',
|
password: '123457',
|
||||||
sign: '4ff02062141d92d80629eae4797ba68056f29a9709cdf59bf206776fc0971c1a.1710400229589',
|
sign: '145595d85079af3b1fb30784177c348555f442837c051d90f57a01ce1ff53c32.1710400229589',
|
||||||
};
|
};
|
||||||
|
|
||||||
jest
|
jest
|
||||||
|
@ -33,7 +33,7 @@ describe('SurveyResponseService', () => {
|
|||||||
const surveyData = {
|
const surveyData = {
|
||||||
data: {},
|
data: {},
|
||||||
clientTime: new Date(),
|
clientTime: new Date(),
|
||||||
difTime: 0,
|
diffTime: 0,
|
||||||
surveyId: 'testId',
|
surveyId: 'testId',
|
||||||
surveyPath: 'testPath',
|
surveyPath: 'testPath',
|
||||||
optionTextAndId: {},
|
optionTextAndId: {},
|
||||||
@ -59,7 +59,7 @@ describe('SurveyResponseService', () => {
|
|||||||
surveyPath: surveyData.surveyPath,
|
surveyPath: surveyData.surveyPath,
|
||||||
data: surveyData.data,
|
data: surveyData.data,
|
||||||
clientTime: surveyData.clientTime,
|
clientTime: surveyData.clientTime,
|
||||||
difTime: surveyData.difTime,
|
diffTime: surveyData.diffTime,
|
||||||
pageId: surveyData.surveyId,
|
pageId: surveyData.surveyId,
|
||||||
secretKeys: [],
|
secretKeys: [],
|
||||||
optionTextAndId: surveyData.optionTextAndId,
|
optionTextAndId: surveyData.optionTextAndId,
|
||||||
|
4
web/components.d.ts
vendored
4
web/components.d.ts
vendored
@ -17,6 +17,7 @@ declare module 'vue' {
|
|||||||
ElDialog: typeof import('element-plus/es')['ElDialog']
|
ElDialog: typeof import('element-plus/es')['ElDialog']
|
||||||
ElForm: typeof import('element-plus/es')['ElForm']
|
ElForm: typeof import('element-plus/es')['ElForm']
|
||||||
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
||||||
|
ElIcon: typeof import('element-plus/es')['ElIcon']
|
||||||
ElInput: typeof import('element-plus/es')['ElInput']
|
ElInput: typeof import('element-plus/es')['ElInput']
|
||||||
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
|
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
|
||||||
ElMenu: typeof import('element-plus/es')['ElMenu']
|
ElMenu: typeof import('element-plus/es')['ElMenu']
|
||||||
@ -42,6 +43,8 @@ declare module 'vue' {
|
|||||||
ElTimePicker: typeof import('element-plus/es')['ElTimePicker']
|
ElTimePicker: typeof import('element-plus/es')['ElTimePicker']
|
||||||
ElTooltip: typeof import('element-plus/es')['ElTooltip']
|
ElTooltip: typeof import('element-plus/es')['ElTooltip']
|
||||||
ElTree: typeof import('element-plus/es')['ElTree']
|
ElTree: typeof import('element-plus/es')['ElTree']
|
||||||
|
IEpArrowLeft: typeof import('~icons/ep/arrow-left')['default']
|
||||||
|
IEpArrowRight: typeof import('~icons/ep/arrow-right')['default']
|
||||||
IEpBottom: typeof import('~icons/ep/bottom')['default']
|
IEpBottom: typeof import('~icons/ep/bottom')['default']
|
||||||
IEpCheck: typeof import('~icons/ep/check')['default']
|
IEpCheck: typeof import('~icons/ep/check')['default']
|
||||||
IEpCirclePlus: typeof import('~icons/ep/circle-plus')['default']
|
IEpCirclePlus: typeof import('~icons/ep/circle-plus')['default']
|
||||||
@ -54,6 +57,7 @@ declare module 'vue' {
|
|||||||
IEpMinus: typeof import('~icons/ep/minus')['default']
|
IEpMinus: typeof import('~icons/ep/minus')['default']
|
||||||
IEpMonitor: typeof import('~icons/ep/monitor')['default']
|
IEpMonitor: typeof import('~icons/ep/monitor')['default']
|
||||||
IEpMore: typeof import('~icons/ep/more')['default']
|
IEpMore: typeof import('~icons/ep/more')['default']
|
||||||
|
IEpMoreFilled: typeof import('~icons/ep/more-filled')['default']
|
||||||
IEpPlus: typeof import('~icons/ep/plus')['default']
|
IEpPlus: typeof import('~icons/ep/plus')['default']
|
||||||
IEpQuestionFilled: typeof import('~icons/ep/question-filled')['default']
|
IEpQuestionFilled: typeof import('~icons/ep/question-filled')['default']
|
||||||
IEpRank: typeof import('~icons/ep/rank')['default']
|
IEpRank: typeof import('~icons/ep/rank')['default']
|
||||||
|
@ -1 +1,2 @@
|
|||||||
export const DND_GROUP = 'question'
|
export const DND_GROUP = 'question'
|
||||||
|
export const QUESTION_CATALOG = 'questionCatalog'
|
||||||
|
@ -53,6 +53,7 @@ export const defaultQuestionConfig = {
|
|||||||
star: 5,
|
star: 5,
|
||||||
optionOrigin: '',
|
optionOrigin: '',
|
||||||
originType: 'selected',
|
originType: 'selected',
|
||||||
|
innerType:'',
|
||||||
matrixOptionsRely: '',
|
matrixOptionsRely: '',
|
||||||
numberRange: {
|
numberRange: {
|
||||||
min: {
|
min: {
|
||||||
|
@ -14,8 +14,9 @@
|
|||||||
:ref="`questionWrapper-${element.field}`"
|
:ref="`questionWrapper-${element.field}`"
|
||||||
:moduleConfig="element"
|
:moduleConfig="element"
|
||||||
:qIndex="element.qIndex"
|
:qIndex="element.qIndex"
|
||||||
|
:isFirst="index==0"
|
||||||
:indexNumber="element.indexNumber"
|
:indexNumber="element.indexNumber"
|
||||||
:isSelected="currentEditOne === index"
|
:isSelected="currentEditOne === element.qIndex"
|
||||||
:isLast="index + 1 === questionDataList.length"
|
:isLast="index + 1 === questionDataList.length"
|
||||||
@select="handleSelect"
|
@select="handleSelect"
|
||||||
@changeSeq="handleChangeSeq"
|
@changeSeq="handleChangeSeq"
|
||||||
@ -24,7 +25,7 @@
|
|||||||
:type="element.type"
|
:type="element.type"
|
||||||
:moduleConfig="element"
|
:moduleConfig="element"
|
||||||
:indexNumber="element.indexNumber"
|
:indexNumber="element.indexNumber"
|
||||||
:isSelected="currentEditOne === index"
|
:isSelected="currentEditOne === element.qIndex"
|
||||||
:readonly="true"
|
:readonly="true"
|
||||||
@change="handleChange"
|
@change="handleChange"
|
||||||
></QuestionContainerB>
|
></QuestionContainerB>
|
||||||
@ -39,7 +40,6 @@ import { useEditStore } from '@/management/stores/edit'
|
|||||||
import QuestionContainerB from '@/materials/questions/QuestionContainerB'
|
import QuestionContainerB from '@/materials/questions/QuestionContainerB'
|
||||||
import QuestionWrapper from '@/management/pages/edit/components/QuestionWrapper.vue'
|
import QuestionWrapper from '@/management/pages/edit/components/QuestionWrapper.vue'
|
||||||
import draggable from 'vuedraggable'
|
import draggable from 'vuedraggable'
|
||||||
import { filterQuestionPreviewData } from '@/management/utils/index'
|
|
||||||
import { DND_GROUP } from '@/management/config/dnd'
|
import { DND_GROUP } from '@/management/config/dnd'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
@ -60,15 +60,15 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: ['change', 'select', 'changeSeq'],
|
emits: ['change', 'select', 'changeSeq','change'],
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
const editStore = useEditStore()
|
const editStore = useEditStore()
|
||||||
const renderData = computed({
|
const renderData = computed({
|
||||||
get() {
|
get() {
|
||||||
return filterQuestionPreviewData(props.questionDataList)
|
return props.questionDataList; //filterQuestionPreviewData(props.questionDataList)
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
editStore.setQuestionDataList(value)
|
editStore.moveQuestionDataList(value)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const handleSelect = (index) => {
|
const handleSelect = (index) => {
|
||||||
|
101
web/src/management/pages/edit/components/PagingWrapper.vue
Normal file
101
web/src/management/pages/edit/components/PagingWrapper.vue
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
<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>
|
@ -51,6 +51,10 @@ const props = defineProps({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
isFirst: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
isLast: {
|
isLast: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
@ -81,7 +85,7 @@ const showHover = computed(() => {
|
|||||||
return isHover.value || props.isSelected
|
return isHover.value || props.isSelected
|
||||||
})
|
})
|
||||||
const showUp = computed(() => {
|
const showUp = computed(() => {
|
||||||
return props.qIndex !== 0
|
return !props.isFirst
|
||||||
})
|
})
|
||||||
const showDown = computed(() => {
|
const showDown = computed(() => {
|
||||||
return !props.isLast
|
return !props.isLast
|
||||||
|
@ -10,6 +10,7 @@ export default function (schema) {
|
|||||||
'skinConf',
|
'skinConf',
|
||||||
'submitConf',
|
'submitConf',
|
||||||
'questionDataList',
|
'questionDataList',
|
||||||
|
"pagingConf",
|
||||||
'logicConf'
|
'logicConf'
|
||||||
])
|
])
|
||||||
configData.dataConf = {
|
configData.dataConf = {
|
||||||
|
@ -0,0 +1,282 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="props.totalPage > 0" class="com-pagination">
|
||||||
|
<span :class="['com-pagination-item', prev_class]" @click="changePage(prev_page)">
|
||||||
|
<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)">
|
||||||
|
<span>{{ i }}</span>
|
||||||
|
<div v-if="!props.readonly" :class="['moreControls']" @click.stop="showTooltipVisible(i)">
|
||||||
|
<i-ep-MoreFilled />
|
||||||
|
</div>
|
||||||
|
</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' : '')]">
|
||||||
|
<span>{{ i }}</span>
|
||||||
|
<div v-if="!props.readonly" :class="['moreControls']" @click.stop="showTooltipVisible(i)">
|
||||||
|
<i-ep-MoreFilled />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-tooltip class="controls-wrap" effect="light" placement="bottom" :visible="moreVisible">
|
||||||
|
<span class="com-pagination-item" @click.stop="moreVisible = true">
|
||||||
|
<i-ep-MoreFilled />
|
||||||
|
</span>
|
||||||
|
<template #content>
|
||||||
|
<div class="bubble-wrap">
|
||||||
|
<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)">
|
||||||
|
<span>{{ i }}</span>
|
||||||
|
<div v-if="!props.readonly" :class="['moreControls']" @click.stop="showTooltipVisible(i)">
|
||||||
|
<i-ep-MoreFilled />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<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">
|
||||||
|
<template #content>
|
||||||
|
<slot name="tooltip" :index="tooltipIndex"></slot>
|
||||||
|
</template>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { clone } from "lodash-es";
|
||||||
|
import { withDefaults, reactive, computed, watch, ref, onMounted, onUnmounted, nextTick, useSlots } from "vue";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
modelValue: number // 页码
|
||||||
|
totalPage?: 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']);
|
||||||
|
|
||||||
|
const state = reactive({
|
||||||
|
now: props.modelValue,
|
||||||
|
jump: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
const slot = useSlots();
|
||||||
|
|
||||||
|
const moreVisible = ref(false)
|
||||||
|
const tooltipVisible = ref(false)
|
||||||
|
const triggerBtn = ref<EventTarget | null>(null);
|
||||||
|
const tooltipIndex = ref(0)
|
||||||
|
|
||||||
|
const now_page = computed(() => {
|
||||||
|
return state.now * 1;
|
||||||
|
});
|
||||||
|
const prev_class = computed(() => {
|
||||||
|
return now_page.value == 1 ? 'disabled' : '';
|
||||||
|
});
|
||||||
|
const next_class = computed(() => {
|
||||||
|
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;
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const totalArr = computed(() => {
|
||||||
|
const arr = [];
|
||||||
|
for (let i = 0; i < props.totalPage; i++) {
|
||||||
|
arr.push(i + 1);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
return {
|
||||||
|
startArr,
|
||||||
|
bubbleArr,
|
||||||
|
endArr
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const firstPagination = computed(() => {
|
||||||
|
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);
|
||||||
|
};
|
||||||
|
|
||||||
|
const showTooltipVisible = (index:number) => {
|
||||||
|
if (slot.tooltip) {
|
||||||
|
nextTick(() => {
|
||||||
|
tooltipIndex.value = index;
|
||||||
|
triggerBtn.value = document.getElementsByClassName(`page-${index}`)[0] || null;
|
||||||
|
tooltipVisible.value = true;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const hideMoreVisible = () => {
|
||||||
|
moreVisible.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hideTooltipVisible = () => {
|
||||||
|
tooltipVisible.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
document.addEventListener('click', hideMoreVisible)
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.bubble-wrap {
|
||||||
|
.bubble-item {
|
||||||
|
max-width: 100px;
|
||||||
|
min-width: 10px;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 6px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #cccc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.com-pagination {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 0;
|
||||||
|
user-select: none;
|
||||||
|
.moreControls{
|
||||||
|
color:#6E707C;
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
left:22px;
|
||||||
|
svg{
|
||||||
|
transform: rotate(90deg);
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&-item {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
// padding: 0 4px;
|
||||||
|
min-width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
color: #303133;
|
||||||
|
border-radius: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 14px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: $primary-color;
|
||||||
|
.moreControls{
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: $primary-color;
|
||||||
|
.moreControls{
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
display: block;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
width: inherit;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: $primary-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.disabled,
|
||||||
|
.disabled:hover {
|
||||||
|
svg{
|
||||||
|
cursor: not-allowed;
|
||||||
|
color:#303133 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.current,
|
||||||
|
.current:hover {
|
||||||
|
color: $primary-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,8 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="main-operation" @click="onMainClick" ref="mainOperation">
|
<div class="main-operation" @click="onMainClick" ref="mainOperation">
|
||||||
|
<div class="pagination-wrapper">
|
||||||
|
<PagingWrapper :readonly="false"/>
|
||||||
|
</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"
|
||||||
:bannerConf="bannerConf"
|
:bannerConf="bannerConf"
|
||||||
:readonly="false"
|
:readonly="false"
|
||||||
:is-selected="currentEditOne === 'mainTitle'"
|
:is-selected="currentEditOne === 'mainTitle'"
|
||||||
@ -11,7 +15,7 @@
|
|||||||
/>
|
/>
|
||||||
<MaterialGroup
|
<MaterialGroup
|
||||||
:current-edit-one="parseInt(currentEditOne)"
|
:current-edit-one="parseInt(currentEditOne)"
|
||||||
:questionDataList="questionDataList"
|
:questionDataList="pagingQuestionData"
|
||||||
@select="setCurrentEditOne"
|
@select="setCurrentEditOne"
|
||||||
@change="handleChange"
|
@change="handleChange"
|
||||||
@changeSeq="onQuestionOperation"
|
@changeSeq="onQuestionOperation"
|
||||||
@ -21,6 +25,7 @@
|
|||||||
:submit-conf="submitConf"
|
:submit-conf="submitConf"
|
||||||
:readonly="false"
|
:readonly="false"
|
||||||
:skin-conf="skinConf"
|
:skin-conf="skinConf"
|
||||||
|
:is-finally-page="isFinallyPage"
|
||||||
:is-selected="currentEditOne === 'submit'"
|
:is-selected="currentEditOne === 'submit'"
|
||||||
@select="setCurrentEditOne('submit')"
|
@select="setCurrentEditOne('submit')"
|
||||||
/>
|
/>
|
||||||
@ -32,6 +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 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'
|
||||||
@ -40,13 +46,15 @@ const MainTitle = communalLoader.loadComponent('MainTitle')
|
|||||||
const SubmitButton = communalLoader.loadComponent('SubmitButton')
|
const SubmitButton = communalLoader.loadComponent('SubmitButton')
|
||||||
|
|
||||||
const editStore = useEditStore()
|
const editStore = useEditStore()
|
||||||
const { questionDataList, currentEditOne, currentEditKey } = storeToRefs(editStore)
|
const { currentEditOne, currentEditKey,pagingQuestionData,isFinallyPage,pagingEditOne } = 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)
|
||||||
const materialGroup = ref(null)
|
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,
|
||||||
@ -138,6 +146,13 @@ watch(
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
background-color: #f6f7f9;
|
background-color: #f6f7f9;
|
||||||
}
|
}
|
||||||
|
.pagination-wrapper{
|
||||||
|
width: 90%;
|
||||||
|
padding-right: 30px;
|
||||||
|
margin-right: -30px;
|
||||||
|
position: relative;
|
||||||
|
top: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
.toolbar {
|
.toolbar {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -1,68 +1,95 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="question-catalog-wrapper">
|
<div class="question-catalog-wrapper">
|
||||||
<draggable
|
<el-collapse>
|
||||||
:list="renderData"
|
<el-collapse-item v-for="(v, i) in renderData" :key="v" :title="`第${i + 1}页`" :name="i + 1">
|
||||||
@end="handleDragEnd"
|
<draggable v-model="renderData[i]" itemKey="field" :group="QUESTION_CATALOG" handle=".draggHandle"
|
||||||
itemKey="field"
|
host-class="catalog-item-ghost">
|
||||||
handle=".draggHandle"
|
<template #item="{ element }">
|
||||||
host-class="catalog-item-ghost"
|
<CatalogItem :title="element.title" :indexNumber="element.indexNumber" :showIndex="element.showIndex"
|
||||||
>
|
@select="setPagingOneEdit(element.qIndex, i + 1)" />
|
||||||
<template #item="{ element, index }">
|
</template>
|
||||||
<CatalogItem
|
</draggable>
|
||||||
:title="element.title"
|
</el-collapse-item>
|
||||||
:indexNumber="element.indexNumber"
|
</el-collapse>
|
||||||
:showIndex="element.showIndex"
|
|
||||||
@select="setCurrentEditOne(index)"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</draggable>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed } 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'
|
||||||
|
|
||||||
import CatalogItem from './CatalogItem.vue'
|
import CatalogItem from './CatalogItem.vue'
|
||||||
import { filterQuestionPreviewData } from '@/management/utils/index'
|
import { QUESTION_CATALOG } from '@/management/config/dnd'
|
||||||
|
|
||||||
const editStore = useEditStore()
|
const editStore = useEditStore()
|
||||||
const { questionDataList, currentEditOne } = storeToRefs(editStore)
|
const { questionDataList, pagingConf } = storeToRefs(editStore)
|
||||||
const { moveQuestion, setCurrentEditOne } = editStore
|
const { setCurrentEditOne, getPagingQuestionData, updatePagingEditOne,setPaging,compareQuestionSeq } = editStore
|
||||||
const renderData = computed(() => {
|
|
||||||
return filterQuestionPreviewData(questionDataList.value) || []
|
const renderData: any = ref([])
|
||||||
|
|
||||||
|
const setPagingOneEdit = (qIndex: number, pagingIndex: number) => {
|
||||||
|
updatePagingEditOne(pagingIndex)
|
||||||
|
setCurrentEditOne(qIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
watch(() => [pagingConf.value,questionDataList.value], () => {
|
||||||
|
renderData.value = [];
|
||||||
|
for (let index = 0; index < pagingConf.value.length; index++) {
|
||||||
|
renderData.value.push(getPagingQuestionData(index + 1))
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
deep: true,
|
||||||
|
immediate: true
|
||||||
})
|
})
|
||||||
|
|
||||||
const handleDragEnd = ({ newIndex, oldIndex }: any) => {
|
watch(() => renderData.value, (newVal) => {
|
||||||
if (currentEditOne.value === oldIndex) {
|
if (newVal.length == 0) return;
|
||||||
setCurrentEditOne(newIndex)
|
let pagingData: Array<number> = [];
|
||||||
}
|
let questionList: Array<any> = [];
|
||||||
|
newVal.map((v:any) => {
|
||||||
moveQuestion({
|
pagingData.push(v.length)
|
||||||
index: oldIndex,
|
questionList.push(...v)
|
||||||
range: newIndex - oldIndex
|
|
||||||
})
|
})
|
||||||
}
|
setPaging(pagingData)
|
||||||
|
compareQuestionSeq(questionList)
|
||||||
|
|
||||||
|
}, {
|
||||||
|
deep: true
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.question-catalog-wrapper {
|
.question-catalog-wrapper {
|
||||||
padding-bottom: 400px; // 考试题有个上拉框会盖住,改成和题型一致的
|
padding-bottom: 400px; // 考试题有个上拉框会盖住,改成和题型一致的
|
||||||
|
|
||||||
.catelog-first-page {
|
.catelog-first-page {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #999999;
|
color: #999999;
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.catalog-item-ghost {
|
.catalog-item-ghost {
|
||||||
&.question-catalog-item {
|
&.question-catalog-item {
|
||||||
.catalog-item {
|
.catalog-item {
|
||||||
color: $normal-color-light;
|
color: $normal-color-light;
|
||||||
|
|
||||||
.draggHandle {
|
.draggHandle {
|
||||||
color: $normal-color-light;
|
color: $normal-color-light;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:deep(.el-collapse-item__header) {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #6E707C;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
.catalog-item-dragging {
|
.catalog-item-dragging {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
class="questiontype-list"
|
class="questiontype-list"
|
||||||
:list="item.questionList"
|
:list="item.questionList"
|
||||||
:group="{ name: DND_GROUP, pull: 'clone', put: false }"
|
:group="{ name: DND_GROUP, pull: 'clone', put: false }"
|
||||||
:clone="getNewQuestion"
|
:clone="createNewQuestion"
|
||||||
item-key="path"
|
item-key="path"
|
||||||
>
|
>
|
||||||
<template #item="{ element }">
|
<template #item="{ element }">
|
||||||
@ -44,44 +44,26 @@ import draggable from 'vuedraggable'
|
|||||||
import { DND_GROUP } from '@/management/config/dnd'
|
import { DND_GROUP } from '@/management/config/dnd'
|
||||||
|
|
||||||
import questionMenuConfig, { questionTypeList } from '@/management/config/questionMenuConfig'
|
import questionMenuConfig, { questionTypeList } from '@/management/config/questionMenuConfig'
|
||||||
import { getQuestionByType } from '@/management/utils/index'
|
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { useEditStore } from '@/management/stores/edit'
|
import { useEditStore } from '@/management/stores/edit'
|
||||||
import { isNumber as _isNumber } from 'lodash-es'
|
import { ref } from 'vue'
|
||||||
import { computed, ref } from 'vue'
|
|
||||||
import { QUESTION_TYPE } from '@/common/typeEnum.ts'
|
|
||||||
|
|
||||||
const editStore = useEditStore()
|
const editStore = useEditStore()
|
||||||
const { questionDataList, currentEditOne } = storeToRefs(editStore)
|
const { newQuestionIndex } = storeToRefs(editStore)
|
||||||
const { addQuestion, setCurrentEditOne } = editStore
|
const { addQuestion, setCurrentEditOne,createNewQuestion } = editStore
|
||||||
|
|
||||||
const activeNames = ref([0, 1])
|
const activeNames = ref([0, 1])
|
||||||
const previewImg = ref('')
|
const previewImg = ref('')
|
||||||
const isShowPreviewImage = ref(false)
|
const isShowPreviewImage = ref(false)
|
||||||
const previewTop = ref(0)
|
const previewTop = ref(0)
|
||||||
const newQuestionIndex = computed(() => {
|
|
||||||
const index = _isNumber(currentEditOne.value)
|
|
||||||
? currentEditOne.value + 1
|
|
||||||
: questionDataList.value.length
|
|
||||||
return index
|
|
||||||
})
|
|
||||||
|
|
||||||
questionLoader.init({
|
questionLoader.init({
|
||||||
typeList: questionTypeList.map((item) => item.type)
|
typeList: questionTypeList.map((item) => item.type)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getNewQuestion = ({ type }) => {
|
|
||||||
const fields = questionDataList.value.map((item) => item.field)
|
|
||||||
const newQuestion = getQuestionByType(type, fields)
|
|
||||||
newQuestion.title = newQuestion.title = `标题${newQuestionIndex.value + 1}`
|
|
||||||
if (type === QUESTION_TYPE.VOTE) {
|
|
||||||
newQuestion.innerType = QUESTION_TYPE.RADIO
|
|
||||||
}
|
|
||||||
return newQuestion
|
|
||||||
}
|
|
||||||
|
|
||||||
const onQuestionType = ({ type }) => {
|
const onQuestionType = ({ type }) => {
|
||||||
const newQuestion = getNewQuestion({ type })
|
const newQuestion = createNewQuestion({ type })
|
||||||
addQuestion({ question: newQuestion, index: newQuestionIndex.value })
|
addQuestion({ question: newQuestion, index: newQuestionIndex.value })
|
||||||
setCurrentEditOne(newQuestionIndex.value)
|
setCurrentEditOne(newQuestionIndex.value)
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="main-operation">
|
<div class="main-operation">
|
||||||
|
<div class="pagination-wrapper">
|
||||||
|
<PagingWrapper :readonly="true" />
|
||||||
|
</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 :bannerConf="bannerConf" :readonly="false" />
|
<HeaderContent v-if="pagingEditOne==1" :bannerConf="bannerConf" :readonly="false" />
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<MainTitle :isSelected="false" :bannerConf="bannerConf" :readonly="false" />
|
<MainTitle v-if="pagingEditOne==1" :isSelected="false" :bannerConf="bannerConf" :readonly="false" />
|
||||||
<MaterialGroup :questionDataList="questionDataList" ref="MaterialGroup" />
|
<MaterialGroup :questionDataList="pagingQuestionData" ref="MaterialGroup" />
|
||||||
<SubmitButton
|
<SubmitButton :submit-conf="submitConf" :skin-conf="skinConf" :readonly="false"
|
||||||
:submit-conf="submitConf"
|
:is-selected="currentEditOne === 'submit'" :is-finally-page="isFinallyPage" />
|
||||||
:skin-conf="skinConf"
|
<LogoIcon :logo-conf="bottomConf" :readonly="false" :is-selected="currentEditOne === 'logo'" />
|
||||||
:readonly="false"
|
|
||||||
:is-selected="currentEditOne === 'submit'"
|
|
||||||
/>
|
|
||||||
<LogoIcon
|
|
||||||
:logo-conf="bottomConf"
|
|
||||||
:readonly="false"
|
|
||||||
:is-selected="currentEditOne === 'logo'"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -26,6 +21,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 { 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'
|
||||||
@ -38,6 +34,7 @@ const LogoIcon = () => communalLoader.loadComponent('LogoIcon')
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
MaterialGroup,
|
MaterialGroup,
|
||||||
|
PagingWrapper,
|
||||||
HeaderContent: HeaderContent(),
|
HeaderContent: HeaderContent(),
|
||||||
MainTitle: MainTitle(),
|
MainTitle: MainTitle(),
|
||||||
SubmitButton: SubmitButton(),
|
SubmitButton: SubmitButton(),
|
||||||
@ -45,7 +42,7 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
const editStore = useEditStore()
|
const editStore = useEditStore()
|
||||||
const { questionDataList, currentEditOne, currentEditKey } = storeToRefs(editStore)
|
const { pagingQuestionData, currentEditOne, currentEditKey,isFinallyPage,pagingEditOne } = storeToRefs(editStore)
|
||||||
const { schema } = editStore
|
const { schema } = editStore
|
||||||
const { bannerConf, submitConf, skinConf, bottomConf } = toRefs(schema)
|
const { bannerConf, submitConf, skinConf, bottomConf } = toRefs(schema)
|
||||||
|
|
||||||
@ -54,9 +51,11 @@ export default defineComponent({
|
|||||||
submitConf,
|
submitConf,
|
||||||
bottomConf,
|
bottomConf,
|
||||||
skinConf,
|
skinConf,
|
||||||
questionDataList,
|
pagingQuestionData,
|
||||||
currentEditOne,
|
currentEditOne,
|
||||||
currentEditKey
|
currentEditKey,
|
||||||
|
isFinallyPage,
|
||||||
|
pagingEditOne
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@ -92,6 +91,12 @@ export default defineComponent({
|
|||||||
background-color: #f6f7f9;
|
background-color: #f6f7f9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pagination-wrapper {
|
||||||
|
position: relative;
|
||||||
|
top: 50px;
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
.toolbar {
|
.toolbar {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 38px;
|
height: 38px;
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
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 } 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'
|
||||||
|
|
||||||
import { getSurveyById } from '@/management/api/survey'
|
import { getSurveyById } from '@/management/api/survey'
|
||||||
import { getNewField } from '@/management/utils'
|
import { getNewField } from '@/management/utils'
|
||||||
@ -71,8 +74,10 @@ function useInitializeSchema(surveyId: Ref<string>) {
|
|||||||
link: ''
|
link: ''
|
||||||
},
|
},
|
||||||
questionDataList: [],
|
questionDataList: [],
|
||||||
|
pagingEditOne: 1,
|
||||||
|
pagingConf:[], // 分页逻辑
|
||||||
logicConf: {
|
logicConf: {
|
||||||
showLogicConf: []
|
showLogicConf: [],
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -84,7 +89,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.pagingConf = codeData.pagingConf;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getSchemaFromRemote() {
|
async function getSchemaFromRemote() {
|
||||||
@ -92,15 +99,19 @@ function useInitializeSchema(surveyId: Ref<string>) {
|
|||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
const metaData = res.data.surveyMetaRes
|
const metaData = res.data.surveyMetaRes
|
||||||
document.title = metaData.title
|
document.title = metaData.title
|
||||||
|
const data = res.data.surveyConfRes.code
|
||||||
const {
|
const {
|
||||||
bannerConf,
|
bannerConf,
|
||||||
bottomConf,
|
bottomConf,
|
||||||
skinConf,
|
skinConf,
|
||||||
baseConf,
|
baseConf,
|
||||||
submitConf,
|
submitConf,
|
||||||
dataConf,
|
dataConf,
|
||||||
logicConf = {}
|
logicConf = {}
|
||||||
} = res.data.surveyConfRes.code
|
} = data
|
||||||
|
if (!data.pagingConf || data.pagingConf.length === 0) {
|
||||||
|
data.pagingConf = [dataConf.dataList.length]
|
||||||
|
}
|
||||||
initSchema({
|
initSchema({
|
||||||
metaData,
|
metaData,
|
||||||
codeData: {
|
codeData: {
|
||||||
@ -110,6 +121,7 @@ function useInitializeSchema(surveyId: Ref<string>) {
|
|||||||
baseConf,
|
baseConf,
|
||||||
submitConf,
|
submitConf,
|
||||||
questionDataList: dataConf.dataList,
|
questionDataList: dataConf.dataList,
|
||||||
|
pagingConf: data.pagingConf,
|
||||||
logicConf
|
logicConf
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -125,7 +137,7 @@ function useInitializeSchema(surveyId: Ref<string>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function useQuestionDataListOperations(questionDataList: Ref<any[]>, updateTime: () => void) {
|
function useQuestionDataListOperations(questionDataList: Ref<any[]>, updateTime: () => void,pagingOperations:(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))
|
||||||
@ -134,10 +146,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')
|
||||||
updateTime()
|
updateTime()
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteQuestion({ index }: { index: number }) {
|
function deleteQuestion({ index }: { index: number }) {
|
||||||
|
pagingOperations('remove')
|
||||||
questionDataList.value.splice(index, 1)
|
questionDataList.value.splice(index, 1)
|
||||||
updateTime()
|
updateTime()
|
||||||
}
|
}
|
||||||
@ -266,6 +280,138 @@ function useCurrentEdit({
|
|||||||
changeCurrentEditStatus
|
changeCurrentEditStatus
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function usePagingEdit({
|
||||||
|
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;
|
||||||
|
})
|
||||||
|
const pagingCount = computed(() => pagingConf.value.length || 0)
|
||||||
|
|
||||||
|
const pagingQuestionData = computed(() => {
|
||||||
|
return getPagingQuestionData(pagingEditOne.value)
|
||||||
|
})
|
||||||
|
|
||||||
|
const getPagingQuestionData = (index:number) => {
|
||||||
|
const { startIndex, endIndex } = getSorter(index)
|
||||||
|
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];
|
||||||
|
|
||||||
|
for (let index = 0; index < pagingConf.value.length; index++) {
|
||||||
|
const item = pagingConf.value[index];
|
||||||
|
if ((newPagingEditOne - 1) == index) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
startIndex+=item
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
startIndex,
|
||||||
|
endIndex:startIndex + endIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const addPaging = () => {
|
||||||
|
schema.pagingConf.push(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatePagingEditOne = (index: number) => {
|
||||||
|
schema.pagingEditOne = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
const deletePaging = (index: number) => {
|
||||||
|
if (pagingConf.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)
|
||||||
|
questionDataList.value = newQuestion
|
||||||
|
updateTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
questionDataList.value = newQuestion
|
||||||
|
const rangeCount = schema.pagingConf[range-1]
|
||||||
|
schema.pagingConf[range-1] = schema.pagingConf[index-1]
|
||||||
|
schema.pagingConf[index - 1] = rangeCount;
|
||||||
|
updateTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
const copyPaging = (index: number) => {
|
||||||
|
|
||||||
|
const newQuestionList = _cloneDeep(getPagingQuestionData(index))
|
||||||
|
newQuestionList.forEach((item) => {
|
||||||
|
item.field = getNewField(questionDataList.value.map((item) => item.field))
|
||||||
|
})
|
||||||
|
schema.pagingConf.splice(index, 0, newQuestionList.length)
|
||||||
|
const { endIndex } = getSorter(index)
|
||||||
|
questionDataList.value.splice(endIndex, 0, ...newQuestionList)
|
||||||
|
updateTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
const pagingOperations = (type:string) => {
|
||||||
|
const count = pagingConf.value[pagingEditOne.value - 1];
|
||||||
|
if (type == 'add') {
|
||||||
|
if (count!=undefined) {
|
||||||
|
schema.pagingConf[pagingEditOne.value - 1] = count + 1; ;
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (type == 'remove') {
|
||||||
|
if (count) {
|
||||||
|
schema.pagingConf[pagingEditOne.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];
|
||||||
|
if (newIndex != oldIndex) {
|
||||||
|
schema.pagingConf[index] = newIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return {
|
||||||
|
pagingEditOne,
|
||||||
|
pagingConf,
|
||||||
|
isFinallyPage,
|
||||||
|
pagingCount,
|
||||||
|
pagingQuestionData,
|
||||||
|
getSorter,
|
||||||
|
updatePagingEditOne,
|
||||||
|
deletePaging,
|
||||||
|
addPaging,
|
||||||
|
copyPaging,
|
||||||
|
getPagingQuestionData,
|
||||||
|
pagingOperations,
|
||||||
|
swapArrayRanges,
|
||||||
|
setPaging
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
type IBannerItem = {
|
type IBannerItem = {
|
||||||
name: string
|
name: string
|
||||||
@ -325,11 +471,72 @@ export const useEditStore = defineStore('edit', () => {
|
|||||||
schemaUpdateTime.value = Date.now()
|
schemaUpdateTime.value = Date.now()
|
||||||
}
|
}
|
||||||
|
|
||||||
const { copyQuestion, addQuestion, deleteQuestion, moveQuestion } = useQuestionDataListOperations(
|
const { pagingEditOne, pagingConf, isFinallyPage, pagingCount, pagingQuestionData, getSorter,
|
||||||
questionDataList,
|
updatePagingEditOne, deletePaging,pagingOperations,addPaging,getPagingQuestionData,copyPaging,swapArrayRanges,setPaging }= usePagingEdit({ schema, questionDataList },updateTime)
|
||||||
updateTime
|
|
||||||
|
const { copyQuestion, addQuestion, deleteQuestion, moveQuestion} = useQuestionDataListOperations(
|
||||||
|
questionDataList,
|
||||||
|
updateTime,
|
||||||
|
pagingOperations
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
if (countTotal != newData.length) {
|
||||||
|
schema.pagingConf[pagingEditOne.value - 1] = schema.pagingConf[pagingEditOne.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 => {
|
||||||
|
newSeq.push(v.field)
|
||||||
|
});
|
||||||
|
(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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (status) {
|
||||||
|
setQuestionDataList(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const newQuestionIndex = computed(() => {
|
||||||
|
if (_isNumber(currentEditOne.value)) {
|
||||||
|
return currentEditOne.value + 1
|
||||||
|
} else {
|
||||||
|
const pagingConf = schema.pagingConf
|
||||||
|
const questCount = pagingConf[schema.pagingEditOne - 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 newQuestion = getQuestionByType(type, fields)
|
||||||
|
newQuestion.title = newQuestion.title = `标题${newQuestionIndex.value + 1}`
|
||||||
|
if (type === QUESTION_TYPE.VOTE) {
|
||||||
|
newQuestion.innerType = QUESTION_TYPE.RADIO
|
||||||
|
}
|
||||||
|
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()
|
||||||
@ -354,12 +561,27 @@ export const useEditStore = defineStore('edit', () => {
|
|||||||
currentEditKey,
|
currentEditKey,
|
||||||
currentEditStatus,
|
currentEditStatus,
|
||||||
currentEditMeta,
|
currentEditMeta,
|
||||||
|
newQuestionIndex,
|
||||||
setCurrentEditOne,
|
setCurrentEditOne,
|
||||||
changeCurrentEditStatus,
|
changeCurrentEditStatus,
|
||||||
|
pagingEditOne,
|
||||||
|
pagingConf,
|
||||||
|
isFinallyPage,
|
||||||
|
pagingCount,
|
||||||
|
pagingQuestionData,
|
||||||
|
getSorter,
|
||||||
|
updatePagingEditOne,
|
||||||
|
deletePaging,
|
||||||
|
addPaging,
|
||||||
|
getPagingQuestionData,
|
||||||
|
copyPaging,
|
||||||
|
swapArrayRanges,
|
||||||
|
setPaging,
|
||||||
schemaUpdateTime,
|
schemaUpdateTime,
|
||||||
schema,
|
schema,
|
||||||
questionDataList,
|
questionDataList,
|
||||||
setQuestionDataList,
|
setQuestionDataList,
|
||||||
|
moveQuestionDataList,
|
||||||
init,
|
init,
|
||||||
initSchema,
|
initSchema,
|
||||||
getSchemaFromRemote,
|
getSchemaFromRemote,
|
||||||
@ -367,7 +589,9 @@ export const useEditStore = defineStore('edit', () => {
|
|||||||
addQuestion,
|
addQuestion,
|
||||||
deleteQuestion,
|
deleteQuestion,
|
||||||
moveQuestion,
|
moveQuestion,
|
||||||
|
createNewQuestion,
|
||||||
changeSchema,
|
changeSchema,
|
||||||
changeThemePreset
|
changeThemePreset,
|
||||||
|
compareQuestionSeq
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -10,6 +10,7 @@ export default defineComponent({
|
|||||||
type: Object,
|
type: Object,
|
||||||
default: () => ({})
|
default: () => ({})
|
||||||
},
|
},
|
||||||
|
isFinallyPage: Boolean,
|
||||||
readonly: Boolean,
|
readonly: Boolean,
|
||||||
validate: Function,
|
validate: Function,
|
||||||
renderData: Array
|
renderData: Array
|
||||||
@ -41,11 +42,11 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
render() {
|
render() {
|
||||||
const { submitConf } = this.props
|
const { submitConf,isFinallyPage } = this.props
|
||||||
return (
|
return (
|
||||||
<div class={['submit-warp', 'preview-submit_wrapper']} onClick={this.handleClick}>
|
<div class={['submit-warp', 'preview-submit_wrapper']} onClick={this.handleClick}>
|
||||||
<button class="submit-btn" type="primary" onClick={this.submit}>
|
<button class="submit-btn" type="primary" onClick={this.submit}>
|
||||||
{submitConf.submitTitle}
|
{isFinallyPage ? submitConf.submitTitle : '下一页'}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -16,7 +16,7 @@ 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 } =
|
const { bannerConf, baseConf, bottomConf, dataConf, skinConf, submitConf, logicConf,pagingConf } =
|
||||||
data.code
|
data.code
|
||||||
const questionData = {
|
const questionData = {
|
||||||
bannerConf,
|
bannerConf,
|
||||||
@ -24,7 +24,12 @@ const loadData = (res: any, surveyPath: string) => {
|
|||||||
bottomConf,
|
bottomConf,
|
||||||
dataConf,
|
dataConf,
|
||||||
skinConf,
|
skinConf,
|
||||||
submitConf
|
submitConf,
|
||||||
|
pagingConf
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!pagingConf || pagingConf?.length == 0){
|
||||||
|
questionData.pagingConf = [dataConf.dataList.length]
|
||||||
}
|
}
|
||||||
|
|
||||||
document.title = data.title
|
document.title = data.title
|
||||||
|
@ -2,14 +2,15 @@
|
|||||||
<div class="index">
|
<div class="index">
|
||||||
<ProgressBar />
|
<ProgressBar />
|
||||||
<div class="wrapper" ref="boxRef">
|
<div class="wrapper" ref="boxRef">
|
||||||
<HeaderContent :bannerConf="bannerConf" :readonly="true" />
|
<HeaderContent v-if="pagingIndex==1" :bannerConf="bannerConf" :readonly="true" />
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<MainTitle :bannerConf="bannerConf" :readonly="true"></MainTitle>
|
<MainTitle v-if="pagingIndex==1" :bannerConf="bannerConf" :readonly="true"></MainTitle>
|
||||||
<MainRenderer ref="mainRef"></MainRenderer>
|
<MainRenderer ref="mainRef"></MainRenderer>
|
||||||
<SubmitButton
|
<SubmitButton
|
||||||
:validate="validate"
|
:validate="validate"
|
||||||
:submitConf="submitConf"
|
:submitConf="submitConf"
|
||||||
:readonly="true"
|
:readonly="true"
|
||||||
|
:isFinallyPage="isFinallyPage"
|
||||||
:renderData="renderData"
|
:renderData="renderData"
|
||||||
@submit="handleSubmit"
|
@submit="handleSubmit"
|
||||||
></SubmitButton>
|
></SubmitButton>
|
||||||
@ -61,14 +62,11 @@ 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 {
|
const isFinallyPage = computed(() => questionStore.isFinallyPage)
|
||||||
bannerConf,
|
const pagingIndex = computed(() => questionStore.pagingIndex)
|
||||||
submitConf,
|
const { bannerConf, submitConf, bottomConf: logoConf, whiteData } = storeToRefs(surveyStore)
|
||||||
bottomConf: logoConf,
|
const surveyPath = computed(() => surveyStore.surveyPath || '')
|
||||||
whiteData,
|
|
||||||
} = storeToRefs(surveyStore);
|
|
||||||
const surveyPath = computed(() => surveyStore.surveyPath || "");
|
|
||||||
|
|
||||||
const validate = (cbk: (v: boolean) => void) => {
|
const validate = (cbk: (v: boolean) => void) => {
|
||||||
const index = 0;
|
const index = 0;
|
||||||
@ -126,9 +124,12 @@ const submitSurver = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
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) {
|
||||||
|
questionStore.addPagingIndex();
|
||||||
|
return
|
||||||
|
}
|
||||||
if (is_again) {
|
if (is_again) {
|
||||||
confirm({
|
confirm({
|
||||||
title: again_text,
|
title: again_text,
|
||||||
|
@ -10,9 +10,10 @@ 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 renderData = computed(() => {
|
const questionList = computed(() => {
|
||||||
let index = 1
|
let index = 1
|
||||||
return (
|
return (
|
||||||
questionSeq.value &&
|
questionSeq.value &&
|
||||||
@ -38,6 +39,41 @@ 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 isFinallyPage = computed(() => {
|
||||||
|
const surveyStore = useSurveyStore()
|
||||||
|
return pagingIndex.value === surveyStore.pagingConf.length;
|
||||||
|
})
|
||||||
|
|
||||||
|
const addPagingIndex = () => {
|
||||||
|
pagingIndex.value++
|
||||||
|
}
|
||||||
|
|
||||||
|
const getSorter = () => {
|
||||||
|
let startIndex = 0;
|
||||||
|
const surveyStore = useSurveyStore()
|
||||||
|
const newPagingEditOne = pagingIndex.value;
|
||||||
|
const endIndex = surveyStore.pagingConf[newPagingEditOne - 1];
|
||||||
|
|
||||||
|
for (let index = 0; index < surveyStore.pagingConf.length; index++) {
|
||||||
|
const item = surveyStore.pagingConf[index];
|
||||||
|
if ((newPagingEditOne - 1) == index) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
startIndex+=item
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
startIndex,
|
||||||
|
endIndex:startIndex + endIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const setQuestionData = (data) => {
|
const setQuestionData = (data) => {
|
||||||
questionData.value = data
|
questionData.value = data
|
||||||
}
|
}
|
||||||
@ -146,6 +182,9 @@ export const useQuestionStore = defineStore('question', () => {
|
|||||||
questionData,
|
questionData,
|
||||||
questionSeq,
|
questionSeq,
|
||||||
renderData,
|
renderData,
|
||||||
|
isFinallyPage,
|
||||||
|
pagingIndex,
|
||||||
|
addPagingIndex,
|
||||||
setQuestionData,
|
setQuestionData,
|
||||||
changeSelectMoreData,
|
changeSelectMoreData,
|
||||||
setQuestionSeq,
|
setQuestionSeq,
|
||||||
|
@ -38,6 +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 router = useRouter()
|
const router = useRouter()
|
||||||
const questionStore = useQuestionStore()
|
const questionStore = useQuestionStore()
|
||||||
@ -127,10 +128,10 @@ export const useSurveyStore = defineStore('survey', () => {
|
|||||||
'dataConf',
|
'dataConf',
|
||||||
'skinConf',
|
'skinConf',
|
||||||
'submitConf',
|
'submitConf',
|
||||||
'whiteData'
|
'whiteData',
|
||||||
|
"pagingConf"
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
|
|
||||||
questionStore.questionData = questionData
|
questionStore.questionData = questionData
|
||||||
questionStore.questionSeq = questionSeq
|
questionStore.questionSeq = questionSeq
|
||||||
|
|
||||||
@ -144,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
|
||||||
// 获取已投票数据
|
// 获取已投票数据
|
||||||
questionStore.initVoteData()
|
questionStore.initVoteData()
|
||||||
}
|
}
|
||||||
@ -171,6 +172,7 @@ export const useSurveyStore = defineStore('survey', () => {
|
|||||||
submitConf,
|
submitConf,
|
||||||
formValues,
|
formValues,
|
||||||
whiteData,
|
whiteData,
|
||||||
|
pagingConf,
|
||||||
|
|
||||||
initSurvey,
|
initSurvey,
|
||||||
changeData,
|
changeData,
|
||||||
|
Loading…
Reference in New Issue
Block a user