feat: 整卷增加基础配置:必填、显示类型、显示序号、显示分割线 (#391)
* feat: 增加整卷配置功能 * fix: 限制单题修改配置时只对基础配置进行更新全局基础配置操作 --------- Co-authored-by: jiangchunfu <jiangchunfu@kaike.la>
This commit is contained in:
parent
28591f00a3
commit
624308bae8
@ -1,37 +1,51 @@
|
||||
<template>
|
||||
<div class="setter-wrapper">
|
||||
<div class="no-select-question" v-if="currentEditOne === null">
|
||||
<div class="no-select-question" v-if="editStore.currentEditOne === null">
|
||||
<img src="/imgs/icons/unselected.webp" />
|
||||
<h4 class="tipFont">选中题型可以编辑</h4>
|
||||
<span class="tip">来!试试看~</span>
|
||||
</div>
|
||||
<template v-else>
|
||||
<div class="setter-title">{{ currentEditMeta?.title || '' }}</div>
|
||||
<SetterField
|
||||
class="question-config-form"
|
||||
:form-config-list="formConfigList"
|
||||
:module-config="moduleConfig"
|
||||
@form-change="handleFormChange"
|
||||
/>
|
||||
</template>
|
||||
<el-tabs v-else v-model="confType" type="border-card" stretch>
|
||||
<el-tab-pane name="baseConf" label="单题设置">
|
||||
<div class="setter-title">{{ currentEditMeta?.title || '' }}</div>
|
||||
<SetterField
|
||||
:form-config-list="formConfigList"
|
||||
:module-config="moduleConfig"
|
||||
@form-change="handleFormChange"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="globalBaseConf" label="整卷设置">
|
||||
<SetterField
|
||||
:form-config-list="[basicConfig]"
|
||||
:module-config="editStore.editGlobalBaseConf.globalBaseConfig"
|
||||
@form-change="editStore.editGlobalBaseConf.updateGlobalConfOption"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
import { useEditStore } from '@/management/stores/edit'
|
||||
|
||||
import basicConfig from '@/materials/questions/common/config/basicConfig'
|
||||
import SetterField from '@/management/pages/edit/components/SetterField.vue'
|
||||
|
||||
const confType = ref('baseConf')
|
||||
const editStore = useEditStore()
|
||||
const { currentEditOne, currentEditKey, currentEditMeta, formConfigList, moduleConfig } =
|
||||
storeToRefs(editStore)
|
||||
|
||||
const { currentEditKey, currentEditMeta, formConfigList, moduleConfig } = storeToRefs(editStore)
|
||||
const { changeSchema } = editStore
|
||||
const handleFormChange = (data: any) => {
|
||||
const { key, value } = data
|
||||
const resultKey = `${currentEditKey.value}.${key}`
|
||||
changeSchema({ key: resultKey, value })
|
||||
if (key in editStore.editGlobalBaseConf.globalBaseConfig)
|
||||
editStore.editGlobalBaseConf.updateCounts('MODIFY', { key, value })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.setter-wrapper {
|
||||
width: 360px;
|
||||
@ -39,36 +53,53 @@ const handleFormChange = (data: any) => {
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
background-color: #fff;
|
||||
}
|
||||
.no-select-question {
|
||||
padding-top: 125px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.setter-title {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
font-size: 14px;
|
||||
color: $primary-color;
|
||||
padding-left: 20px;
|
||||
border-bottom: 1px solid #edeffc;
|
||||
}
|
||||
img {
|
||||
width: 160px;
|
||||
padding: 25px;
|
||||
}
|
||||
|
||||
.no-select-question {
|
||||
padding-top: 125px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
width: 160px;
|
||||
padding: 25px;
|
||||
.tip {
|
||||
font-size: 14px;
|
||||
color: $normal-color;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.tip {
|
||||
.setter-title {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
font-size: 14px;
|
||||
color: $normal-color;
|
||||
letter-spacing: 0;
|
||||
color: $primary-color;
|
||||
padding-left: 20px;
|
||||
border-bottom: 1px solid #edeffc;
|
||||
}
|
||||
}
|
||||
|
||||
.question-config-form {
|
||||
padding: 30px 20px 50px 20px;
|
||||
:deep(.el-tabs) {
|
||||
width: 360px;
|
||||
height: 100%;
|
||||
border: none;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.el-tabs__nav {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.el-tabs__content {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 0;
|
||||
|
||||
.config-form {
|
||||
padding: 30px 20px 50px 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -0,0 +1,91 @@
|
||||
import { reactive, type Ref } from 'vue'
|
||||
|
||||
export type TypeMethod = 'INIT' | 'MODIFY' | 'REMOVE' | 'ADD'
|
||||
|
||||
export default function useEditGlobalBaseConf(
|
||||
questionDetailList: Ref<any[]>,
|
||||
updateTime: () => void
|
||||
) {
|
||||
// 整卷配置数据
|
||||
const globalBaseConfig = reactive({
|
||||
isRequired: true,
|
||||
showIndex: true,
|
||||
showType: true,
|
||||
showSpliter: true
|
||||
})
|
||||
|
||||
// 整卷配置各项选项选中个数统计
|
||||
const optionCheckedCounts = {
|
||||
isRequiredCount: 0,
|
||||
showIndexCount: 0,
|
||||
showTypeCount: 0,
|
||||
showSpliterCount: 0
|
||||
}
|
||||
|
||||
// 初始化统计
|
||||
function initCounts() {
|
||||
questionDetailList.value.forEach((question: any) => {
|
||||
calculateCountsForQuestion('INIT', { question })
|
||||
})
|
||||
updateGlobalBaseConf()
|
||||
}
|
||||
|
||||
// 更新统计
|
||||
function updateCounts(type: TypeMethod, data: any) {
|
||||
if (type === 'MODIFY') {
|
||||
calculateOptionCounts(type, data)
|
||||
} else {
|
||||
calculateCountsForQuestion(type, data)
|
||||
}
|
||||
updateGlobalBaseConf()
|
||||
}
|
||||
|
||||
// 计算整卷配置各项选项选中个数
|
||||
function calculateCountsForQuestion(type: TypeMethod, { question }: any) {
|
||||
Object.keys(globalBaseConfig).forEach((key) => {
|
||||
calculateOptionCounts(type, { key, value: question[key] })
|
||||
})
|
||||
}
|
||||
|
||||
// 计算单个选项选中个数
|
||||
function calculateOptionCounts(type: TypeMethod, { key, value }: any) {
|
||||
const _key = `${key}Count` as keyof typeof optionCheckedCounts
|
||||
if (value) {
|
||||
if (type === 'REMOVE') optionCheckedCounts[_key]--
|
||||
else optionCheckedCounts[_key]++
|
||||
} else {
|
||||
if (type === 'MODIFY') optionCheckedCounts[_key]--
|
||||
}
|
||||
}
|
||||
|
||||
// 更新整卷配置状态
|
||||
function updateGlobalBaseConf() {
|
||||
const len = questionDetailList.value.length
|
||||
const { isRequiredCount, showIndexCount, showSpliterCount, showTypeCount } = optionCheckedCounts
|
||||
Object.assign(globalBaseConfig, {
|
||||
isRequired: isRequiredCount === len,
|
||||
showIndex: showIndexCount === len,
|
||||
showSpliter: showSpliterCount === len,
|
||||
showType: showTypeCount === len
|
||||
})
|
||||
}
|
||||
|
||||
// 整卷配置修改
|
||||
function updateGlobalConfOption({ key, value }: { key: string; value: boolean }) {
|
||||
const len = questionDetailList.value.length
|
||||
const _key = `${key}Count` as keyof typeof optionCheckedCounts
|
||||
if (value) optionCheckedCounts[_key] = len
|
||||
else optionCheckedCounts[_key] = 0
|
||||
questionDetailList.value.forEach((question: any) => {
|
||||
question[key] = value
|
||||
})
|
||||
updateTime()
|
||||
}
|
||||
|
||||
return {
|
||||
globalBaseConfig,
|
||||
initCounts,
|
||||
updateCounts,
|
||||
updateGlobalConfOption
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@ import questionLoader from '@/materials/questions/questionLoader'
|
||||
import { SurveyPermissions } from '@/management/utils/types/workSpace'
|
||||
import { getBannerData } from '@/management/api/skin.js'
|
||||
import { getCollaboratorPermissions } from '@/management/api/space'
|
||||
import useEditGlobalBaseConf, { type TypeMethod } from './composables/useEditGlobalBaseConf'
|
||||
import { CODE_MAP } from '../api/base'
|
||||
|
||||
const innerMetaConfig = {
|
||||
@ -28,7 +29,7 @@ const innerMetaConfig = {
|
||||
}
|
||||
}
|
||||
|
||||
function useInitializeSchema(surveyId: Ref<string>) {
|
||||
function useInitializeSchema(surveyId: Ref<string>, initializeSchemaCallBack: () => void) {
|
||||
const schema = reactive({
|
||||
metaData: null,
|
||||
bannerConf: {
|
||||
@ -130,6 +131,7 @@ function useInitializeSchema(surveyId: Ref<string>) {
|
||||
logicConf
|
||||
}
|
||||
})
|
||||
initializeSchemaCallBack()
|
||||
} else {
|
||||
throw new Error(res.errmsg || '问卷不存在')
|
||||
}
|
||||
@ -142,11 +144,17 @@ function useInitializeSchema(surveyId: Ref<string>) {
|
||||
}
|
||||
}
|
||||
|
||||
function useQuestionDataListOperations(
|
||||
questionDataList: Ref<any[]>,
|
||||
updateTime: () => void,
|
||||
function useQuestionDataListOperations({
|
||||
questionDataList,
|
||||
updateTime,
|
||||
pageOperations,
|
||||
updateCounts
|
||||
}: {
|
||||
questionDataList: Ref<any[]>
|
||||
updateTime: () => void
|
||||
pageOperations: (type: string) => void
|
||||
) {
|
||||
updateCounts: (type: TypeMethod, data: any) => void
|
||||
}) {
|
||||
function copyQuestion({ index }: { index: number }) {
|
||||
const newQuestion = _cloneDeep(questionDataList.value[index])
|
||||
newQuestion.field = getNewField(questionDataList.value.map((item) => item.field))
|
||||
@ -157,12 +165,14 @@ function useQuestionDataListOperations(
|
||||
questionDataList.value.splice(index, 0, question)
|
||||
pageOperations('add')
|
||||
updateTime()
|
||||
updateCounts('ADD', { question })
|
||||
}
|
||||
|
||||
function deleteQuestion({ index }: { index: number }) {
|
||||
pageOperations('remove')
|
||||
questionDataList.value.splice(index, 1)
|
||||
const [question] = questionDataList.value.splice(index, 1)
|
||||
updateTime()
|
||||
updateCounts('REMOVE', { question })
|
||||
}
|
||||
|
||||
function moveQuestion({ index, range }: { index: number; range: number }) {
|
||||
@ -432,9 +442,13 @@ export const useEditStore = defineStore('edit', () => {
|
||||
const bannerList: Ref<IBannerList> = ref({})
|
||||
const cooperPermissions = ref(Object.values(SurveyPermissions))
|
||||
const schemaUpdateTime = ref(Date.now())
|
||||
const { schema, initSchema, getSchemaFromRemote } = useInitializeSchema(surveyId)
|
||||
const { schema, initSchema, getSchemaFromRemote } = useInitializeSchema(surveyId, () => {
|
||||
editGlobalBaseConf.initCounts()
|
||||
})
|
||||
const questionDataList = toRef(schema, 'questionDataList')
|
||||
|
||||
const editGlobalBaseConf = useEditGlobalBaseConf(questionDataList, updateTime)
|
||||
|
||||
function setQuestionDataList(data: any) {
|
||||
schema.questionDataList = data
|
||||
}
|
||||
@ -497,9 +511,12 @@ export const useEditStore = defineStore('edit', () => {
|
||||
} = usePageEdit({ schema, questionDataList }, updateTime)
|
||||
|
||||
const { copyQuestion, addQuestion, deleteQuestion, moveQuestion } = useQuestionDataListOperations(
|
||||
questionDataList,
|
||||
updateTime,
|
||||
pageOperations
|
||||
{
|
||||
questionDataList,
|
||||
updateTime,
|
||||
pageOperations,
|
||||
updateCounts: editGlobalBaseConf.updateCounts
|
||||
}
|
||||
)
|
||||
|
||||
function moveQuestionDataList(data: any) {
|
||||
@ -575,6 +592,7 @@ export const useEditStore = defineStore('edit', () => {
|
||||
}
|
||||
|
||||
return {
|
||||
editGlobalBaseConf,
|
||||
surveyId,
|
||||
setSurveyId,
|
||||
bannerList,
|
||||
|
Loading…
Reference in New Issue
Block a user