perl: 选项配额优化
This commit is contained in:
parent
05414b1386
commit
a0237c8c5f
@ -61,7 +61,7 @@ export interface DataItem {
|
|||||||
starStyle?: string;
|
starStyle?: string;
|
||||||
innerType?: string;
|
innerType?: string;
|
||||||
deleteRecover?: boolean;
|
deleteRecover?: boolean;
|
||||||
noDisplay?: boolean;
|
quotaNoDisplay?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Option {
|
export interface Option {
|
||||||
|
@ -63,7 +63,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"deleteRecover": false,
|
"deleteRecover": false,
|
||||||
"noDisplay": false
|
"quotaNoDisplay": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -77,5 +77,5 @@ export const defaultQuestionConfig = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
deleteRecover: false,
|
deleteRecover: false,
|
||||||
noDisplay: false
|
quotaNoDisplay: false
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ import 'element-plus/theme-chalk/src/message.scss'
|
|||||||
import { saveSurvey } from '@/management/api/survey'
|
import { saveSurvey } from '@/management/api/survey'
|
||||||
import { showLogicEngine } from '@/management/hooks/useShowLogicEngine'
|
import { showLogicEngine } from '@/management/hooks/useShowLogicEngine'
|
||||||
import buildData from './buildData'
|
import buildData from './buildData'
|
||||||
import { getSurveyHistory, getConflictHistory } from '@/management/api/survey'
|
import { getConflictHistory } from '@/management/api/survey'
|
||||||
|
|
||||||
const isSaving = ref<boolean>(false)
|
const isSaving = ref<boolean>(false)
|
||||||
const isShowAutoSave = ref<boolean>(false)
|
const isShowAutoSave = ref<boolean>(false)
|
||||||
|
@ -48,7 +48,7 @@ export default defineComponent({
|
|||||||
type: Number,
|
type: Number,
|
||||||
default: 10
|
default: 10
|
||||||
},
|
},
|
||||||
noDisplay:{
|
quotaNoDisplay:{
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
}
|
}
|
||||||
@ -103,7 +103,6 @@ export default defineComponent({
|
|||||||
<div class="choice-wrapper">
|
<div class="choice-wrapper">
|
||||||
<div class={[isMatrix ? 'nest-box' : '', 'choice-box']}>
|
<div class={[isMatrix ? 'nest-box' : '', 'choice-box']}>
|
||||||
{getOptions.map((item, index) => {
|
{getOptions.map((item, index) => {
|
||||||
item.disabled = !this.readonly && item.quota !== "0" && (item.quota - item.voteCount) === 0
|
|
||||||
return (
|
return (
|
||||||
!item.hide && (
|
!item.hide && (
|
||||||
<div
|
<div
|
||||||
@ -152,16 +151,16 @@ export default defineComponent({
|
|||||||
)}
|
)}
|
||||||
{
|
{
|
||||||
// 如果设置了配额并且展示配额
|
// 如果设置了配额并且展示配额
|
||||||
!this.readonly && item.quota !== "0" && !this.noDisplay && (
|
!this.readonly && (item.quota && item.quota !== "0") && !this.quotaNoDisplay && (
|
||||||
<span
|
<span
|
||||||
class="remaining-text"
|
class="remaining-text"
|
||||||
style={{
|
style={{
|
||||||
display: 'block',
|
display: 'block',
|
||||||
fontSize: 'smaller',
|
fontSize: 'smaller',
|
||||||
color: item.quota - item.voteCount === 0 ? '#EB505C' : '#92949D'
|
color: item.release === 0 ? '#EB505C' : '#92949D'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
剩余{item.quota - item.voteCount}
|
剩余{item.release}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{slots.vote?.({
|
{slots.vote?.({
|
||||||
|
@ -42,7 +42,7 @@ export default defineComponent({
|
|||||||
type: [Number, String],
|
type: [Number, String],
|
||||||
default: 1
|
default: 1
|
||||||
},
|
},
|
||||||
noDisplay:{
|
quotaNoDisplay:{
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
}
|
}
|
||||||
@ -64,7 +64,7 @@ export default defineComponent({
|
|||||||
return options.map((item) => {
|
return options.map((item) => {
|
||||||
return {
|
return {
|
||||||
...item,
|
...item,
|
||||||
disabled: isDisabled(item)
|
disabled: (item.release === 0) || isDisabled(item)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -101,7 +101,7 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
render() {
|
render() {
|
||||||
const { readonly, field, myOptions, onChange, maxNum, value, noDisplay, selectMoreView } = this
|
const { readonly, field, myOptions, onChange, maxNum, value, quotaNoDisplay, selectMoreView } = this
|
||||||
return (
|
return (
|
||||||
<BaseChoice
|
<BaseChoice
|
||||||
uiTarget="checkbox"
|
uiTarget="checkbox"
|
||||||
@ -111,7 +111,7 @@ export default defineComponent({
|
|||||||
options={myOptions}
|
options={myOptions}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
value={value}
|
value={value}
|
||||||
noDisplay={noDisplay}
|
quotaNoDisplay={quotaNoDisplay}
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
selectMore: (scoped) => {
|
selectMore: (scoped) => {
|
||||||
|
@ -112,9 +112,27 @@ const meta = {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "quotaConfig",
|
name: 'optionQuota',
|
||||||
name: "quotaConfig",
|
label: '选项配额',
|
||||||
type: "QuotaConfig",
|
labelStyle: {
|
||||||
|
'font-weight': 'bold'
|
||||||
|
},
|
||||||
|
type: 'QuotaConfig',
|
||||||
|
// 输出转换
|
||||||
|
valueSetter({ options, deleteRecover, quotaNoDisplay}) {
|
||||||
|
return [{
|
||||||
|
key: 'options',
|
||||||
|
value: options
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'deleteRecover',
|
||||||
|
value: deleteRecover
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'quotaNoDisplay',
|
||||||
|
value: quotaNoDisplay
|
||||||
|
}]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
editConfigure: {
|
editConfigure: {
|
||||||
|
@ -32,7 +32,7 @@ export default defineComponent({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
noDisplay:{
|
quotaNoDisplay:{
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
}
|
}
|
||||||
@ -85,7 +85,7 @@ export default defineComponent({
|
|||||||
field={this.field}
|
field={this.field}
|
||||||
layout={this.layout}
|
layout={this.layout}
|
||||||
onChange={this.onChange}
|
onChange={this.onChange}
|
||||||
noDisplay={this.noDisplay}
|
quotaNoDisplay={this.quotaNoDisplay}
|
||||||
>
|
>
|
||||||
{{
|
{{
|
||||||
selectMore: (scoped) => {
|
selectMore: (scoped) => {
|
||||||
|
@ -72,6 +72,19 @@ const meta = {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
// deleteRecover
|
||||||
|
{
|
||||||
|
name: 'deleteRecover',
|
||||||
|
propType: Boolean,
|
||||||
|
description: '删除后恢复选项配额',
|
||||||
|
defaultValue: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'quotaNoDisplay',
|
||||||
|
propType: Boolean,
|
||||||
|
description: '不展示配额剩余数量',
|
||||||
|
defaultValue: false
|
||||||
|
}
|
||||||
],
|
],
|
||||||
formConfig: [
|
formConfig: [
|
||||||
basicConfig,
|
basicConfig,
|
||||||
@ -87,9 +100,27 @@ const meta = {
|
|||||||
hidden: true
|
hidden: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "quotaConfig",
|
name: 'optionQuota',
|
||||||
name: "quotaConfig",
|
label: '选项配额',
|
||||||
type: "QuotaConfig",
|
labelStyle: {
|
||||||
|
'font-weight': 'bold'
|
||||||
|
},
|
||||||
|
type: 'QuotaConfig',
|
||||||
|
// 输出转换
|
||||||
|
valueSetter({ options, deleteRecover, quotaNoDisplay}) {
|
||||||
|
return [{
|
||||||
|
key: 'options',
|
||||||
|
value: options
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'deleteRecover',
|
||||||
|
value: deleteRecover
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'quotaNoDisplay',
|
||||||
|
value: quotaNoDisplay
|
||||||
|
}]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
editConfigure: {
|
editConfigure: {
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="quota-wrapper">
|
<div class="quota-wrapper">
|
||||||
<span class="quota-title">选项配额</span>
|
|
||||||
<span class="quota-config" @click="openQuotaConfig"> 设置> </span>
|
<span class="quota-config" @click="openQuotaConfig"> 设置> </span>
|
||||||
|
<el-dialog v-model="dialogVisible" @closed="cleanTempQuota" class="dialog">
|
||||||
<el-dialog v-model="dialogTableVisible" @closed="cleanTempQuota" class="dialog">
|
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="dialog-title">选项配额</div>
|
<div class="dialog-title">选项配额</div>
|
||||||
</template>
|
</template>
|
||||||
@ -58,7 +56,7 @@
|
|||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<el-checkbox v-model="noDisplayValue" label="不展示配额剩余数量"> </el-checkbox>
|
<el-checkbox v-model="quotaNoDisplayValue" label="不展示配额剩余数量"> </el-checkbox>
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
class="tooltip"
|
class="tooltip"
|
||||||
effect="dark"
|
effect="dark"
|
||||||
@ -88,26 +86,30 @@ import { ElMessageBox } from 'element-plus'
|
|||||||
const props = defineProps(['formConfig', 'moduleConfig'])
|
const props = defineProps(['formConfig', 'moduleConfig'])
|
||||||
const emit = defineEmits(['form-change'])
|
const emit = defineEmits(['form-change'])
|
||||||
|
|
||||||
const dialogTableVisible = ref(false)
|
const dialogVisible = ref(false)
|
||||||
const moduleConfig = ref(props.moduleConfig)
|
const moduleConfig = ref(props.moduleConfig)
|
||||||
const optionData = ref(props.moduleConfig.options)
|
const optionData = ref(props.moduleConfig.options)
|
||||||
const deleteRecoverValue = ref(moduleConfig.value.deleteRecover)
|
const deleteRecoverValue = ref(moduleConfig.value.deleteRecover)
|
||||||
const noDisplayValue = ref(moduleConfig.value.noDisplay)
|
const quotaNoDisplayValue = ref(moduleConfig.value.quotaNoDisplay)
|
||||||
|
|
||||||
const openQuotaConfig = () => {
|
const openQuotaConfig = () => {
|
||||||
optionData.value.forEach((item) => {
|
optionData.value.forEach((item) => {
|
||||||
item.tempQuota = item.quota
|
item.tempQuota = item.quota
|
||||||
})
|
})
|
||||||
dialogTableVisible.value = true
|
dialogVisible.value = true
|
||||||
}
|
}
|
||||||
const cancel = () => {
|
const cancel = () => {
|
||||||
dialogTableVisible.value = false
|
dialogVisible.value = false
|
||||||
}
|
}
|
||||||
const confirm = () => {
|
const confirm = () => {
|
||||||
handleDeleteRecoverChange()
|
dialogVisible.value = false
|
||||||
handleNoDisplayChange()
|
// 更新选项
|
||||||
handleQuotaChange()
|
handleQuotaChange()
|
||||||
dialogTableVisible.value = false
|
emit(FORM_CHANGE_EVENT_KEY, {
|
||||||
|
options: optionData.value,
|
||||||
|
deleteRecover: deleteRecoverValue.value,
|
||||||
|
quotaNoDisplay: quotaNoDisplayValue.value
|
||||||
|
})
|
||||||
}
|
}
|
||||||
const handleCellClick = (row, column) => {
|
const handleCellClick = (row, column) => {
|
||||||
if (column.property === 'quota') {
|
if (column.property === 'quota') {
|
||||||
@ -127,18 +129,6 @@ const handleInput = (row) => {
|
|||||||
}
|
}
|
||||||
row.isEditing = false
|
row.isEditing = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleDeleteRecoverChange = () => {
|
|
||||||
const key = 'deleteRecover'
|
|
||||||
const value = deleteRecoverValue.value
|
|
||||||
emit(FORM_CHANGE_EVENT_KEY, { key, value })
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleNoDisplayChange = () => {
|
|
||||||
const key = 'noDisplay'
|
|
||||||
const value = noDisplayValue.value
|
|
||||||
emit(FORM_CHANGE_EVENT_KEY, { key, value })
|
|
||||||
}
|
|
||||||
const handleQuotaChange = () => {
|
const handleQuotaChange = () => {
|
||||||
optionData.value.forEach((item) => {
|
optionData.value.forEach((item) => {
|
||||||
item.quota = item.tempQuota
|
item.quota = item.tempQuota
|
||||||
@ -156,7 +146,7 @@ watch(
|
|||||||
moduleConfig.value = val
|
moduleConfig.value = val
|
||||||
optionData.value = val.options
|
optionData.value = val.options
|
||||||
deleteRecoverValue.value = val.deleteRecover
|
deleteRecoverValue.value = val.deleteRecover
|
||||||
noDisplayValue.value = val.noDisplay
|
quotaNoDisplayValue.value = val.quotaNoDisplay
|
||||||
},
|
},
|
||||||
{ immediate: true, deep: true }
|
{ immediate: true, deep: true }
|
||||||
)
|
)
|
||||||
@ -164,9 +154,9 @@ watch(
|
|||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.quota-wrapper {
|
.quota-wrapper {
|
||||||
width: 100%;
|
width: 90%;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
.quota-title {
|
.quota-title {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
@ -13,6 +13,7 @@ import QuestionRuleContainer from '../../materials/questions/QuestionRuleContain
|
|||||||
import { useVoteMap } from '@/render/hooks/useVoteMap'
|
import { useVoteMap } from '@/render/hooks/useVoteMap'
|
||||||
import { useShowOthers } from '@/render/hooks/useShowOthers'
|
import { useShowOthers } from '@/render/hooks/useShowOthers'
|
||||||
import { useShowInput } from '@/render/hooks/useShowInput'
|
import { useShowInput } from '@/render/hooks/useShowInput'
|
||||||
|
import { useOptionsQuota } from '@/render/hooks/useOptionsQuota'
|
||||||
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'
|
||||||
@ -41,16 +42,26 @@ const questionConfig = computed(() => {
|
|||||||
const { type, field, options = [], ...rest } = cloneDeep(moduleConfig)
|
const { type, field, options = [], ...rest } = cloneDeep(moduleConfig)
|
||||||
// console.log(field,'这里依赖的formValue,所以change时会触发重新计算')
|
// console.log(field,'这里依赖的formValue,所以change时会触发重新计算')
|
||||||
let alloptions = options
|
let alloptions = options
|
||||||
if (type === QUESTION_TYPE.VOTE || NORMAL_CHOICES.includes(type)) {
|
if (type === QUESTION_TYPE.VOTE) {
|
||||||
|
// 处理投票进度
|
||||||
const { options, voteTotal } = useVoteMap(field)
|
const { options, voteTotal } = useVoteMap(field)
|
||||||
const voteOptions = unref(options)
|
const voteOptions = unref(options)
|
||||||
alloptions = alloptions.map((obj, index) => Object.assign(obj, voteOptions[index]))
|
alloptions = alloptions.map((obj, index) => Object.assign(obj, voteOptions[index]))
|
||||||
moduleConfig.voteTotal = unref(voteTotal)
|
moduleConfig.voteTotal = unref(voteTotal)
|
||||||
}
|
}
|
||||||
|
if(NORMAL_CHOICES.includes(type) &&
|
||||||
|
options.some(option => option.quota > 0)) {
|
||||||
|
// 处理普通选择题的选项配额
|
||||||
|
let { options: optionWithQuota } = useOptionsQuota(field)
|
||||||
|
|
||||||
|
alloptions = alloptions.map((obj, index) => Object.assign(obj, optionWithQuota[index]))
|
||||||
|
console.log({alloptions})
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
NORMAL_CHOICES.includes(type) &&
|
NORMAL_CHOICES.includes(type) &&
|
||||||
options.filter((optionItem) => optionItem.others).length > 0
|
options.some(option => option.others)
|
||||||
) {
|
) {
|
||||||
|
// 处理普通选择题的填写更多
|
||||||
let { options, othersValue } = useShowOthers(field)
|
let { options, othersValue } = useShowOthers(field)
|
||||||
const othersOptions = unref(options)
|
const othersOptions = unref(options)
|
||||||
alloptions = alloptions.map((obj, index) => Object.assign(obj, othersOptions[index]))
|
alloptions = alloptions.map((obj, index) => Object.assign(obj, othersOptions[index]))
|
||||||
@ -60,6 +71,7 @@ const questionConfig = computed(() => {
|
|||||||
RATES.includes(type) && rest?.rangeConfig &&
|
RATES.includes(type) && rest?.rangeConfig &&
|
||||||
Object.keys(rest?.rangeConfig).filter((index) => rest?.rangeConfig[index].isShowInput).length > 0
|
Object.keys(rest?.rangeConfig).filter((index) => rest?.rangeConfig[index].isShowInput).length > 0
|
||||||
) {
|
) {
|
||||||
|
// 处理评分题的的选项后输入框
|
||||||
let { rangeConfig, othersValue } = useShowInput(field)
|
let { rangeConfig, othersValue } = useShowInput(field)
|
||||||
moduleConfig.rangeConfig = unref(rangeConfig)
|
moduleConfig.rangeConfig = unref(rangeConfig)
|
||||||
moduleConfig.othersValue = unref(othersValue)
|
moduleConfig.othersValue = unref(othersValue)
|
||||||
@ -105,5 +117,10 @@ const handleChange = (data) => {
|
|||||||
if (props.moduleConfig.type === QUESTION_TYPE.VOTE) {
|
if (props.moduleConfig.type === QUESTION_TYPE.VOTE) {
|
||||||
store.dispatch('updateVoteData', data)
|
store.dispatch('updateVoteData', data)
|
||||||
}
|
}
|
||||||
|
// 处理普通选择题
|
||||||
|
if (props.moduleConfig.type === NORMAL_CHOICES) {
|
||||||
|
store.dispatch('changeQuota', data)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
22
web/src/render/hooks/useOptionsQuota.js
Normal file
22
web/src/render/hooks/useOptionsQuota.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import store from '../store/index'
|
||||||
|
export const useOptionsQuota = (questionKey) => {
|
||||||
|
const options = store.state.questionData[questionKey].options.map((option) => {
|
||||||
|
if(option.quota){
|
||||||
|
const optionHash = option.hash
|
||||||
|
const selectCount = store.state.quotaMap?.[questionKey]?.[optionHash] || 0
|
||||||
|
const release = Number(option.quota) - Number(selectCount)
|
||||||
|
return {
|
||||||
|
...option,
|
||||||
|
disabled: release === 0,
|
||||||
|
selectCount,
|
||||||
|
release
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
...option,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return { options }
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
import store from '../store/index'
|
import store from '../store/index'
|
||||||
export const useVoteMap = (questionKey) => {
|
export const useVoteMap = (questionKey) => {
|
||||||
let voteTotal = store.state.voteMap?.[questionKey]?.total || 0
|
let voteTotal = store.state.voteMap?.[questionKey]?.total || 0
|
||||||
|
|
||||||
const options = store.state.questionData[questionKey].options.map((option) => {
|
const options = store.state.questionData[questionKey].options.map((option) => {
|
||||||
const optionHash = option.hash
|
const optionHash = option.hash
|
||||||
const voteCount = store.state.voteMap?.[questionKey]?.[optionHash] || 0
|
const voteCount = store.state.voteMap?.[questionKey]?.[optionHash] || 0
|
||||||
|
@ -82,14 +82,14 @@ const normalizationRequestBody = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//浏览器缓存数据
|
//浏览器缓存数据
|
||||||
localStorage.removeItem(surveyPath + "_questionData")
|
localStorage.removeItem(surveyPath.value + "_questionData")
|
||||||
localStorage.removeItem("isSubmit")
|
localStorage.removeItem("isSubmit")
|
||||||
//数据加密
|
//数据加密
|
||||||
var formData = Object.assign({}, store.state.formValues)
|
var formData = Object.assign({}, store.state.formValues)
|
||||||
for(const key in formData){
|
for(const key in formData){
|
||||||
formData[key] = encodeURIComponent(formData[key])
|
formData[key] = encodeURIComponent(formData[key])
|
||||||
}
|
}
|
||||||
localStorage.setItem(surveyPath + "_questionData", JSON.stringify(formData))
|
localStorage.setItem(surveyPath.value + "_questionData", JSON.stringify(formData))
|
||||||
localStorage.setItem('isSubmit', JSON.stringify(true))
|
localStorage.setItem('isSubmit', JSON.stringify(true))
|
||||||
|
|
||||||
if (encryptInfo?.encryptType) {
|
if (encryptInfo?.encryptType) {
|
||||||
|
@ -5,10 +5,11 @@ import 'moment/locale/zh-cn'
|
|||||||
moment.locale('zh-cn')
|
moment.locale('zh-cn')
|
||||||
import adapter from '../adapter'
|
import adapter from '../adapter'
|
||||||
import { queryVote, getEncryptInfo } from '@/render/api/survey'
|
import { queryVote, getEncryptInfo } from '@/render/api/survey'
|
||||||
import { RuleMatch } from '@/common/logicEngine/RulesMatch'
|
|
||||||
import state from './state'
|
import state from './state'
|
||||||
import useCommandComponent from '../hooks/useCommandComponent'
|
import useCommandComponent from '../hooks/useCommandComponent'
|
||||||
import BackAnswerDialog from '../components/BackAnswerDialog.vue'
|
import BackAnswerDialog from '../components/BackAnswerDialog.vue'
|
||||||
|
|
||||||
|
import { NORMAL_CHOICES } from '@/common/typeEnum.ts'
|
||||||
/**
|
/**
|
||||||
* CODE_MAP不从management引入,在dev阶段,会导致B端 router被加载,进而导致C端路由被添加 baseUrl: /management
|
* CODE_MAP不从management引入,在dev阶段,会导致B端 router被加载,进而导致C端路由被添加 baseUrl: /management
|
||||||
*/
|
*/
|
||||||
@ -18,6 +19,7 @@ const CODE_MAP = {
|
|||||||
NO_AUTH: 403
|
NO_AUTH: 403
|
||||||
}
|
}
|
||||||
const VOTE_INFO_KEY = 'voteinfo'
|
const VOTE_INFO_KEY = 'voteinfo'
|
||||||
|
const QUOTA_INFO_KEY = 'limitinfo'
|
||||||
import router from '../router'
|
import router from '../router'
|
||||||
|
|
||||||
const confirm = useCommandComponent(BackAnswerDialog)
|
const confirm = useCommandComponent(BackAnswerDialog)
|
||||||
@ -145,7 +147,7 @@ export default {
|
|||||||
|
|
||||||
for (const field in questionData) {
|
for (const field in questionData) {
|
||||||
const { type } = questionData[field]
|
const { type } = questionData[field]
|
||||||
if (/vote/.test(type) || /radio/.test(type) || /checkbox/.test(type)) {
|
if (/vote/.test(type)) {
|
||||||
fieldList.push(field)
|
fieldList.push(field)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -221,16 +223,80 @@ export default {
|
|||||||
console.log(error)
|
console.log(error)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async initRuleEngine({ commit }, ruleConf) {
|
async initQuotaMap({ state, commit }) {
|
||||||
const ruleEngine = new RuleMatch(ruleConf)
|
const questionData = state.questionData
|
||||||
commit('setRuleEgine', ruleEngine)
|
const surveyPath = state.surveyPath
|
||||||
|
const fieldList = Object.keys(questionData).filter(field => {
|
||||||
|
if (NORMAL_CHOICES.includes(questionData[field].type)) {
|
||||||
|
return questionData[field].options.some(option => option.quota > 0)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 如果不存在则不请求选项上限接口
|
||||||
|
if (fieldList.length <= 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
localStorage.removeItem(QUOTA_INFO_KEY)
|
||||||
|
const quotaRes = await queryVote({
|
||||||
|
surveyPath,
|
||||||
|
fieldList: fieldList.join(',')
|
||||||
|
})
|
||||||
|
|
||||||
|
if (quotaRes.code === 200) {
|
||||||
|
localStorage.setItem(
|
||||||
|
QUOTA_INFO_KEY,
|
||||||
|
JSON.stringify({
|
||||||
|
...quotaRes.data
|
||||||
|
})
|
||||||
|
)
|
||||||
|
Object.keys(quotaRes.data).forEach(field => {
|
||||||
|
Object.keys(quotaRes.data[field]).forEach((optionHash) => {
|
||||||
|
commit('updateQuotaMapByKey', { questionKey: field, optionKey: optionHash, data: quotaRes.data[field][optionHash] })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 题目选中时更新选项配额
|
||||||
|
changeQuota({ state, commit }, data) {
|
||||||
|
const { key: questionKey, value: questionVal } = data
|
||||||
|
// 更新前获取接口缓存在localStorage中的数据
|
||||||
|
const localData = localStorage.getItem(QUOTA_INFO_KEY)
|
||||||
|
const quotaMap = JSON.parse(localData)
|
||||||
|
// const quotaMap = state.quotaMap
|
||||||
|
const currentQuestion = state.questionData[questionKey]
|
||||||
|
const options = currentQuestion.options
|
||||||
|
options.forEach((option) => {
|
||||||
|
const optionhash = option.hash
|
||||||
|
const selectCount = quotaMap?.[questionKey]?.[optionhash].selectCount || 0
|
||||||
|
// 如果选中值包含该选项,对应 voteCount 和 voteTotal + 1
|
||||||
|
if (
|
||||||
|
Array.isArray(questionVal) ? questionVal.includes(optionhash) : questionVal === optionhash
|
||||||
|
) {
|
||||||
|
const countPayload = {
|
||||||
|
questionKey,
|
||||||
|
optionKey: optionhash,
|
||||||
|
selectCount: selectCount + 1
|
||||||
|
}
|
||||||
|
commit('updateQuotaMapByKey', countPayload)
|
||||||
|
} else {
|
||||||
|
const countPayload = {
|
||||||
|
questionKey,
|
||||||
|
optionKey: optionhash,
|
||||||
|
selectCount: selectCount
|
||||||
|
}
|
||||||
|
commit('updateQuotaMapByKey', countPayload)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载上次填写过的数据到问卷页
|
// 加载上次填写过的数据到问卷页
|
||||||
function loadFormData({ commit, dispatch }, {bannerConf, baseConf, bottomConf, dataConf, skinConf, submitConf }, formData) {
|
function loadFormData({ commit, dispatch }, {bannerConf, baseConf, bottomConf, dataConf, skinConf, submitConf }, formData) {
|
||||||
commit('setRouter', 'indexPage')
|
|
||||||
|
|
||||||
// 根据初始的schema生成questionData, questionSeq, rules, formValues, 这四个字段
|
// 根据初始的schema生成questionData, questionSeq, rules, formValues, 这四个字段
|
||||||
const { questionData, questionSeq, rules, formValues } = adapter.generateData({
|
const { questionData, questionSeq, rules, formValues } = adapter.generateData({
|
||||||
bannerConf,
|
bannerConf,
|
||||||
@ -262,11 +328,12 @@ export default {
|
|||||||
})
|
})
|
||||||
// 获取已投票数据
|
// 获取已投票数据
|
||||||
dispatch('initVoteData')
|
dispatch('initVoteData')
|
||||||
|
// 获取选项上线选中数据
|
||||||
|
dispatch('initQuotaMap')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载空白页面
|
// 加载空白页面
|
||||||
function clearFormData({ commit, dispatch }, { bannerConf, baseConf, bottomConf, dataConf, skinConf, submitConf }) {
|
function clearFormData({ commit, dispatch }, { bannerConf, baseConf, bottomConf, dataConf, skinConf, submitConf }) {
|
||||||
commit('setRouter', 'indexPage')
|
|
||||||
|
|
||||||
// 根据初始的schema生成questionData, questionSeq, rules, formValues, 这四个字段
|
// 根据初始的schema生成questionData, questionSeq, rules, formValues, 这四个字段
|
||||||
const { questionData, questionSeq, rules, formValues } = adapter.generateData({
|
const { questionData, questionSeq, rules, formValues } = adapter.generateData({
|
||||||
@ -293,4 +360,5 @@ export default {
|
|||||||
})
|
})
|
||||||
// 获取已投票数据
|
// 获取已投票数据
|
||||||
dispatch('initVoteData')
|
dispatch('initVoteData')
|
||||||
|
dispatch('initQuotaMap')
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,11 @@ export default {
|
|||||||
setEncryptInfo(state, data) {
|
setEncryptInfo(state, data) {
|
||||||
state.encryptInfo = data
|
state.encryptInfo = data
|
||||||
},
|
},
|
||||||
setRuleEgine(state, ruleEngine) {
|
updateQuotaMapByKey(state, { questionKey, optionKey, data }) {
|
||||||
state.ruleEngine = ruleEngine
|
// 兼容为空的情况
|
||||||
|
if (!state.quotaMap[questionKey]) {
|
||||||
|
state.quotaMap[questionKey] = {}
|
||||||
|
}
|
||||||
|
state.quotaMap[questionKey][optionKey] = data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,5 +12,5 @@ export default {
|
|||||||
questionSeq: [], // 题目的顺序,因为可能会有分页的情况,所以是一个二维数组[[qid1, qid2], [qid3,qid4]]
|
questionSeq: [], // 题目的顺序,因为可能会有分页的情况,所以是一个二维数组[[qid1, qid2], [qid3,qid4]]
|
||||||
voteMap: {},
|
voteMap: {},
|
||||||
encryptInfo: null,
|
encryptInfo: null,
|
||||||
ruleEngine: null
|
quotaMap: {}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user