Browse Source

用户投票界面

master
liruiqiang 7 days ago
parent
commit
7408282496
  1. 4
      src/apis/vote.js
  2. 316
      src/views/Vote/Vote.vue

4
src/apis/vote.js

@ -1,5 +1,5 @@
import { request } from "@/utils/request";
export const apiGetVote = (articleId) => request.get('/vote/getVote', articleId)
export const apiAddVoteRecord = async (voteRecord) => request.post(`/vote/addRecord`,voteRecord)
export const apiGetVote = (articleId) => request.get('/vote/getVote', {params:{articleId}})
export const apiAddVoteRecord = async (record) => request.post(`/vote/addRecord`,record)
export const apiGetVoteIndex = async(userId,voteId) => request.get(`/vote/getIndex?userId=${userId}&voteId=${voteId}`)

316
src/views/Vote/Vote.vue

@ -1,126 +1,165 @@
<template>
<div class="articleandvote-section">
<div :data="ActiveAndVote">
<!-- 文章组件 -->
<div class="article-section">
<div>
<h2 class="article-title">{{ ActiveAndVote.articleTitle }}</h2>
<!-- <h2 class="article-title">小柒战队 VS MIke战队, 公司达人动态风格争霸赛</h2> -->
<div class="article-content">
<!-- <p>{{ ActiveAndVote.articleContent }}</p> -->
<p>正源谐音的小柒战队 VS 暗藏谐音MIke战队, 赶快在视频下方留言选择自己的战队争夺10金豆吧!</p>
</div>
</div>
</div>
<!-- 投票组件 -->
<!-- <div class="voting-title">{{ ActiveAndVote.voteTitle }}</div> -->
<div class="voting-title"> 你pick小柒战队还是MIke战队? </div>
<!--<div class="team-buttons">
<button
v-for="option in ActiveAndVote.optionList"
:key="option.id"
class="team-button"
:class="{ active: selectedOption === option.id }"
@click="selectOption(option.id)">
{{ option.optionContent }}
</button>
</div> -->
<div class="team-buttons">
<button
class="team-button"
:class="{ active: selectedTeam === 'xiaoqi' }"
@click="selectTeam('xiaoqi')">
小柒战队
</button>
<button
class="team-button"
:class="{ active: selectedTeam === 'mike' }"
@click="selectTeam('mike')">
MIke战队
</button>
</div>
<button
class="confirm-button"
:disabled="!selectedTeam"
@click="confirmVote">
确认投票
</button>
<div class="voting-info">
<div style="display: flex; align-items: center;">
<p style="margin-right: 350px;">当前共有{{ totalVotes }}人参与</p>
<a href="#" class="homily-link">Homily Link</a><a>&nbsp;创建</a>
<!-- <a href="#" class="homily-link">{{ ActiveAndVote.username }}</a><a>&nbsp;创建</a> -->
</div>
<p>此投票于{{ formattedDate }}结束</p>
<!-- 文章组件 -->
<div class="article-section">
<div>
<h2 class="article-title"> {{ ActiveAndVote.articleTitle }} </h2>
<div class="article-content">
<p>{{ ActiveAndVote.articleContent }}</p>
</div>
</div>
</div>
<!-- 投票组件 -->
<div class="voting-title">{{ ActiveAndVote.voteTitle }}</div>
<div class="team-buttons">
<button
v-for="option in ActiveAndVote.optionList"
:key="option.id"
:value="option.id"
class="team-button"
:class="{ active: selectedOptions.includes(option.id) }"
@click="selectOption(option.id)">
{{ option.optionContent }}
</button>
</div>
<button
class="confirm-button"
:class="{ 'disabled-style': ActiveAndVote.votePollStatus === 2 }"
:disabled="ActiveAndVote.votePollStatus === 2 || selectedOptions.length === 0"
@click="showConfirmModal">
确认投票
</button>
<!-- 提示框 -->
<div v-if="showModal" class="modal-overlay">
<div class="modal-content">
<p>今日投票次数剩余{{ userVoteIndexNow }} 是否继续投票</p>
<div class="modal-buttons">
<button class="modal-button yes" @click="submitVote"></button>
<button class="modal-button no" @click="closeModal"></button>
</div>
</div>
</div>
<!-- 底部组件 -->
<div class="voting-info">
<div style="display: flex; align-items: center;">
<p style="margin-right: 350px;">当前共有{{ totalVotes }}人参与</p>
<a href="#" class="homily-link">{{ ActiveAndVote.username }}</a><a>&nbsp;创建</a>
</div>
<p>此投票于{{ ActiveAndVote.deadlineTime }}结束</p>
</div>
</div>
</div>
</template>
<script setup>
import { onMounted, ref } from 'vue'
import { ref, reactive, computed } from 'vue'
import {apiGetVote,apiAddVoteRecord,apiGetVoteIndex} from '@/apis/vote.js'
import { useVoteStore } from '@/stores/vote'
import { ElMessage } from 'element-plus';
//
const ActiveAndVote = ref({})
const getVote = async (articleId) => {
const res = await apiGetVote(articleId)
ActiveAndVote.value = res.data
}
onMounted(async ()=>{
const res = await useVoteStore().getVote(9)
console.log(res)
const record = reactive({
userId: 0,
articleId: 0,
voteId: 0,
OptionId: [],
voteIndex: 1
})
//
const userVoteIndexNow = ref(0)
const voteId = ActiveAndVote.voteId
const GetIndex = async(userId,voteId) => {
const res = await apiGetVoteIndex(userId,voteId)
userVoteIndexNow.value = res.data
}
GetIndex()
//
const selectedTeam = ref(null);
const selectTeam = (team) => {
selectedTeam.value = team;
};
const totalVotes = ref(100); //
//
const ActiveAndVote = reactive({
voteId: 0,
optionList:[],
participationNumber:0
});
record.articleId = 12 // id
const getVote = async () => {
try {
const res = await apiGetVote(record.articleId)
if (res.data.code === 0) {
Object.assign(ActiveAndVote, res.data.data)
record.voteId = ActiveAndVote.voteId
totalVotes.value += ActiveAndVote.participationNumber;
console.log('投票数据加载成功:', ActiveAndVote)
await GetIndex()
} else {
console.error('请求失败:', res.message)
}
} catch (err) {
console.error('网络错误:', err)
}
}
getVote()
//
const totalVotes = ref(100); //
// totalVotes.value = totalVotes.value + ActiveAndVote.participationNumber
//
const userVoteIndexNow = ref(3) //
record.userId = 1 // id
const GetIndex = async() => {
const res = await apiGetVoteIndex(record.userId,record.voteId)
userVoteIndexNow.value = res.data.data.voteIndex
console.log('用户今日本活动剩余投票数:', userVoteIndexNow.value)
}
const confirmVote = () => {
if (selectedTeam.value) {
totalVotes.value += 1;
emit('vote-count-changed', totalVotes.value);
selectedTeam.value = null;
//
alert('投票成功!');
// id
const selectedOptions = ref([]);// ID
const selectOption = (optionId) => {
const index = selectedOptions.value.indexOf(optionId);
//
if (ActiveAndVote.multiOption == 0) {
selectedOptions.value = [optionId];
return;
}
//
if (index > -1) {
//
selectedOptions.value.splice(index, 1);
} else {
//
if (selectedOptions.value.length >= 10) {
alert('最多只能选择 10 个选项');
return;
}
selectedOptions.value.push(optionId);
}
};
//
const deadlineTime = "2025-06-21 15:20:41";
//
const [datePart, timePart] = deadlineTime.split(" ");
//
const [year, month, day] = datePart.split("-");
//
const formattedDate = `${year}${month}${day}${timePart}`;
//
//
const showModal = ref(false)
//
const showConfirmModal = () => {
showModal.value = true;
};
//
const closeModal = () => {
showModal.value = false;
};
//
const submitVote = async() => {
console.log('剩余投票次数',userVoteIndexNow.value,'选择个数',selectedOptions.value.length)
if (userVoteIndexNow.value > 0 && selectedOptions.value.length > 0) {
record.OptionId = computed(() => selectedOptions.value);
record.voteIndex = 4 - userVoteIndexNow.value
//
console.log('添加投票信息',record.userId,record.articleId,record.voteId,record.OptionId,record.voteIndex)
await apiAddVoteRecord(record)
ElMessage.success('添加成功')
userVoteIndexNow.value -= 1; //
totalVotes.value += 1; //
selectedOptions.value = []; //
closeModal(); //
await getVote()
} else {
ElMessage.error('没有剩余投票次数或未选择任何选项')
}
};
selectedTeam,
selectTeam,
confirmVote
</script>
<style scoped>
@ -173,7 +212,7 @@ const formattedDate = `${year}年${month}月${day}日 ${timePart}`;
padding: 12px 15px;
border: none;
border-radius: 25px;
background-color: #4169E1; /* 点击前背景为蓝色 */
background-color: rgb(36, 184, 233); /* 点击前背景为蓝色 */
font-size: 15px;
width: 80%;
margin: 0 auto;
@ -184,7 +223,7 @@ const formattedDate = `${year}年${month}月${day}日 ${timePart}`;
}
.team-button.active {
background-color: #FFD700; /* 点击后背景为黄色 */
background-color: #FFA500; /* 点击后背景为黄色 */
font-weight: bold;
color: black; /* 点击后文字颜色为黑色 */
}
@ -204,6 +243,75 @@ const formattedDate = `${year}年${month}月${day}日 ${timePart}`;
text-align: center; /* 文字居中 */
}
.confirm-button:hover {
background-color: #CC0000;
transform: translateY(-2px); /* 微微上移 */
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.confirm-button.disabled-style {
background-color: gray; /* 灰色背景 */
color: #ccc; /* 灰色文字 */
cursor: not-allowed; /* 鼠标变成禁止符号 */
}
/* 提示框样式 */
/* 提示框背景遮罩 */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
}
/* 提示框主体 */
.modal-content {
background-color: #87CEEB; /* 更明显的浅蓝色背景 */
padding: 30px 40px; /* 增加内边距 */
border-radius: 12px; /* 边角更圆润一些 */
width: 350px;
min-height: 180px;
text-align: center;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2); /* 添加阴影效果 */
}
/* 提示文字 */
.modal-content p {
font-size: 25px; /* 文字更大 */
color: #333;
margin-bottom: 20px;
}
.modal-buttons {
display: flex;
justify-content: space-around;
margin-top: 10px;
}
.modal-button {
padding: 10px 20px;
border: none;
border-radius: 25px;
font-size: 14px;
cursor: pointer;
}
.modal-button.yes {
background-color: orange;
color: white;
}
.modal-button.no {
background-color: lightgray;
color: black;
}
/* 底部样式 */
.voting-info {
font-size: 13px;
color: #888;

Loading…
Cancel
Save