Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 修复了用户模式不会自动保存答案的问题 #103

Merged
merged 4 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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';

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 @@
answer: String,
});


const handleExceed = () => {
ElMessage.warning('最多只能上传一张图片!');
}
Expand All @@ -126,7 +132,7 @@
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
Loading