feat: 答题页相关vuex迁移pinia (#341)

This commit is contained in:
hiStephen 2024-07-16 10:56:39 +08:00 committed by GitHub
parent f08c8bcd2a
commit 09866663f2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 306 additions and 138 deletions

View File

@ -16,10 +16,12 @@ import { computed } from 'vue'
import { useStore } from 'vuex' import { useStore } from 'vuex'
import MaterialGroup from './MaterialGroup.vue' import MaterialGroup from './MaterialGroup.vue'
import { useQuestionStore } from '../stores/question'
const store = useStore() const store = useStore()
const questionStore = useQuestionStore()
const renderData = computed(() => store.getters?.renderData) const renderData = computed(() => questionStore.renderData)
const rules = computed(() => store.state.rules) const rules = computed(() => store.state.rules)
const formValues = computed(() => store.state.formValues) const formValues = computed(() => store.state.formValues)

View File

@ -16,6 +16,7 @@ import { useShowInput } from '@/render/hooks/useShowInput'
import store from '@/render/store' import store from '@/render/store'
import { cloneDeep } from 'lodash-es' import { cloneDeep } from 'lodash-es'
import { ruleEngine } from '@/render/hooks/useRuleEngine.js' import { ruleEngine } from '@/render/hooks/useRuleEngine.js'
import { useQuestionStore } from '../stores/question'
import { NORMAL_CHOICES, RATES, QUESTION_TYPE } from '@/common/typeEnum.ts' import { NORMAL_CHOICES, RATES, QUESTION_TYPE } from '@/common/typeEnum.ts'
@ -32,6 +33,7 @@ const props = defineProps({
} }
}) })
const emit = defineEmits(['change']) const emit = defineEmits(['change'])
const questionStore = useQuestionStore()
const formValues = computed(() => { const formValues = computed(() => {
return store.state.formValues return store.state.formValues
@ -105,7 +107,7 @@ const handleChange = (data) => {
emit('change', data) emit('change', data)
// //
if (props.moduleConfig.type === QUESTION_TYPE.VOTE) { if (props.moduleConfig.type === QUESTION_TYPE.VOTE) {
store.dispatch('updateVoteData', data) questionStore.updateVoteData(data)
} }
} }
</script> </script>

View File

@ -1,8 +1,11 @@
import store from '../store/index' import store from '../store/index'
import { useQuestionStore } from '../stores/question'
export const useShowInput = (questionKey) => { export const useShowInput = (questionKey) => {
const questionStore = useQuestionStore()
const formValues = store.state.formValues const formValues = store.state.formValues
const questionVal = formValues[questionKey] const questionVal = formValues[questionKey]
let rangeConfig = store.state.questionData[questionKey].rangeConfig let rangeConfig = questionStore.questionData[questionKey].rangeConfig
let othersValue = {} let othersValue = {}
if (rangeConfig && Object.keys(rangeConfig).length > 0) { if (rangeConfig && Object.keys(rangeConfig).length > 0) {
for (let key in rangeConfig) { for (let key in rangeConfig) {

View File

@ -1,9 +1,12 @@
import store from '../store/index' import store from '../store/index'
import { useQuestionStore } from '../stores/question'
export const useShowOthers = (questionKey) => { export const useShowOthers = (questionKey) => {
const questionStore = useQuestionStore()
const formValues = store.state.formValues const formValues = store.state.formValues
const questionVal = formValues[questionKey] const questionVal = formValues[questionKey]
let othersValue = {} let othersValue = {}
let options = store.state.questionData[questionKey].options.map((optionItem) => { let options = questionStore.questionData[questionKey].options.map((optionItem) => {
if (optionItem.others) { if (optionItem.others) {
const opKey = `${questionKey}_${optionItem.hash}` const opKey = `${questionKey}_${optionItem.hash}`
othersValue[opKey] = formValues[opKey] othersValue[opKey] = formValues[opKey]

View File

@ -1,10 +1,12 @@
import store from '../store/index' import { useQuestionStore } from '../stores/question'
export const useVoteMap = (questionKey) => {
let voteTotal = store.state.voteMap?.[questionKey]?.total || 0
const options = store.state.questionData[questionKey].options.map((option) => { export const useVoteMap = (questionKey) => {
const questionStore = useQuestionStore()
let voteTotal = questionStore.voteMap?.[questionKey]?.total || 0
const options = questionStore.questionData[questionKey].options.map((option) => {
const optionHash = option.hash const optionHash = option.hash
const voteCount = store.state.voteMap?.[questionKey]?.[optionHash] || 0 const voteCount = questionStore.voteMap?.[questionKey]?.[optionHash] || 0
return { return {
...option, ...option,

View File

@ -30,6 +30,7 @@ import ConfirmDialog from '../components/ConfirmDialog.vue'
import ProgressBar from '../components/ProgressBar.vue' import ProgressBar from '../components/ProgressBar.vue'
import { useSurveyStore } from '../stores/survey' import { useSurveyStore } from '../stores/survey'
import { useQuestionStore } from '../stores/question'
import { submitForm } from '../api/survey' import { submitForm } from '../api/survey'
import encrypt from '../utils/encrypt' import encrypt from '../utils/encrypt'
@ -59,9 +60,10 @@ const confirm = useCommandComponent(ConfirmDialog)
const store = useStore() const store = useStore()
const router = useRouter() const router = useRouter()
const surveyStore = useSurveyStore() const surveyStore = useSurveyStore()
const questionStore = useQuestionStore()
const bannerConf = computed(() => store.state?.bannerConf || {}) const bannerConf = computed(() => store.state?.bannerConf || {})
const renderData = computed(() => store.getters.renderData) const renderData = computed(() => questionStore.renderData)
const submitConf = computed(() => store.state?.submitConf || {}) const submitConf = computed(() => store.state?.submitConf || {})
const logoConf = computed(() => store.state?.bottomConf || {}) const logoConf = computed(() => store.state?.bottomConf || {})
const surveyPath = computed(() => surveyStore.surveyPath || '') const surveyPath = computed(() => surveyStore.surveyPath || '')

View File

@ -4,9 +4,10 @@ import 'moment/locale/zh-cn'
// 设置中文 // 设置中文
moment.locale('zh-cn') moment.locale('zh-cn')
import adapter from '../adapter' import adapter from '../adapter'
import { queryVote } from '@/render/api/survey' // import { queryVote } from '@/render/api/survey'
import { RuleMatch } from '@/common/logicEngine/RulesMatch' import { RuleMatch } from '@/common/logicEngine/RulesMatch'
import { useSurveyStore } from '@/render/stores/survey' import { useSurveyStore } from '@/render/stores/survey'
import { useQuestionStore } from '@/render/stores/question'
/** /**
* CODE_MAP不从management引入在dev阶段会导致B端 router被加载进而导致C端路由被添加 baseUrl: /management * CODE_MAP不从management引入在dev阶段会导致B端 router被加载进而导致C端路由被添加 baseUrl: /management
*/ */
@ -15,12 +16,13 @@ import { useSurveyStore } from '@/render/stores/survey'
// ERROR: 500, // ERROR: 500,
// NO_AUTH: 403 // NO_AUTH: 403
// } // }
const VOTE_INFO_KEY = 'voteinfo' // const VOTE_INFO_KEY = 'voteinfo'
import router from '../router' import router from '../router'
export default { export default {
// 初始化 // 初始化
init({ commit, dispatch }, { bannerConf, baseConf, bottomConf, dataConf, skinConf, submitConf }) { init({ commit }, { bannerConf, baseConf, bottomConf, dataConf, skinConf, submitConf }) {
const surveyStore = useSurveyStore() const surveyStore = useSurveyStore()
const questionStore = useQuestionStore()
surveyStore.setEnterTime() surveyStore.setEnterTime()
const { begTime, endTime, answerBegTime, answerEndTime } = baseConf const { begTime, endTime, answerBegTime, answerEndTime } = baseConf
const { msgContent } = submitConf const { msgContent } = submitConf
@ -67,10 +69,11 @@ export default {
submitConf submitConf
}) })
questionStore.questionData = questionData
questionStore.questionSeq = questionSeq
// 将数据设置到state上 // 将数据设置到state上
commit('assignState', { commit('assignState', {
questionData,
questionSeq,
rules, rules,
bannerConf, bannerConf,
baseConf, baseConf,
@ -81,88 +84,90 @@ export default {
formValues formValues
}) })
// 获取已投票数据 // 获取已投票数据
dispatch('initVoteData') questionStore.initVoteData()
}, },
// 用户输入或者选择后,更新表单数据 // 用户输入或者选择后,更新表单数据
changeData({ commit }, data) { changeData({ commit }, data) {
commit('changeFormData', data) commit('changeFormData', data)
}, },
// 初始化投票题的数据 // 初始化投票题的数据
async initVoteData({ state, commit }) { // async initVoteData({ state, commit }) {
const surveyStore = useSurveyStore() // const surveyStore = useSurveyStore()
const questionData = state.questionData // const questionStore = useQuestionStore()
const surveyPath = surveyStore.surveyPath // const questionData = questionStore.questionData
// const surveyPath = surveyStore.surveyPath
const fieldList = [] // const fieldList = []
for (const field in questionData) { // for (const field in questionData) {
const { type } = questionData[field] // const { type } = questionData[field]
if (/vote/.test(type)) { // if (/vote/.test(type)) {
fieldList.push(field) // fieldList.push(field)
} // }
} // }
if (fieldList.length <= 0) { // if (fieldList.length <= 0) {
return // return
} // }
try { // try {
localStorage.removeItem(VOTE_INFO_KEY) // localStorage.removeItem(VOTE_INFO_KEY)
const voteRes = await queryVote({ // const voteRes = await queryVote({
surveyPath, // surveyPath,
fieldList: fieldList.join(',') // fieldList: fieldList.join(',')
}) // })
if (voteRes.code === 200) { // if (voteRes.code === 200) {
localStorage.setItem( // localStorage.setItem(
VOTE_INFO_KEY, // VOTE_INFO_KEY,
JSON.stringify({ // JSON.stringify({
...voteRes.data // ...voteRes.data
}) // })
) // )
commit('setVoteMap', voteRes.data) // questionStore.setVoteMap(voteRes.data)
} // }
} catch (error) { // } catch (error) {
console.log(error) // console.log(error)
} // }
}, // },
updateVoteData({ state, commit }, data) { // updateVoteData({ state, commit }, data) {
const { key: questionKey, value: questionVal } = data // const questionStore = useQuestionStore()
// 更新前获取接口缓存在localStorage中的数据 // const { key: questionKey, value: questionVal } = data
const localData = localStorage.getItem(VOTE_INFO_KEY) // // 更新前获取接口缓存在localStorage中的数据
const voteinfo = JSON.parse(localData) // const localData = localStorage.getItem(VOTE_INFO_KEY)
const currentQuestion = state.questionData[questionKey] // const voteinfo = JSON.parse(localData)
const options = currentQuestion.options // const currentQuestion = questionStore.questionData[questionKey]
const voteTotal = voteinfo?.[questionKey]?.total || 0 // const options = currentQuestion.options
let totalPayload = { // const voteTotal = voteinfo?.[questionKey]?.total || 0
questionKey, // let totalPayload = {
voteKey: 'total', // questionKey,
voteValue: voteTotal // voteKey: 'total',
} // voteValue: voteTotal
options.forEach((option) => { // }
const optionhash = option.hash // options.forEach((option) => {
const voteCount = voteinfo?.[questionKey]?.[optionhash] || 0 // const optionhash = option.hash
// 如果选中值包含该选项对应voteCount 和 voteTotal + 1 // const voteCount = voteinfo?.[questionKey]?.[optionhash] || 0
if ( // // 如果选中值包含该选项对应voteCount 和 voteTotal + 1
Array.isArray(questionVal) ? questionVal.includes(optionhash) : questionVal === optionhash // if (
) { // Array.isArray(questionVal) ? questionVal.includes(optionhash) : questionVal === optionhash
const countPayload = { // ) {
questionKey, // const countPayload = {
voteKey: optionhash, // questionKey,
voteValue: voteCount + 1 // voteKey: optionhash,
} // voteValue: voteCount + 1
totalPayload.voteValue += 1 // }
commit('updateVoteMapByKey', countPayload) // totalPayload.voteValue += 1
} else { // questionStore.updateVoteMapByKey(countPayload)
const countPayload = { // } else {
questionKey, // const countPayload = {
voteKey: optionhash, // questionKey,
voteValue: voteCount // voteKey: optionhash,
} // voteValue: voteCount
commit('updateVoteMapByKey', countPayload) // }
} // questionStore.updateVoteMapByKey(countPayload)
commit('updateVoteMapByKey', totalPayload) // }
}) // questionStore.updateVoteMapByKey(totalPayload)
}, // })
// },
// async getEncryptInfo({ commit }) { // async getEncryptInfo({ commit }) {
// try { // try {
// const res = await getEncryptInfo() // const res = await getEncryptInfo()

View File

@ -1,30 +1,25 @@
export default { export default {
// 题目列表 // 题目列表
renderData: (state) => { // renderData: (state) => {
const { questionSeq, questionData } = state // const { questionSeq, questionData } = state
// let index = 1
let index = 1 // return (
return ( // questionSeq &&
questionSeq && // questionSeq.reduce((pre, item) => {
questionSeq.reduce((pre, item) => { // const questionArr = []
const questionArr = [] // item.forEach((questionKey) => {
// const question = { ...questionData[questionKey] }
item.forEach((questionKey) => { // // 开启显示序号
const question = { ...questionData[questionKey] } // if (question.showIndex) {
// 开启显示序号 // question.indexNumber = index++
if (question.showIndex) { // }
question.indexNumber = index++ // questionArr.push(question)
} // })
// if (questionArr && questionArr.length) {
questionArr.push(question) // pre.push(questionArr)
}) // }
// return pre
if (questionArr && questionArr.length) { // }, [])
pre.push(questionArr) // )
} // }
return pre
}, [])
)
}
} }

View File

@ -6,9 +6,6 @@ export default {
state[key] = value state[key] = value
}) })
}, },
setQuestionData(state, data) {
state.questionData = data
},
setErrorInfo(state, { errorType, errorMsg }) { setErrorInfo(state, { errorType, errorMsg }) {
state.errorInfo = { state.errorInfo = {
errorType, errorType,
@ -20,30 +17,30 @@ export default {
// console.log('formValues', key, value) // console.log('formValues', key, value)
set(state, `formValues.${key}`, value) set(state, `formValues.${key}`, value)
}, },
changeSelectMoreData(state, data) { // changeSelectMoreData(state, data) {
const { key, value, field } = data // const { key, value, field } = data
set(state, `questionData.${field}.othersValue.${key}`, value) // set(state, `questionData.${field}.othersValue.${key}`, value)
}, // },
// setEnterTime(state) { // setEnterTime(state) {
// state.enterTime = Date.now() // state.enterTime = Date.now()
// }, // },
// setSurveyPath(state, data) { // setSurveyPath(state, data) {
// state.surveyPath = data // state.surveyPath = data
// }, // },
setVoteMap(state, data) { // setVoteMap(state, data) {
state.voteMap = data // state.voteMap = data
}, // },
updateVoteMapByKey(state, data) { // updateVoteMapByKey(state, data) {
const { questionKey, voteKey, voteValue } = data // const { questionKey, voteKey, voteValue } = data
// 兼容为空的情况 // // 兼容为空的情况
if (!state.voteMap[questionKey]) { // if (!state.voteMap[questionKey]) {
state.voteMap[questionKey] = {} // state.voteMap[questionKey] = {}
} // }
state.voteMap[questionKey][voteKey] = voteValue // state.voteMap[questionKey][voteKey] = voteValue
}, // },
setQuestionSeq(state, data) { // setQuestionSeq(state, data) {
state.questionSeq = data // state.questionSeq = data
}, // },
// setEncryptInfo(state, data) { // setEncryptInfo(state, data) {
// state.encryptInfo = data // state.encryptInfo = data
// }, // },

View File

@ -2,15 +2,15 @@
export default { export default {
// surveyPath: '', // surveyPath: '',
questionData: null, // questionData: null,
// isMobile: isMobile(), // isMobile: isMobile(),
errorInfo: { errorInfo: {
errorType: '', errorType: '',
errorMsg: '' errorMsg: ''
}, },
// enterTime: null, // enterTime: null,
questionSeq: [], // 题目的顺序,因为可能会有分页的情况,所以是一个二维数组[[qid1, qid2], [qid3,qid4]] // questionSeq: [], // 题目的顺序,因为可能会有分页的情况,所以是一个二维数组[[qid1, qid2], [qid3,qid4]]
voteMap: {}, // voteMap: {},
// encryptInfo: null, // encryptInfo: null,
ruleEngine: null ruleEngine: null
} }

View File

@ -0,0 +1,157 @@
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
import { set } from 'lodash-es'
import { useSurveyStore } from '@/render/stores/survey'
import { queryVote } from '@/render/api/survey'
const VOTE_INFO_KEY = 'voteinfo'
export const useQuestionStore = defineStore('question', () => {
const voteMap = ref({})
const questionData = ref(null)
const questionSeq = ref([]) // 题目的顺序,因为可能会有分页的情况,所以是一个二维数组[[qid1, qid2], [qid3,qid4]]
// 题目列表
const renderData = computed(() => {
let index = 1
return (
questionSeq.value &&
questionSeq.value.reduce((pre, item) => {
const questionArr = []
item.forEach((questionKey) => {
const question = { ...questionData.value[questionKey] }
// 开启显示序号
if (question.showIndex) {
question.indexNumber = index++
}
questionArr.push(question)
})
if (questionArr && questionArr.length) {
pre.push(questionArr)
}
return pre
}, [])
)
})
const setQuestionData = (data) => {
questionData.value = data
}
const changeSelectMoreData = (data) => {
const { key, value, field } = data
set(questionData.value, `${field}.othersValue.${key}`, value)
}
const setQuestionSeq = (data) => {
questionSeq.value = data
}
const setVoteMap = (data) => {
voteMap.value = data
}
const updateVoteMapByKey = (data) => {
const { questionKey, voteKey, voteValue } = data
// 兼容为空的情况
if (!voteMap.value[questionKey]) {
voteMap.value[questionKey] = {}
}
voteMap.value[questionKey][voteKey] = voteValue
}
//初始化投票题的数据
const initVoteData = async () => {
const surveyStore = useSurveyStore()
const surveyPath = surveyStore.surveyPath
const fieldList = []
for (const field in questionData.value) {
const { type } = questionData.value[field]
if (/vote/.test(type)) {
fieldList.push(field)
}
}
if (fieldList.length <= 0) {
return
}
try {
localStorage.removeItem(VOTE_INFO_KEY)
const voteRes = await queryVote({
surveyPath,
fieldList: fieldList.join(',')
})
if (voteRes.code === 200) {
localStorage.setItem(
VOTE_INFO_KEY,
JSON.stringify({
...voteRes.data
})
)
setVoteMap(voteRes.data)
}
} catch (error) {
console.log(error)
}
}
const updateVoteData = (data) => {
const { key: questionKey, value: questionVal } = data
// 更新前获取接口缓存在localStorage中的数据
const localData = localStorage.getItem(VOTE_INFO_KEY)
const voteinfo = JSON.parse(localData)
const currentQuestion = questionData.value[questionKey]
const options = currentQuestion.options
const voteTotal = voteinfo?.[questionKey]?.total || 0
let totalPayload = {
questionKey,
voteKey: 'total',
voteValue: voteTotal
}
options.forEach((option) => {
const optionhash = option.hash
const voteCount = voteinfo?.[questionKey]?.[optionhash] || 0
// 如果选中值包含该选项对应voteCount 和 voteTotal + 1
if (
Array.isArray(questionVal) ? questionVal.includes(optionhash) : questionVal === optionhash
) {
const countPayload = {
questionKey,
voteKey: optionhash,
voteValue: voteCount + 1
}
totalPayload.voteValue += 1
updateVoteMapByKey(countPayload)
} else {
const countPayload = {
questionKey,
voteKey: optionhash,
voteValue: voteCount
}
updateVoteMapByKey(countPayload)
}
updateVoteMapByKey(totalPayload)
})
}
return {
voteMap,
questionData,
questionSeq,
renderData,
setQuestionData,
changeSelectMoreData,
setQuestionSeq,
setVoteMap,
updateVoteMapByKey,
initVoteData,
updateVoteData
}
})