Skip to content

Commit

Permalink
Merge pull request #103 from mao2006/quit-reserve
Browse files Browse the repository at this point in the history
fix: 修复了用户模式不会自动保存答案的问题
  • Loading branch information
xixiIBN5100 authored Oct 16, 2024
2 parents 6e95fe0 + 51a9926 commit 6c4a6c6
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 27 deletions.
33 changes: 27 additions & 6 deletions src/pages/View/checkbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,22 @@
</div>
</div>
<div class="flex gap-10 mt-10" v-if="localOtherOption">
<input ref="otherCheckbox" type="checkbox" :name="props.serial_num" class="my-5" style="zoom: 140%" :value="otherAnswer" @click='otherAnswerChecked = !otherAnswerChecked'/>
<input ref="otherCheckbox" type="checkbox" :name="props.serial_num" class="my-5" style="zoom: 140%" :value="otherAnswer" v-model="otherAnswerChecked"/>
<input type="text" class="input-sm w-150" placeholder="其他" v-model="otherAnswer" @input="updateOtherAnswer" />
</div>
</div>
</div>
</template>

<script setup lang="ts">
import { ref, watch, defineProps, defineEmits, computed } from 'vue'
import { useMainStore } from '@/stores';
import { ref, watch, defineProps, defineEmits, computed, onMounted } from 'vue'
const optionStore = useMainStore().useOptionStore()
const props = defineProps<{
questionnaireID:string
serial_num: number,
title?: string,
required: boolean,
Expand All @@ -57,12 +62,24 @@ const props = defineProps<{
const localUnique = ref<boolean>(props.unique);
const localOtherOption = ref<boolean>(props.otherOption);
const localOptions = ref(props.options ? [...props.options] : []);
const otherAnswer = ref<string>('');
const answerArr = ref<string[]>([]);
const otherAnswer = ref<string>(optionStore.search(props.questionnaireID,props.serial_num));
const answerArr = ref<string[]>(props.answer ? props.answer.split('') : []);
// console.log(answerArr)
const emits = defineEmits(['update:answer']);
const otherAnswerChecked = ref(false)
const otherCheckbox = ref<HTMLInputElement | null>(null);
// console.log(answerArr.value + ' '+ otherAnswer.value)
onMounted(() => {
if(answerArr.value.includes(otherAnswer.value)){
// console.log("111")
otherAnswerChecked.value = true
}
}
)
// console.log(otherAnswerChecked.value)
const deleteOldAnswer = () => {
const otherIndex = answerArr.value.indexOf(otherAnswer.value);
if (otherIndex !== -1) {
Expand All @@ -87,13 +104,17 @@ watch(filteredAnswerArr, () => {
if (otherCheckbox.value && otherCheckbox.value.checked && !answerArr.value.includes(otherAnswer.value)) {
answerArr.value.push(otherAnswer.value)
}
console.log(filteredAnswerArr.value)
console.log(otherAnswerChecked.value)
// console.log(filteredAnswerArr.value)
// console.log(otherAnswerChecked.value)
const combinedAnswers = filteredAnswerArr.value.join('');
emits('update:answer', combinedAnswers);
});
watch(otherAnswer, (newOtherAnswer, oldOtherAnswer) => {
if(newOtherAnswer){
optionStore.update(props.questionnaireID,props.serial_num,newOtherAnswer)
}
if (newOtherAnswer !== oldOtherAnswer && otherCheckbox.value && otherCheckbox.value.checked) {
const otherIndex = answerArr.value.indexOf(oldOtherAnswer);
if (otherIndex !== -1) {
Expand Down
22 changes: 14 additions & 8 deletions src/pages/View/file.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@

<template #file="{ file }">
<div>
<img class="el-upload-list__item-thumbnail" :src="file.url" />
<img class="el-upload-list__item-thumbnail" :src="props.answer" />
<span class="el-upload-list__item-actions">
<span
class="el-upload-list__item-preview"
Expand All @@ -57,41 +57,46 @@
</el-upload>

<el-dialog v-model="dialogVisible">
<img w-full :src="dialogImageUrl" alt="Preview Image" />
<img w-full :src="props.answer" alt="Preview Image" />
</el-dialog>

</div>
</div>
</template>

<script setup lang="ts">
import { ref, watch, defineProps, defineEmits } from 'vue';
import { ref, watch, defineProps, defineEmits, onMounted } from 'vue';
import type { UploadFile } from 'element-plus'
import {ElMessage} from "element-plus";
import { Delete, Plus, ZoomIn } from '@element-plus/icons-vue'
import { useMainStore } from '@/stores';
const imageStore = useMainStore().useImageStore();
const dialogImageUrl = ref('')
const dialogVisible = ref(false)
const disabled = ref(false)
const fileList = ref<UploadFile[]>([])
fileList.value = imageStore.fileList;
const handlePictureCardPreview = (file: UploadFile) => {
dialogImageUrl.value = file.url!
dialogVisible.value = true
}
// 处理删除
const handleRemove = (uploadFile: UploadFile) => {
fileList.value = [] // 清空列表,确保只显示一张图片
}
imageStore.clearFiles(); // 清空 Pinia 文件列表
fileList.value = []; // 清空本地列表
};
// 上传成功回调
const handleUploadSuccess = (response: any, file: UploadFile) => {
if(response.code == 200) {
ElMessage.success('上传成功!')
fileList.value = [{ ...file, url: response.data }]
const uploadedFile: UploadFile = { ...file, url: response.data };
imageStore.addFile(uploadedFile); // 将文件推入 Pinia 存储
localAnswer.value = response.data
} else {
ElMessage.error(response.msg)
Expand All @@ -109,6 +114,7 @@ const props = defineProps({
answer: String,
});
const handleExceed = () => {
ElMessage.warning('最多只能上传一张图片!');
}
Expand All @@ -126,7 +132,7 @@ const emits = defineEmits(['update:answer']);
const localAnswer = ref(props.answer);
watch(localAnswer, (newAnswer) => {
console.log(newAnswer)
// console.log(newAnswer)
emits('update:answer', newAnswer);
});
Expand Down
9 changes: 8 additions & 1 deletion src/pages/View/radio.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,13 @@
</template>

<script setup lang="ts">
import { useMainStore } from '@/stores';
import { ref, watch, defineProps, defineEmits } from 'vue';
const optionStore = useMainStore().useOptionStore()
const props = defineProps<{
questionnaireID:string,
serial_num: number,
title?: string,
required: boolean,
Expand All @@ -53,12 +57,15 @@ const props = defineProps<{
const localUnique = ref<boolean>(props.unique);
const localOtherOption = ref<boolean>(props.otherOption);
const localOptions = ref(props.options ? [...props.options] : []);
const otherAnswer = ref<string>('');
const otherAnswer = ref<string>(optionStore.search(props.questionnaireID,props.serial_num));
const emits = defineEmits(['update:answer']);
const localAnswer = ref(props.answer);
watch([localAnswer, otherAnswer], ([newLocalAnswer, newOtherAnswer]) => {
if(newOtherAnswer){
optionStore.update(props.questionnaireID,props.serial_num,newOtherAnswer)
}//更新optionStore
if (localOtherOption.value && newLocalAnswer === newOtherAnswer) {
emits('update:answer', newOtherAnswer);
} else {
Expand Down
44 changes: 33 additions & 11 deletions src/pages/View/view.vue
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
<!-- 根据问题类型渲染组件 -->
<div v-if="q.question_type === 1">
<el-skeleton animated :loading="loading">
<radio v-model:answer="q.answer" v-model:title="q.subject" v-model:options="q.options" v-model:serial_num="q.serial_num" v-model:unique="q.unique" v-model:required="q.required" v-model:other-option="q.other_option" v-model:describe="q.describe"></radio>
<radio v-model:answer="q.answer" v-model:title="q.subject" v-model:options="q.options" v-model:serial_num="q.serial_num" v-model:unique="q.unique" v-model:required="q.required" v-model:other-option="q.other_option" v-model:describe="q.describe" v-model:questionnaireID = "decryptedId"></radio>
</el-skeleton>
</div>
<div v-if="q.question_type === 2">
Expand All @@ -58,7 +58,7 @@
<skeleton-card></skeleton-card>
</template>
<template #default>
<checkbox v-model:answer="q.answer" v-model:title="q.subject" v-model:options="q.options" v-model:serial_num="q.serial_num" v-model:unique="q.unique" v-model:required="q.required" v-model:other-option="q.other_option" v-model:describe="q.describe"></checkbox>
<checkbox v-model:answer="q.answer" v-model:title="q.subject" v-model:options="q.options" v-model:serial_num="q.serial_num" v-model:unique="q.unique" v-model:required="q.required" v-model:other-option="q.other_option" v-model:describe="q.describe" v-model:questionnaireID = "decryptedId"></checkbox>
</template>
</el-skeleton>
</div>
Expand Down Expand Up @@ -111,7 +111,7 @@
</template>

<script lang="ts" setup>
import {onMounted, ref,} from "vue";
import {onMounted, ref, watch } from "vue";
import {useRequest} from "vue-hooks-plus";
import {getUserAPI, setUserSubmitAPI} from "@/apis";
import {ElNotification} from "element-plus";
Expand Down Expand Up @@ -142,6 +142,9 @@
const decryptedId = ref<string | null>()
const allowSend = ref(true)
const isOutDate = ref(false)
const optionStore = useMainStore().useOptionStore()
const questionnaireStore = useMainStore().useQuetionnaireStore();
onMounted(() => {
loginStore.setShowHeader(false);
Expand All @@ -150,13 +153,23 @@
// 解密 ID
idParam = idParam.replace(/ /g, "+");
decryptedId.value = decryptId(idParam) as string | null;
// console.log(decryptedId.value)
if (decryptedId.value === ""){
ElNotification.error("无效的问卷id")
}
}
getQuestionnaireView();
});
watch(question, (newQuestions) => {
newQuestions.forEach(q => {
if (q.answer) {
questionnaireStore.updateAnswer(decryptedId.value, q.serial_num, q.answer);
console.log(questionnaireStore.userAnswer)
}
});
}, { deep: true });
const decryptId = (encryptedId) => {
try {
const bytes = CryptoJS.AES.decrypt(encryptedId, Key);
Expand All @@ -176,13 +189,18 @@
question.value = formData.value.questions;
time.value = formData.value.time.replace("T", " ").split("+")[0].split(".")[0]
submitData.value.id = res.data.id;
question.value.forEach((q) => {
if(q.question_type === 1){
q.answer = ' '
} else {
q.answer = '';
// console.log("问卷id:"+submitData.value.id)
question.value.forEach(q => {
//获取已存储的答案
const storedAnswer = questionnaireStore.searchAnswer(decryptedId.value,q.serial_num)
if (storedAnswer) {
q.answer = storedAnswer.answer;
}else if (q.question_type===1){
q.answer = " ";
}else {
q.answer = "";
}
});
})
loading.value = false
} else if (res.code === 200509){
isOutDate.value = true
Expand Down Expand Up @@ -236,14 +254,18 @@
onBefore: () => startLoading(),
onSuccess(res) {
if (res.code === 200 && res.msg === 'OK') {
const imageStore = useMainStore().useImageStore()
ElNotification.success('提交成功');
questionnaireStore.deleteAnswer(decryptedId.value)
imageStore.clearFiles()
optionStore.deleteOption(decryptedId.value)
router.push('/Thank');
} else {
ElNotification.error(res.msg );
ElNotification.error(res.msg);
}
},
onError(e) {
ElNotification.error( e.message);
ElNotification.error(e.message);
},
onFinally: () => {
showModal('QuestionnaireSubmit', true);
Expand Down
8 changes: 7 additions & 1 deletion src/stores/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,20 @@ import { defineStore } from 'pinia'
import useLoginStore from './service/loginStore'
import useTempStore from './service/tempStore'
import useDarkModeStore from './service/darkStore'
import useQuetionnaireStore from './service/questionnaireStore'
import { useImageStore } from './service/imageStore'
import useOptionStore from './service/optionStore'

export const useMainStore = defineStore(
'main',
() => {
return {
useLoginStore,
useTempStore,
useDarkModeStore
useDarkModeStore,
useQuetionnaireStore,
useImageStore,
useOptionStore
}
},
{ persist: true }
Expand Down
19 changes: 19 additions & 0 deletions src/stores/service/imageStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { defineStore } from 'pinia';
import { ref } from 'vue';
import type { UploadFile } from 'element-plus';

export const useImageStore = defineStore('image', () => {
const fileList = ref<UploadFile[]>([]); // 用于存储上传的文件列表

const addFile = (file: UploadFile) => {
fileList.value.push(file); // 添加文件到列表
};

const clearFiles = () => {
fileList.value = []; // 清空文件列表
};


return { fileList, addFile, clearFiles };
}, { persist: true });

37 changes: 37 additions & 0 deletions src/stores/service/optionStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//存储单选和多选的
import { defineStore } from "pinia";
import { ref } from "vue";

const useOptionStore = defineStore('OptionStore', () => {
const options = ref([])
const search = (id: any, serial_num: number) => {
const optionSearched = options.value.find(q => q.id === id && q.serial_num === serial_num)
console.log(optionSearched)
return optionSearched ? optionSearched.option : ''
}
const update = (id: any, serial_num: number, option: string) => {
const tempOption = options.value.find(q => q.id === id && q.serial_num === serial_num)
if (tempOption) {
tempOption.option = option
} else {
options.value.push({
id: id,
serial_num: serial_num,
option: option
})
}
}

const deleteOption = (id: any) => {
options.value = options.value.filter(o => o.id !== id)
}

return {
options,
search,
update,
deleteOption
}
}, { persist: true })

export default useOptionStore
Loading

0 comments on commit 6c4a6c6

Please sign in to comment.