Browse Source

用户投票界面

master
liruiqiang 5 days ago
parent
commit
0af1087d27
  1. 189
      src/views/Vote/Vote.vue

189
src/views/Vote/Vote.vue

@ -11,16 +11,28 @@
</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 v-for="(option,index) in optionLists" :key="option.id" class="progressContainer">
<el-progress
v-if="!isResultShown"
class="centered-progress"
:percentage="100"
:stroke-width="40"
:format="() => option.optionContent"
:text-inside="true"
:class="{ active: selectedOptions.includes(option.id) }"
@click="selectOption(option.id,index)"
>
</el-progress>
<div v-if="isResultShown" class="progressWrapper">
<el-progress
class="left-progress"
:percentage="getPercentage(option.count + 25)"
:stroke-width="40"
:format="() => option.optionContent"
:text-inside="true"
/>
<span class="count-right">{{ option.count + 25 }}</span>
</div>
</div>
<button
class="confirm-button"
@ -55,9 +67,10 @@
<script setup>
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 isResultShown = ref(false)
//
const record = reactive({
userId: 0,
articleId: 0,
@ -65,24 +78,37 @@ const record = reactive({
OptionId: [],
voteIndex: 1
})
const totalVotes = ref(100); //
//
//
const totalVotes = ref(0);
const selectNum = ref(0);
//
const ActiveAndVote = reactive({
voteId: 0,
optionList:[],
participationNumber:0
});
//
const optionLists = reactive([{
id:0,
optionContent:"",
count: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;
Object.assign(ActiveAndVote, res.data.data) //
optionLists.splice(0) //
optionLists.push(...ActiveAndVote.optionList) //
record.voteId = ActiveAndVote.voteId //
selectNum.value = ActiveAndVote.optionList.length
totalVotes.value = selectNum.value * 25
totalVotes.value += ActiveAndVote.participationNumber; //
console.log('投票数据加载成功:', ActiveAndVote)
await GetIndex()
await GetIndex() //
} else {
console.error('请求失败:', res.message)
}
@ -105,17 +131,31 @@ const GetIndex = async() => {
// id
const selectedOptions = ref([]);// ID
const selectOption = (optionId) => {
const index = selectedOptions.value.indexOf(optionId);
const selectOption = (optionId,index) => {
const idx = selectedOptions.value.indexOf(optionId);
//
if (ActiveAndVote.multiOption == 0) {
//
selectedOptions.value.forEach(id => {
const prevIndex = optionLists.findIndex(opt => opt.id === id);
if (prevIndex > -1) {
optionLists[prevIndex].optionContent = optionLists[prevIndex].optionContent.replace(/ √$/, '');
}
});
// id
selectedOptions.value = [optionId];
console.log(selectedOptions.value)
//
optionLists[index].optionContent += ' √';
return;
}
//
if (index > -1) {
if (idx > -1) {
//
selectedOptions.value.splice(index, 1);
selectedOptions.value.splice(idx, 1);
console.log(selectedOptions.value)
//
optionLists[index].optionContent = optionLists[index].optionContent.replace(/ √$/, '');
} else {
//
if (selectedOptions.value.length >= 10) {
@ -123,6 +163,9 @@ const selectOption = (optionId) => {
return;
}
selectedOptions.value.push(optionId);
console.log(selectedOptions.value)
//
optionLists[index].optionContent += ' √';
}
};
@ -137,6 +180,21 @@ const showConfirmModal = () => {
//
const closeModal = () => {
showModal.value = false;
isResultShown.value = true; //
};
//
const totalcounts = computed(() => {
const baseCount = ActiveAndVote.optionList.reduce((sum, option) => sum + option.count, 0); //
const extra = selectNum.value * 25; //
return baseCount + extra;
});
const getPercentage = (count) => {
if (totalVotes.value === 0) return 0;
const percentage = Math.min(100, Number(((count / totalcounts.value) * 100).toFixed(2)));
return percentage
};
@ -150,16 +208,16 @@ const submitVote = async() => {
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()
showModal.value = false //
if(userVoteIndexNow.value == 1){
isResultShown.value = true; //
}
await getVote() //
} else {
ElMessage.error('没有剩余投票次数或未选择任何选项')
}
};
</script>
<style scoped>
@ -201,31 +259,66 @@ const submitVote = async() => {
text-align: center;
}
.team-buttons {
display: flex;
flex-direction: column;
gap: 10px;
margin-bottom: 20px;
.progressContainer {
width: 400px;
margin: 0 auto 20px; /* 让每个进度条容器居中,并有底部间距 */
}
.team-button {
padding: 12px 15px;
border: none;
border-radius: 25px;
background-color: rgb(36, 184, 233); /* 点击前背景为蓝色 */
font-size: 15px;
width: 80%;
margin: 0 auto;
.centered-progress {
cursor: pointer;
transition: all 0.3s;
text-align: center; /* 文字居中 */
color: white; /* 文字颜色为白色 */
font-size: 18px !important; /* 控制字体大小 */
}
.team-button.active {
background-color: #FFA500; /* 点击后背景为黄色 */
font-weight: bold;
color: black; /* 点击后文字颜色为黑色 */
/* 修改 Element Plus 进度条内层样式 */
.centered-progress :deep(.el-progress-bar__inner) {
display: flex !important;
align-items: center !important;
justify-content: center !important;
font-size: 18px !important;
color: #000 !important;
}
.centered-progress :deep(.el-progress-bar__innerText) {
margin: 0 !important;
width: 100% !important;
text-align: center !important;
font-size: 18px !important;
color: #000 !important;
}
/* 点击激活后的颜色 */
.centered-progress.active :deep(.el-progress-bar__inner) {
background-color: #FF9900 !important;
}
/* 包含进度条的相对定位容器 */
.progressWrapper {
width: 400px; /* 同进度条宽度 */
position: relative;
}
/* count 数字,绝对定位到右端,中间垂直对齐 */
.count-right {
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
margin-right: 10px; /* 根据需要微调,让数字在灰条内稍留空隙 */
font-weight: normal;
z-index: 1;
}
/* 左对齐文本状态 */
.left-progress :deep(.el-progress-bar__inner) {
display: flex !important;
align-items: center !important;
justify-content: flex-start !important;
padding-left: 8px !important;
}
.left-progress :deep(.el-progress-bar__innerText) {
font-size: 15px !important;
color: #000 !important;
margin: 0 !important;
}
.confirm-button {

Loading…
Cancel
Save