fix: 移除有问题的功能

This commit is contained in:
sudoooooo 2024-09-14 13:50:51 +08:00
parent dfea4b4779
commit 628872f27c
18 changed files with 104 additions and 551 deletions

View File

@ -1,6 +1,6 @@
import { MongoMemoryServer } from 'mongodb-memory-server';
import { spawn } from 'child_process';
import { RedisMemoryServer } from 'redis-memory-server';
// import { RedisMemoryServer } from 'redis-memory-server';
async function startServerAndRunScript() {
// 启动 MongoDB 内存服务器
@ -9,17 +9,17 @@ async function startServerAndRunScript() {
console.log('MongoDB Memory Server started:', mongoUri);
const redisServer = new RedisMemoryServer();
const redisHost = await redisServer.getHost();
const redisPort = await redisServer.getPort();
// const redisServer = new RedisMemoryServer();
// const redisHost = await redisServer.getHost();
// const redisPort = await redisServer.getPort();
// 通过 spawn 运行另一个脚本,并传递 MongoDB 连接 URL 作为环境变量
const tsnode = spawn(
'cross-env',
[
`XIAOJU_SURVEY_MONGO_URL=${mongoUri}`,
`XIAOJU_SURVEY_REDIS_HOST=${redisHost}`,
`XIAOJU_SURVEY_REDIS_PORT=${redisPort}`,
// `XIAOJU_SURVEY_REDIS_HOST=${redisHost}`,
// `XIAOJU_SURVEY_REDIS_PORT=${redisPort}`,
'NODE_ENV=development',
'SERVER_ENV=local',
'npm',
@ -42,7 +42,7 @@ async function startServerAndRunScript() {
tsnode.on('close', async (code) => {
console.log(`Nodemon process exited with code ${code}`);
await mongod.stop(); // 停止 MongoDB 内存服务器
await redisServer.stop();
// await redisServer.stop();
});
}

View File

@ -60,7 +60,6 @@ export interface DataItem {
rangeConfig?: any;
starStyle?: string;
innerType?: string;
quotaNoDisplay?: boolean;
}
export interface Option {
@ -70,7 +69,6 @@ export interface Option {
othersKey?: string;
placeholderDesc: string;
hash: string;
quota?: number;
}
export interface DataConf {

View File

@ -48,8 +48,7 @@
"mustOthers": false,
"othersKey": "",
"placeholderDesc": "",
"hash": "115019",
"quota": "0"
"hash": "115019"
},
{
"text": "选项2",
@ -58,11 +57,9 @@
"mustOthers": false,
"othersKey": "",
"placeholderDesc": "",
"hash": "115020",
"quota": "0"
"hash": "115020"
}
],
"quotaNoDisplay": false
]
}
]
}

View File

@ -10,7 +10,7 @@ import { ResponseSchemaService } from '../services/responseScheme.service';
import { SurveyResponseService } from '../services/surveyResponse.service';
import { ClientEncryptService } from '../services/clientEncrypt.service';
import { MessagePushingTaskService } from '../../message/services/messagePushingTask.service';
import { RedisService } from 'src/modules/redis/redis.service';
// import { RedisService } from 'src/modules/redis/redis.service';
import moment from 'moment';
import * as Joi from 'joi';
@ -41,7 +41,7 @@ export class SurveyResponseController {
private readonly messagePushingTaskService: MessagePushingTaskService,
private readonly counterService: CounterService,
private readonly logger: XiaojuSurveyLogger,
private readonly redisService: RedisService,
// private readonly redisService: RedisService,
private readonly userService: UserService,
private readonly workspaceMemberService: WorkspaceMemberService,
) {}
@ -224,17 +224,15 @@ export class SurveyResponseController {
const arr = cur.options.map((optionItem) => ({
hash: optionItem.hash,
text: optionItem.text,
quota: optionItem.quota,
}));
pre[cur.field] = arr;
return pre;
}, {});
// 使用redis作为锁校验选项配额
const surveyId = responseSchema.pageId;
const lockKey = `locks:optionSelectedCount:${surveyId}`;
const lock = await this.redisService.lockResource(lockKey, 1000);
this.logger.info(`lockKey: ${lockKey}`);
// const lockKey = `locks:optionSelectedCount:${surveyId}`;
// const lock = await this.redisService.lockResource(lockKey, 1000);
// this.logger.info(`lockKey: ${lockKey}`);
try {
const successParams = [];
for (const field in decryptedData) {
@ -250,23 +248,6 @@ export class SurveyResponseController {
//遍历选项hash值
for (const val of values) {
const option = optionTextAndId[field].find(
(opt) => opt['hash'] === val,
);
const quota = parseInt(option['quota']);
if (
quota &&
optionCountData?.[val] &&
quota <= optionCountData[val]
) {
return {
code: EXCEPTION_CODE.RESPONSE_OVER_LIMIT,
data: {
field,
optionHash: option.hash,
},
};
}
if (!optionCountData[val]) {
optionCountData[val] = 0;
}
@ -292,10 +273,11 @@ export class SurveyResponseController {
} catch (error) {
this.logger.error(error.message);
throw error;
} finally {
await this.redisService.unlockResource(lock);
this.logger.info(`unlockResource: ${lockKey}`);
}
// finally {
// await this.redisService.unlockResource(lock);
// this.logger.info(`unlockResource: ${lockKey}`);
// }
// 入库
const surveyResponse =

View File

@ -1,12 +1,12 @@
import { Module } from '@nestjs/common';
import { MessageModule } from '../message/message.module';
import { RedisModule } from '../redis/redis.module';
// import { RedisModule } from '../redis/redis.module';
import { ResponseSchemaService } from './services/responseScheme.service';
import { SurveyResponseService } from './services/surveyResponse.service';
import { CounterService } from './services/counter.service';
import { ClientEncryptService } from './services/clientEncrypt.service';
import { RedisService } from '../redis/redis.service';
// import { RedisService } from '../redis/redis.service';
import { ResponseSchema } from 'src/models/responseSchema.entity';
import { Counter } from 'src/models/counter.entity';
@ -35,7 +35,7 @@ import { ConfigModule } from '@nestjs/config';
]),
ConfigModule,
MessageModule,
RedisModule,
// RedisModule,
AuthModule,
WorkspaceModule,
],
@ -52,7 +52,7 @@ import { ConfigModule } from '@nestjs/config';
CounterService,
ClientEncryptService,
LoggerProvider,
RedisService,
// RedisService,
],
exports: [
ResponseSchemaService,

View File

@ -11,7 +11,7 @@
"build-only": "vite build",
"type-check": "vue-tsc --build --force",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
"format": "prettier --write src/materials/setters/widgets/QuotaConfig.vue"
"format": "prettier --write src/"
},
"dependencies": {
"@logicflow/core": "2.0.0",

View File

@ -41,15 +41,13 @@ export const defaultQuestionConfig = {
text: '选项1',
others: false,
othersKey: '',
placeholderDesc: '',
quota: '0'
placeholderDesc: ''
},
{
text: '选项2',
others: false,
othersKey: '',
placeholderDesc: '',
quota: '0'
placeholderDesc: ''
}
],
star: 5,
@ -76,6 +74,5 @@ export const defaultQuestionConfig = {
placeholder: '500',
value: 500
}
},
quotaNoDisplay: false
}
}

View File

@ -47,10 +47,6 @@ export default defineComponent({
voteTotal: {
type: Number,
default: 10
},
quotaNoDisplay:{
type: Boolean,
default: true
}
},
emits: ['change'],
@ -146,21 +142,7 @@ export default defineComponent({
v-html={filterXSS(item.text)}
class="item-title-text"
style="display: block; height: auto; padding-top: 9px"
></span>
)}
{
//
!this.readonly && (item.quota && item.quota !== "0") && !this.quotaNoDisplay && (
<span
class="remaining-text"
style={{
display: 'block',
fontSize: 'smaller',
color: item.release === 0 ? '#EB505C' : '#92949D'
}}
>
剩余{item.release}
</span>
></span>
)}
{slots.vote?.({
option: item,

View File

@ -41,15 +41,10 @@ export default defineComponent({
maxNum: {
type: [Number, String],
default: 1
},
quotaNoDisplay:{
type: Boolean,
default: false
}
},
emits: ['change'],
setup(props, { emit }) {
const disableState = computed(() => {
if (!props.maxNum) {
return false
@ -65,24 +60,10 @@ export default defineComponent({
return options.map((item) => {
return {
...item,
disabled: (item.release === 0) || isDisabled(item)
disabled: isDisabled(item)
}
})
})
// 0
watch(() => props.value, (value) => {
const disabledHash = myOptions.value.filter(i => i.disabled).map(i => i.hash)
if (value && disabledHash.length) {
disabledHash.forEach(hash => {
const index = value.indexOf(hash)
if( index> -1) {
const newValue = [...value]
newValue.splice(index, 1)
onChange(newValue)
}
})
}
})
const onChange = (value) => {
const key = props.field
emit('change', {
@ -111,13 +92,12 @@ export default defineComponent({
return {
onChange,
handleSelectMoreChange,
disableState,
myOptions,
selectMoreView
}
},
render() {
const { readonly, field, myOptions, onChange, maxNum, value, quotaNoDisplay, selectMoreView } = this
const { readonly, field, myOptions, onChange, maxNum, value, selectMoreView } = this
return (
<BaseChoice
uiTarget="checkbox"
@ -128,7 +108,6 @@ export default defineComponent({
onChange={onChange}
value={value}
layout={this.layout}
quotaNoDisplay={quotaNoDisplay}
>
{{
selectMore: (scoped) => {

View File

@ -110,7 +110,7 @@ const meta = {
{
label: '横排',
value: 'horizontal'
},
}
]
},
{
@ -119,7 +119,9 @@ const meta = {
key: 'minNum',
value: 0,
min: 0,
max: moduleConfig => { return moduleConfig?.maxNum || 0 },
max: (moduleConfig) => {
return moduleConfig?.maxNum || 0
},
contentClass: 'input-number-config'
},
{
@ -127,30 +129,15 @@ const meta = {
type: 'InputNumber',
key: 'maxNum',
value: 0,
min: moduleConfig => { return moduleConfig?.minNum || 0 },
max: moduleConfig => { return moduleConfig?.options?.length },
min: (moduleConfig) => {
return moduleConfig?.minNum || 0
},
max: (moduleConfig) => {
return moduleConfig?.options?.length
},
contentClass: 'input-number-config'
},
}
]
},
{
name: 'optionQuota',
label: '选项配额',
labelStyle: {
'font-weight': 'bold'
},
type: 'QuotaConfig',
// 输出转换
valueSetter({ options, quotaNoDisplay}) {
return [{
key: 'options',
value: options
},
{
key: 'quotaNoDisplay',
value: quotaNoDisplay
}]
}
}
],
editConfigure: {

View File

@ -31,28 +31,10 @@ export default defineComponent({
readonly: {
type: Boolean,
default: false
},
quotaNoDisplay:{
type: Boolean,
default: false
}
},
emits: ['change'],
setup(props, { emit }) {
// 0
watch(() => props.value, (value) => {
const disabledHash = props.options.filter(i => i.disabled).map(i => i.hash)
if (value && disabledHash.length) {
disabledHash.forEach(hash => {
const index = value.indexOf(hash)
if( index> -1) {
const newValue = [...value]
newValue.splice(index, 1)
onChange(newValue)
}
})
}
})
const onChange = (value) => {
const key = props.field
emit('change', {
@ -99,7 +81,6 @@ export default defineComponent({
field={this.field}
layout={this.layout}
onChange={this.onChange}
quotaNoDisplay={this.quotaNoDisplay}
>
{{
selectMore: (scoped) => {

View File

@ -53,22 +53,22 @@ const meta = {
description: '这是用于描述选项',
defaultValue: [
{
"text": "选项1",
"imageUrl": "",
"others": false,
"mustOthers": false,
"othersKey": "",
"placeholderDesc": "",
"hash": "115019"
text: '选项1',
imageUrl: '',
others: false,
mustOthers: false,
othersKey: '',
placeholderDesc: '',
hash: '115019'
},
{
"text": "选项2",
"imageUrl": "",
"others": false,
"mustOthers": false,
"othersKey": "",
"placeholderDesc": "",
"hash": "115020"
text: '选项2',
imageUrl: '',
others: false,
mustOthers: false,
othersKey: '',
placeholderDesc: '',
hash: '115020'
}
]
},
@ -77,55 +77,34 @@ const meta = {
propType: String,
description: '排列方式',
defaultValue: 'vertical'
},
{
name: 'quotaNoDisplay',
propType: Boolean,
description: '不展示配额剩余数量',
defaultValue: false
}
],
formConfig: [basicConfig, {
name: 'optionConfig',
title: '选项配置',
type: 'Customed',
content: [
{
label: '排列方式',
type: 'RadioGroup',
key: 'layout',
value: 'vertical',
options: [
{
label: '竖排',
value: 'vertical'
},
{
label: '横排',
value: 'horizontal'
},
]
},
]
},{
name: 'optionQuota',
label: '选项配额',
labelStyle: {
'font-weight': 'bold'
},
type: 'QuotaConfig',
// 输出转换
valueSetter({ options, quotaNoDisplay}) {
return [{
key: 'options',
value: options
},
{
key: 'quotaNoDisplay',
value: quotaNoDisplay
}]
formConfig: [
basicConfig,
{
name: 'optionConfig',
title: '选项配置',
type: 'Customed',
content: [
{
label: '排列方式',
type: 'RadioGroup',
key: 'layout',
value: 'vertical',
options: [
{
label: '竖排',
value: 'vertical'
},
{
label: '横排',
value: 'horizontal'
}
]
}
]
}
}],
],
editConfigure: {
optionEdit: {
show: true

View File

@ -1,180 +0,0 @@
<template>
<div class="quota-wrapper">
<span class="quota-config" @click="openQuotaConfig"> 设置> </span>
<el-dialog v-model="dialogVisible" @closed="cleanTempQuota" class="dialog">
<template #header>
<div class="dialog-title">选项配额</div>
</template>
<el-table
:header-cell-style="{ background: '#F6F7F9', color: '#6E707C' }"
:data="optionData"
border
style="width: 100%"
@cell-click="handleCellClick"
>
<el-table-column property="text" label="选项" style="width: 50%">
<template v-slot="scope">
<div v-html="cleanRichTextWithMediaTag(scope.row.text)"></div>
</template>
</el-table-column>
<el-table-column property="quota" style="width: 50%">
<template #header>
<div style="display: flex; align-items: center">
<span>配额设置</span>
<el-tooltip
class="tooltip"
effect="dark"
placement="right"
content="类似商品库存表示最多可以被选择多少次0为无限制已发布问卷上限修改时数量不可减小。"
>
<i-ep-questionFilled class="icon-tip" />
</el-tooltip>
</div>
</template>
<template v-slot="scope">
<el-input
v-if="scope.row.isEditing"
:id="`${scope.row.hash}editInput`"
v-model="scope.row.tempQuota"
type="number"
@blur="handleInput(scope.row)"
placeholder="请输入"
>
</el-input>
<div v-else class="item__txt">
<span v-if="scope.row.tempQuota !== '0'">{{ scope.row.tempQuota }}</span>
<span v-else style="color: #c8c9cd">请输入</span>
</div>
</template>
</el-table-column>
</el-table>
<div class="quota-no-display">
<el-checkbox v-model="quotaNoDisplayValue" label="不展示配额剩余数量"> </el-checkbox>
<el-tooltip
class="tooltip"
effect="dark"
placement="right"
content="勾选后,将不对用户展示剩余配额数量。"
>
<i-ep-questionFilled class="icon-tip" />
</el-tooltip>
</div>
<template #footer>
<div class="diaglog-footer">
<el-button @click="cancel">取消</el-button>
<el-button @click="confirm" type="primary">确定</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { ref, watch, nextTick } from 'vue'
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'
import { ElMessageBox } from 'element-plus'
import { cleanRichTextWithMediaTag } from '@/common/xss'
const props = defineProps(['formConfig', 'moduleConfig'])
const emit = defineEmits(['form-change'])
const dialogVisible = ref(false)
const moduleConfig = ref(props.moduleConfig)
const optionData = ref(props.moduleConfig.options)
const quotaNoDisplayValue = ref(moduleConfig.value.quotaNoDisplay)
const openQuotaConfig = () => {
optionData.value.forEach((item) => {
item.tempQuota = item.quota
})
dialogVisible.value = true
}
const cancel = () => {
dialogVisible.value = false
}
const confirm = () => {
dialogVisible.value = false
//
handleQuotaChange()
emit(FORM_CHANGE_EVENT_KEY, {
options: optionData.value,
quotaNoDisplay: quotaNoDisplayValue.value
})
}
const handleCellClick = (row, column) => {
if (column.property === 'quota') {
optionData.value.forEach((r) => {
if (r !== row) r.isEditing = false
})
row.tempQuota = row.tempQuota === '0' ? row.quota : row.tempQuota
row.isEditing = true
nextTick(() => {
const input = document.getElementById(`${row.hash}editInput`)
input.focus()
})
}
}
const handleInput = (row) => {
if (row.tempQuota !== '0' && +row.tempQuota < +row.quota) {
ElMessageBox.alert('配额数不可减少!', '警告', {
confirmButtonText: '确定'
})
row.tempQuota = row.quota
}
row.isEditing = false
}
const handleQuotaChange = () => {
optionData.value.forEach((item) => {
item.quota = item.tempQuota
delete item.tempQuota
})
}
const cleanTempQuota = () => {
optionData.value.forEach((item) => {
delete item.tempQuota
})
}
watch(
() => props.moduleConfig,
(val) => {
moduleConfig.value = val
optionData.value = val.options
quotaNoDisplayValue.value = val.quotaNoDisplay
},
{ immediate: true, deep: true }
)
</script>
<style lang="scss" scoped>
.quota-wrapper {
width: 90%;
display: flex;
justify-content: flex-end;
:deep(.cell) {
line-height: 35px;
}
.quota-no-display {
padding-top: 8px;
}
}
.quota-title {
font-size: 14px;
color: #606266;
margin-bottom: 20px;
font-weight: bold;
align-items: center;
}
.quota-config {
color: #ffa600;
cursor: pointer;
font-size: 14px;
}
.dialog {
width: 41vw;
.dialog-title {
color: #292a36;
font-size: 20px;
}
}
</style>

View File

@ -15,7 +15,6 @@ import QuestionRuleContainer from '../../materials/questions/QuestionRuleContain
import { useVoteMap } from '@/render/hooks/useVoteMap'
import { useShowOthers } from '@/render/hooks/useShowOthers'
import { useShowInput } from '@/render/hooks/useShowInput'
import { useOptionsQuota } from '@/render/hooks/useOptionsQuota'
import { cloneDeep } from 'lodash-es'
import { useQuestionStore } from '../stores/question'
import { useSurveyStore } from '../stores/survey'
@ -57,17 +56,7 @@ const questionConfig = computed(() => {
alloptions = alloptions.map((obj, index) => Object.assign(obj, voteOptions[index]))
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]))
}
if (
NORMAL_CHOICES.includes(type) &&
options.some(option => option.others)
) {
if (NORMAL_CHOICES.includes(type) && options.some((option) => option.others)) {
//
let { options, othersValue } = useShowOthers(field)
const othersOptions = unref(options)
@ -137,10 +126,6 @@ const handleChange = (data) => {
if (props.moduleConfig.type === QUESTION_TYPE.VOTE) {
questionStore.updateVoteData(data)
}
//
if (props.moduleConfig.type === NORMAL_CHOICES) {
questionStore.updateQuotaData(data)
}
//
localStorageBack()
processJumpSkip()
@ -191,11 +176,11 @@ const processJumpSkip = () => {
questionStore.addNeedHideFields(skipKey)
}
const localStorageBack = () => {
var formData = Object.assign({}, surveyStore.formValues);
var formData = Object.assign({}, surveyStore.formValues)
//
localStorage.removeItem(surveyStore.surveyPath + "_questionData")
localStorage.setItem(surveyStore.surveyPath + "_questionData", JSON.stringify(formData))
localStorage.removeItem(surveyStore.surveyPath + '_questionData')
localStorage.setItem(surveyStore.surveyPath + '_questionData', JSON.stringify(formData))
localStorage.setItem('isSubmit', JSON.stringify(false))
}
</script>

View File

@ -1,23 +0,0 @@
import { useQuestionStore } from '../stores/question'
export const useOptionsQuota = (questionKey) => {
const questionStore = useQuestionStore()
const options = questionStore.questionData[questionKey].options.map((option) => {
if(option.quota){
const optionHash = option.hash
const selectCount = questionStore.quotaMap?.[questionKey]?.[optionHash] || 0
const release = Number(option.quota) - Number(selectCount)
return {
...option,
disabled: release === 0,
selectCount,
release
}
} else {
return {
...option,
}
}
})
return { options }
}

View File

@ -71,7 +71,6 @@ const pageIndex = computed(() => questionStore.pageIndex)
const { bannerConf, submitConf, bottomConf: logoConf, whiteData } = storeToRefs(surveyStore)
const surveyPath = computed(() => surveyStore.surveyPath || '')
const route = useRoute()
onMounted(() => {
const surveyId = route.params.surveyId
@ -152,14 +151,14 @@ const normalizationRequestBody = () => {
}
//
localStorage.removeItem(surveyPath.value + "_questionData")
localStorage.removeItem("isSubmit")
localStorage.removeItem(surveyPath.value + '_questionData')
localStorage.removeItem('isSubmit')
//
var formData : Record<string, any> = Object.assign({}, surveyStore.formValues)
localStorage.setItem(surveyPath.value + "_questionData", JSON.stringify(formData))
var formData: Record<string, any> = Object.assign({}, surveyStore.formValues)
localStorage.setItem(surveyPath.value + '_questionData', JSON.stringify(formData))
localStorage.setItem('isSubmit', JSON.stringify(true))
if (encryptInfo?.encryptType) {
result.encryptType = encryptInfo.encryptType
result.data = encrypt[result.encryptType as 'rsa']({
@ -186,15 +185,6 @@ const submitSurver = async () => {
const res: any = await submitForm(params)
if (res.code === 200) {
router.replace({ name: 'successPage' })
} else if(res.code === 9003) {
//
questionStore.initQuotaMap()
const titile = useQuestionInfo(res.data.field).questionTitle
const optionText = useQuestionInfo(res.data.field).getOptionTitle(res.data.optionHash)
const message = `${titile}】的【${optionText}】配额已满,请重新选择`
alert({
title: message
})
} else {
alert({
title: res.errmsg || '提交失败'

View File

@ -6,13 +6,12 @@ import { queryVote } from '@/render/api/survey'
import { QUESTION_TYPE, NORMAL_CHOICES } from '@/common/typeEnum'
const VOTE_INFO_KEY = 'voteinfo'
const QUOTA_INFO_KEY = 'limitinfo'
// 投票进度逻辑聚合
const usevVoteMap = (questionData) => {
const voteMap = ref({})
//初始化投票题的数据
const initVoteData = async () => {
//初始化投票题的数据
const initVoteData = async () => {
const surveyStore = useSurveyStore()
const surveyPath = surveyStore.surveyPath
@ -104,93 +103,6 @@ const usevVoteMap = (questionData) => {
}
}
// 选项配额逻辑聚合
const useQuotaMap = (questionData) => {
const quotaMap = ref({})
const updateQuotaMapByKey = ({ questionKey, optionKey, data }) =>{
// 兼容为空的情况
if (!quotaMap.value[questionKey]) {
quotaMap.value[questionKey] = {}
}
quotaMap.value[questionKey][optionKey] = data
}
const initQuotaMap = async () => {
const surveyStore = useSurveyStore()
const surveyPath = surveyStore.surveyPath
const fieldList = Object.keys(questionData.value).filter(field => {
if (NORMAL_CHOICES.includes(questionData.value[field].type)) {
return questionData.value[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) => {
updateQuotaMapByKey({ questionKey: field, optionKey: optionHash, data: quotaRes.data[field][optionHash] })
})
})
}
} catch (error) {
console.log(error)
}
}
const updateQuotaData = (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 = questionData.value[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
}
updateQuotaMapByKey(countPayload)
} else {
const countPayload = {
questionKey,
optionKey: optionhash,
selectCount: selectCount
}
updateQuotaMapByKey(countPayload)
}
})
}
return {
quotaMap,
initQuotaMap,
updateQuotaMapByKey,
updateQuotaData
}
}
export const useQuestionStore = defineStore('question', () => {
const questionData = ref(null)
const questionSeq = ref([]) // 题目的顺序,因为可能会有分页的情况,所以是一个二维数组[[qid1, qid2], [qid3,qid4]]
@ -267,7 +179,6 @@ export const useQuestionStore = defineStore('question', () => {
questionData.value = data
}
const { voteMap, setVoteMap, initVoteData, updateVoteData } = usevVoteMap(questionData)
const { quotaMap, initQuotaMap, updateQuotaData } = useQuotaMap(questionData)
const changeSelectMoreData = (data) => {
const { key, value, field } = data
@ -277,7 +188,6 @@ export const useQuestionStore = defineStore('question', () => {
const setQuestionSeq = (data) => {
questionSeq.value = data
}
const setChangeField = (field) => {
changeField.value = field
@ -296,7 +206,6 @@ export const useQuestionStore = defineStore('question', () => {
needHideFields.value = needHideFields.value.filter((field) => !fields.includes(field))
}
return {
questionData,
questionSeq,
renderData,
@ -316,9 +225,6 @@ export const useQuestionStore = defineStore('question', () => {
needHideFields,
addNeedHideFields,
removeNeedHideFields,
getQuestionIndexByField,
quotaMap,
initQuotaMap,
updateQuotaData
getQuestionIndexByField
}
})

View File

@ -13,7 +13,6 @@ import moment from 'moment'
import 'moment/locale/zh-cn'
// 设置中文
import adapter from '../adapter'
import { RuleMatch } from '@/common/logicEngine/RulesMatch'
import useCommandComponent from '../hooks/useCommandComponent'
@ -31,7 +30,6 @@ const CODE_MAP = {
NO_AUTH: 403
}
export const useSurveyStore = defineStore('survey', () => {
const surveyPath = ref('')
const isMobile = ref(isInMobile())
@ -116,8 +114,6 @@ export const useSurveyStore = defineStore('survey', () => {
return isSuccess
}
// 加载空白页面
function clearFormData(option) {
// 根据初始的schema生成questionData, questionSeq, rules, formValues, 这四个字段
@ -153,21 +149,18 @@ export const useSurveyStore = defineStore('survey', () => {
formValues.value = _formValues
whiteData.value = option.whiteData
pageConf.value = option.pageConf
// 获取已投票数据
questionStore.initVoteData()
questionStore.initQuotaMap()
}
function fillFormData(formData) {
const _formValues = cloneDeep(formValues.value)
for(const key in formData){
for (const key in formData) {
_formValues[key] = formData[key]
}
formValues.value = _formValues
}
const initSurvey = (option) => {
setEnterTime()
if (!canFillQuestionnaire(option.baseConf, option.submitConf)) {
return
@ -176,15 +169,15 @@ export const useSurveyStore = defineStore('survey', () => {
clearFormData(option)
const { breakAnswer, backAnswer } = option.baseConf
const localData = JSON.parse(localStorage.getItem(surveyPath.value + "_questionData"))
const localData = JSON.parse(localStorage.getItem(surveyPath.value + '_questionData'))
const isSubmit = JSON.parse(localStorage.getItem('isSubmit'))
if(localData) {
if (localData) {
// 断点续答
if(breakAnswer) {
if (breakAnswer) {
confirm({
title: "是否继续上次填写的内容?",
title: '是否继续上次填写的内容?',
onConfirm: async () => {
try {
// 回填答题内容
@ -195,14 +188,14 @@ export const useSurveyStore = defineStore('survey', () => {
confirm.close()
}
},
onCancel: async() => {
onCancel: async () => {
confirm.close()
}
})
} else if (backAnswer) {
if(isSubmit){
if (isSubmit) {
confirm({
title: "是否继续上次提交的内容?",
title: '是否继续上次提交的内容?',
onConfirm: async () => {
try {
// 回填答题内容
@ -213,7 +206,7 @@ export const useSurveyStore = defineStore('survey', () => {
confirm.close()
}
},
onCancel: async() => {
onCancel: async () => {
confirm.close()
}
})