Skip to content

Commit

Permalink
Merge pull request #117 from xixiIBN5100/feat/voteQuestionnaire
Browse files Browse the repository at this point in the history
Feat/vote questionnaire
  • Loading branch information
xixiIBN5100 authored Dec 9, 2024
2 parents f20270a + fa6c8cc commit 3288d46
Show file tree
Hide file tree
Showing 8 changed files with 254 additions and 27 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:

- name: Installing Dependencies
if: steps.cache-dependencies.outputs.cache-hit != 'true'
run: pnpm install --ignore-scripts
run: pnpm install --no-frozen-lockfile

- name: Building
run: |
Expand Down
1 change: 0 additions & 1 deletion components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ declare module 'vue' {
ElInput: typeof import('element-plus/es')['ElInput']
ElOption: typeof import('element-plus/es')['ElOption']
ElPagination: typeof import('element-plus/es')['ElPagination']
ElRadio: typeof import('element-plus/es')['ElRadio']
ElRadioButton: typeof import('element-plus/es')['ElRadioButton']
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
ElSelect: typeof import('element-plus/es')['ElSelect']
Expand Down
14 changes: 14 additions & 0 deletions src/apis/service/User/getStatistic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { request } from "@/apis/axios";

// 定义请求数据的接口



const setStatisticAPI = (params: { id: number }) => {
return request("/api/user/statistic", {
method: "GET",
params: params
});
};

export default setStatisticAPI;
3 changes: 2 additions & 1 deletion src/pages/DetailInfo/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ onMounted(() => {
id.value = Number(localStorage.getItem('id'))
getInfo();
}else{
console.log(tempStore.surveyType)
submitData.value = {
desc: '',
img: '',
Expand All @@ -281,7 +282,7 @@ onMounted(() => {
time: '',
title: '',
day_limit: 0,
survey_type: tempStore.surveyType.value,
survey_type: Number(tempStore.surveyType),
verify: false
}
loading.value = false
Expand Down
7 changes: 5 additions & 2 deletions src/pages/Home/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import { modal, showModal } from '@/components';
import questionnaireItem from './questionnaireItem.vue';
import { useRequest } from 'vue-hooks-plus';
import { getQuestionnaireListAPI } from '@/apis';
import {nextTick, onMounted, ref} from 'vue';
import {nextTick, onMounted, ref, watch} from 'vue';
import router from '@/router';
import {closeLoading, startLoading} from "@/utilities";
import { useMainStore } from '@/stores';
Expand All @@ -57,7 +57,10 @@ const pageSize = 4;
const totalPageNum = ref(1);
const questionnaireList = ref();
const loading = ref(true);
const surveyType = ref(tempStore.surveyType.value)
const surveyType = ref(tempStore.surveyType)
watch(surveyType, () => {
tempStore.surveyType = surveyType
})
onMounted(() => {
loginStore.setShowHeader(true);
})
Expand Down
3 changes: 2 additions & 1 deletion src/pages/View/checkbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
</div>
<div class="divider my-5"></div>
<div class="flex-col p-5 h-auto">
<span class="dark:opacity-80 text-gray-700 dark:text-gray-400 text-sm my-5" v-if="props.minimum_option !== 0">最少选 {{ props.minimum_option }} 个&ensp;</span><span class="dark:opacity-80 text-gray-700 dark:text-gray-400 text-sm my-5" v-if="props.maximum_option !== 0">最多选 {{ props.maximum_option }} 个</span>
<span class="dark:opacity-80 text-gray-700 dark:text-gray-400 text-sm my-5" v-if="props.minimum_option !== 0">最少选 {{ props.minimum_option }} 个&ensp;</span>
<span class="dark:opacity-80 text-gray-700 dark:text-gray-400 text-sm my-5" v-if="props.maximum_option !== 0">最多选 {{ props.maximum_option }} 个</span>
<div v-for="item in localOptions" :key="item.serial_num" class="flex items-center gap-10 my-5">
<input type="checkbox" :name="props.serial_num" class="my-5" style="zoom: 140%" :value="item.content" v-model="answerArr"/>
<span v-if="item.content" class="text-sm">{{ item.content }}</span>
Expand Down
97 changes: 76 additions & 21 deletions src/pages/View/view.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
</template>
</el-skeleton>
</div>
<div class="flex flex-col h-650 ">
<div class="flex flex-col h-650 " v-if="formData && formData.survey_type === 0">
<div v-for="q in question" :key="q.serial_num">
<!-- 根据问题类型渲染组件 -->
<div v-if="q.question_type === 1">
Expand All @@ -61,7 +61,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" v-model:questionnaireID = "decryptedId" v-model:minimum_option="q.minimum_option" v-model:maximum_option="q.maximum_option"></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 as string" v-model:minimum_option="q.minimum_option" v-model:maximum_option="q.maximum_option"></checkbox>
</template>
</el-skeleton>
</div>
Expand Down Expand Up @@ -100,10 +100,30 @@
<button class="btn w-1/3 bg-red-800 text-red-50 dark:opacity-75 hover:bg-red-600" @click="showModal('QuestionnaireSubmit')" v-if="decryptedId !== '' && !isOutDate" >提交问卷</button>
</div>
</div>
<div class="flex flex-col h-650 " v-if="formData && formData.survey_type === 1">
<div v-for="(q, index) in question" :key="index">
<vote
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"
v-model:minimum_option="q.minimum_option"
v-model:maximum_option="q.maximum_option"
:count="resultData">
<div>
</div></vote>
</div>
<div class="flex justify-center items-center py-50">
<button class="btn w-1/3 bg-red-800 text-red-50 dark:opacity-75 hover:bg-red-600" @click="showModal('QuestionnaireSubmit')" v-if="decryptedId !== '' && !isOutDate" >提交问卷</button>
</div>
</div>

<modal modal-id="QuestionnaireSubmit">
<template #title><span class="text-red-950 dark:text-red-500 ">提交问卷</span></template>

<template #default v-if="formData && !formData.verify || stu_id">
<template #default v-if="formData && !formData.verify || !tokenOutDate">
你确认要提交问卷吗?
</template>
<template #default v-else>
Expand All @@ -118,16 +138,17 @@
</div>
</template>
<template #action>
<button class="btn bg-red-800 text-red-50 w-full hover:bg-red-600" @click="submit" v-if="formData && !formData.verify || stu_id">确认</button>
<button class="btn bg-red-800 text-red-50 w-full hover:bg-red-600" @click="submit" v-if="formData && !formData.verify || !tokenOutDate">确认</button>
<button class="btn bg-red-800 text-red-50 w-full hover:bg-red-600" @click="verify" v-else>确认</button>
</template>
</modal>

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

<script lang="ts" setup>
import {onMounted, ref, watch } from "vue";
import {computed, nextTick, onMounted, ref, watch} from "vue";
import {useRequest} from "vue-hooks-plus";
import {getUserAPI, setUserSubmitAPI} from "@/apis";
import {ElNotification} from "element-plus";
Expand All @@ -145,8 +166,9 @@
import {useMainStore} from "@/stores";
//暗黑模式hook
import { useDarkModeSwitch } from "@/utilities/darkModeSwitch";
import {Discount} from "@element-plus/icons-vue";
import verifyAPI from "@/apis/service/User/verifyApi.ts";
import Vote from "@/pages/View/vote.vue";
import getStatistic from "@/apis/service/User/getStatistic.ts";
const {darkModeStatus,switchDarkMode} = useDarkModeSwitch()
const Key = 'JingHong';
const formData = ref();
Expand All @@ -157,12 +179,12 @@
id: null,
questions_list: [],
});
const resultData = ref(undefined)
const route = useRoute();
const loginStore = useMainStore().useLoginStore();
const decryptedId = ref<string | null>()
const allowSend = ref(true)
const isOutDate = ref(false)
const stu_id = localStorage.getItem("stu_id")
const verifyData = ref( {
stu_id: "",
password: "",
Expand All @@ -186,23 +208,46 @@
getQuestionnaireView();
});
const tokenOutDate = computed(() => {
const lastDate = localStorage.getItem('timestamp');
// 如果没有存储时间戳(首次请求或过期),调用 verifyAPI
if (!lastDate || Date.now() - parseInt(lastDate) > 7 * 24 * 60 * 60 * 1000){
return true
} else {
return false
}
});
const verify = () => {
useRequest(() => verifyAPI(verifyData.value),{
onSuccess(res){
if(res.code === 200){
localStorage.setItem("stu_id", verifyData.value.stu_id)
submit()
} else {
ElNotification.error(res.msg)
const lastDate = localStorage.getItem('timestamp');
// 如果没有存储时间戳(首次请求或过期),调用 verifyAPI
if (!lastDate || Date.now() - parseInt(lastDate) > 7 * 24 * 60 * 60 * 1000) {
// 调用 verifyAPI 获取新的 token
useRequest(() => verifyAPI(verifyData.value), {
onSuccess(res) {
if (res.code === 200) {
// 更新 token 和 timestamp
localStorage.setItem('token', res.data.token);
localStorage.setItem('timestamp', String(Date.now()));
submit();
} else {
ElNotification.error(res.msg);
}
}
}
})
}
});
} else {
// 如果 timestamp 存在且未过期,直接调用 submit
submit();
}
};
watch(question, (newQuestions) => {
newQuestions.forEach(q => {
if (q.answer) {
questionnaireStore.updateAnswer(decryptedId.value, q.serial_num, q.answer);
console.log(questionnaireStore.userAnswer)
}
});
}, { deep: true });
Expand Down Expand Up @@ -292,16 +337,27 @@
serial_num: q.serial_num,
answer: q.answer,
}));
submitData.value.token = localStorage.getItem("token")
useRequest(() => setUserSubmitAPI(submitData.value), {
onBefore: () => startLoading(),
onSuccess(res) {
async 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');
if (formData.value.survey_type === 0) {
router.push('/Thank');
} else {
try{
const res = await getStatistic({id: Number(decryptedId.value)})
resultData.value = res.data.statistics[0].options
console.log(resultData.value)
} catch (e) {
ElNotification.error(e)
}
}
} else {
ElNotification.error(res.msg);
}
Expand All @@ -319,7 +375,6 @@
</script>


Expand Down
Loading

0 comments on commit 3288d46

Please sign in to comment.