Skip to content

Commit

Permalink
feat: 新增用户答题进度保存功能
Browse files Browse the repository at this point in the history
  • Loading branch information
mao2006 committed Oct 13, 2024
1 parent d57c678 commit 5fa9222
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 18 deletions.
2 changes: 1 addition & 1 deletion src/pages/View/checkbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ 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 answerArr = ref<string[]>(props.answer ? props.answer.split('') : []);
const emits = defineEmits(['update:answer']);
const otherAnswerChecked = ref(false)
const otherCheckbox = ref<HTMLInputElement | null>(null);
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';

Check warning on line 68 in src/pages/View/file.vue

View workflow job for this annotation

GitHub Actions / CI

'onMounted' is defined but never used
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) => {

Check warning on line 87 in src/pages/View/file.vue

View workflow job for this annotation

GitHub Actions / CI

'uploadFile' is defined but never used
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
37 changes: 29 additions & 8 deletions src/pages/View/view.vue
Original file line number Diff line number Diff line change
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 @@ -143,20 +143,32 @@
const allowSend = ref(true)
const isOutDate = ref(false)
const questionnaireStore = useMainStore().useQuetionnaireStore();
onMounted(() => {
loginStore.setShowHeader(false);
let idParam = route.query.id as string | undefined;
if (idParam) {
// 解密 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(q.id, 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 +188,19 @@
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 = '';
//获取已存储的答案
question.value.forEach(q => {
const storedAnswer = questionnaireStore.searchAnswer(q.id,q.serial_num)
// console.log("222")
if (storedAnswer) {
// console.log("111")
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,10 +254,13 @@
onBefore: () => startLoading(),
onSuccess(res) {
if (res.code === 200 && res.msg === 'OK') {
const imageStore = useMainStore().useImageStore()
ElNotification.success('提交成功');
questionnaireStore.deleteAnswer()
imageStore.clearFiles()
router.push('/Thank');
} else {
ElNotification.error(res.msg );
ElNotification.error(res.msg);
}
},
onError(e) {
Expand Down
6 changes: 5 additions & 1 deletion src/stores/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@ 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'

export const useMainStore = defineStore(
'main',
() => {
return {
useLoginStore,
useTempStore,
useDarkModeStore
useDarkModeStore,
useQuetionnaireStore,
useImageStore
}
},
{ 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 });

32 changes: 32 additions & 0 deletions src/stores/service/questionnaireStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { defineStore } from "pinia";
import { ref } from "vue";

const useQuestionnaireStore = defineStore("questionnaires", () => {
const userAnswer = ref([])
const searchAnswer = (id: number, serial_num: number) => {
return userAnswer.value.find(question => question.id === id && question.serial_num === serial_num)
}
const updateAnswer = (id: number, serial_num: number, answer: any,) => {
const question = userAnswer.value.find(question => question.id === id && question.serial_num === serial_num)
if (question) {
question.answer = answer
} else {
userAnswer.value.push({
id: id,
serial_num: serial_num,
answer: answer
})
}
}
const deleteAnswer = () => {
userAnswer.value = []
}
return {
userAnswer,
searchAnswer,
updateAnswer,
deleteAnswer
}
}, { persist: true });

export default useQuestionnaireStore;

0 comments on commit 5fa9222

Please sign in to comment.