7 changed files with 272 additions and 6 deletions
-
4src/apis/voteRecord.js
-
4src/components/home/AsideMenu.vue
-
5src/router/index.js
-
12src/stores/voteRecord.js
-
4src/views/VoteDetail/VoteDetail.vue
-
136src/views/VoteRecord/VoteRecord.vue
-
113src/views/test/test.vue
@ -1,5 +1,7 @@ |
|||||
import { request } from "@/utils/request"; |
import { request } from "@/utils/request"; |
||||
|
|
||||
export const apiGetAllVotes = async (userId)=>request.get(`/user/getAllVote?userId=${userId}`); |
|
||||
|
export const apiGetAllVotes = async (condition)=>request.get(`/user/getAllVote`,{ |
||||
|
params:condition |
||||
|
}); |
||||
export const apiGetSelectVotes = async(condition) => request.get(`/user/selectVote`,condition); |
export const apiGetSelectVotes = async(condition) => request.get(`/user/selectVote`,condition); |
||||
|
|
@ -0,0 +1,12 @@ |
|||||
|
import { apiGetAllVotes } from "@/apis/voteRecord"; |
||||
|
import { defineStore } from "pinia"; |
||||
|
|
||||
|
export const useVoteRecordStore = defineStore("VoteRecord", () => { |
||||
|
const getAllVotes = async (condition) => { |
||||
|
return await apiGetAllVotes(condition) |
||||
|
}; |
||||
|
|
||||
|
return { |
||||
|
getAllVotes, |
||||
|
}; |
||||
|
}); |
@ -1,5 +1,135 @@ |
|||||
<template> |
<template> |
||||
<div> |
|
||||
ccc |
|
||||
|
<div class="filter-container"> |
||||
|
<el-input v-model="condition.voteTitle" placeholder="请输入投票标题" clearable style="width: 200px;" /> |
||||
|
<el-input v-model="condition.articleTitle" placeholder="请输入文章/视频标题" clearable style="width: 200px;" /> |
||||
|
<el-date-picker v-model="condition.createTime" type="date" placeholder="请选择创建时间" :size="size" /> |
||||
|
<el-date-picker v-model="condition.deadlineTime" type="date" placeholder="请选择截止时间" :size="size" /> |
||||
|
<el-select v-model="condition.status" clearable = {{true}} value-key="code" placeholder="请选择状态" style="width: 200px;"> |
||||
|
<el-option v-for="item in options" :key="item.code" :label="item.label" :value="item.code" /> |
||||
|
</el-select> |
||||
|
<el-button type="danger" @click="selectVoteData"> |
||||
|
搜索 |
||||
|
</el-button> |
||||
</div> |
</div> |
||||
</template> |
|
||||
|
<el-table :data="tableData" show-overflow-tooltip style="width: 100%"> |
||||
|
<!-- <el-table-column type="selection" width="55" /> --> |
||||
|
<el-table-column property="voteTitle" label="投票标题" width="180" /> |
||||
|
<el-table-column property="articleTitle" label="文章/视频标题" width="180" /> |
||||
|
<el-table-column property="createTime" label="创建时间" width="180" /> |
||||
|
<el-table-column property="deadlineTime" label="结束时间" width="180" /> |
||||
|
<el-table-column label="状态" width="100"> |
||||
|
<template #default="{ row }"> |
||||
|
{{ row.status === 1 ? '进行中' : '已结束' }} |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column fixed="right" label="投票结果" min-width="120"> |
||||
|
<template #default="scope"> |
||||
|
<el-button link type="primary" size="small" @click.prevent="goDetail(scope.row)"> |
||||
|
查看详情 |
||||
|
</el-button> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
<div class="pagination-container"> |
||||
|
<el-pagination v-model:current-page="pageInfo.pageNum" :page-sizes="[2, 5, 10, 50, 100]" |
||||
|
:page-size="pageInfo.pageSize" layout="total, sizes, prev, pager, next, jumper" :total="totalCount" |
||||
|
@size-change="handleSizeChange" @current-change="handleCurrentChange" /> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script setup> |
||||
|
import { useUserStore } from '@/stores/user' |
||||
|
import { useVoteRecordStore } from '@/stores/voteRecord' |
||||
|
import { ref, onMounted, reactive } from 'vue' |
||||
|
import { useRouter } from 'vue-router' |
||||
|
const options = ref([ |
||||
|
{ |
||||
|
code: 1, |
||||
|
label: "进行中" |
||||
|
}, |
||||
|
{ |
||||
|
code: 2, |
||||
|
label: "已结束" |
||||
|
} |
||||
|
]) |
||||
|
const router = useRouter() |
||||
|
const userId = useUserStore().userId |
||||
|
const goDetail = (voteRow) => { |
||||
|
console.log(voteRow) |
||||
|
router.push({ |
||||
|
path: '/voteDetail', |
||||
|
query: { |
||||
|
voteId: voteRow.voteId, |
||||
|
voteTitle: voteRow.voteTitle, |
||||
|
articleTitle: voteRow.articleTitle |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
const tableData = ref([]) |
||||
|
const totalCount = ref(0) |
||||
|
const pageInfo = reactive({ |
||||
|
pageNum: 1, |
||||
|
pageSize: 50 |
||||
|
}) |
||||
|
const condition = reactive({ |
||||
|
voteTitle: '', |
||||
|
articleTitle: '', |
||||
|
createTime: '', |
||||
|
deadlineTime: '', |
||||
|
status: '' |
||||
|
}) |
||||
|
const selectVoteData = async () => { |
||||
|
pageInfo.pageNum = 1 |
||||
|
await fetchVoteData() |
||||
|
} |
||||
|
// 获取投票数据函数 |
||||
|
const fetchVoteData = async () => { |
||||
|
try { |
||||
|
let params = reactive({ |
||||
|
userId: userId, |
||||
|
page: pageInfo.pageNum, |
||||
|
pageSize: pageInfo.pageSize, |
||||
|
voteTitle: condition.voteTitle, |
||||
|
articleTitle: condition.articleTitle, |
||||
|
createTime: condition.createTime, |
||||
|
deadlineTime: condition.deadlineTime, |
||||
|
status: condition.status |
||||
|
}) |
||||
|
console.log(params) |
||||
|
const res = await useVoteRecordStore().getAllVotes(params) |
||||
|
console.log(res) |
||||
|
tableData.value = res.data.data.rows |
||||
|
totalCount.value = res.data.data.total |
||||
|
} catch (err) { |
||||
|
console.error('请求失败', err) |
||||
|
} |
||||
|
} |
||||
|
onMounted(async () => { |
||||
|
fetchVoteData() |
||||
|
}) |
||||
|
|
||||
|
const handleSizeChange = async (newSize) => { |
||||
|
pageInfo.pageSize = newSize |
||||
|
pageInfo.pageNum = 1 |
||||
|
await fetchVoteData() |
||||
|
} |
||||
|
const handleCurrentChange = async (newPage) => { |
||||
|
pageInfo.pageNum = newPage |
||||
|
await fetchVoteData() |
||||
|
} |
||||
|
|
||||
|
</script> |
||||
|
<style scoped> |
||||
|
.filter-container { |
||||
|
margin-bottom: 16px; |
||||
|
display: flex; |
||||
|
gap: 12px; |
||||
|
flex-wrap: wrap; |
||||
|
} |
||||
|
|
||||
|
.pagination-container { |
||||
|
display: flex; |
||||
|
padding-top: 20px; |
||||
|
|
||||
|
} |
||||
|
</style> |
@ -0,0 +1,113 @@ |
|||||
|
<template> |
||||
|
<div class="vote-results"> |
||||
|
<div v-for="opt in options" :key="opt.id" class="progressContainer"> |
||||
|
<!-- 居中显示的状态 --> |
||||
|
<el-progress |
||||
|
v-if="voteStatus" |
||||
|
class="centered-progress" |
||||
|
:percentage="100" |
||||
|
:format="() => opt.content" |
||||
|
:stroke-width="30" |
||||
|
:text-inside="true" |
||||
|
:color="colors[opt.id]" |
||||
|
style="width: 300px;" |
||||
|
@click="clickBtn(opt.id)" |
||||
|
/> |
||||
|
<!-- 显示 count 于灰条最右侧的状态 --> |
||||
|
<div v-else class="progressWrapper"> |
||||
|
<el-progress |
||||
|
class="left-progress" |
||||
|
:percentage="opt.count" |
||||
|
:format="() => opt.content + ' √'" |
||||
|
:stroke-width="30" |
||||
|
:text-inside="true" |
||||
|
:color="colors[opt.id]" |
||||
|
/> |
||||
|
<!-- 绝对定位在灰色轨道的最右边 --> |
||||
|
<span class="count-right">{{ opt.count }}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
<el-button @click="totalStatus">确认</el-button> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { ref } from 'vue' |
||||
|
|
||||
|
const voteStatus = ref(true) |
||||
|
const totalStatus = () => { |
||||
|
voteStatus.value = !voteStatus.value |
||||
|
} |
||||
|
|
||||
|
const options = ref([ |
||||
|
{ id: 1, content: '选择1', count: 20 }, |
||||
|
{ id: 2, content: '选择2', count: 30 }, |
||||
|
{ id: 3, content: '选择3', count: 40 }, |
||||
|
]) |
||||
|
|
||||
|
const colors = ref({}) |
||||
|
function genUniqueColors() { |
||||
|
const used = new Set() |
||||
|
options.value.forEach(opt => { |
||||
|
let c |
||||
|
do { |
||||
|
c = '#' + Math.floor(Math.random() * 0x1000000) |
||||
|
.toString(16) |
||||
|
.padStart(6, '0') |
||||
|
} while (used.has(c)) |
||||
|
used.add(c) |
||||
|
colors.value[opt.id] = c |
||||
|
}) |
||||
|
} |
||||
|
genUniqueColors() |
||||
|
|
||||
|
const clickBtn = idx => { |
||||
|
console.log('点击了:', idx) |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.progressContainer { |
||||
|
width: 300px; |
||||
|
margin-bottom: 20px; |
||||
|
} |
||||
|
|
||||
|
/* 包含进度条的相对定位容器 */ |
||||
|
.progressWrapper { |
||||
|
position: relative; |
||||
|
width: 300px; /* 同进度条宽度 */ |
||||
|
} |
||||
|
|
||||
|
/* count 数字,绝对定位到右端,中间垂直对齐 */ |
||||
|
.count-right { |
||||
|
position: absolute; |
||||
|
right: 0; |
||||
|
top: 50%; |
||||
|
transform: translateY(-50%); |
||||
|
margin-right: 4px; /* 根据需要微调,让数字在灰条内稍留空隙 */ |
||||
|
font-weight: bold; |
||||
|
z-index: 1; |
||||
|
} |
||||
|
|
||||
|
/* 居中状态 */ |
||||
|
.centered-progress :deep(.el-progress-bar__inner) { |
||||
|
display: flex !important; |
||||
|
align-items: center !important; |
||||
|
justify-content: center !important; |
||||
|
} |
||||
|
.centered-progress :deep(.el-progress-bar__inner-text) { |
||||
|
margin: 0 !important; |
||||
|
width: auto !important; |
||||
|
} |
||||
|
|
||||
|
/* 左对齐文本状态 */ |
||||
|
.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__inner-text) { |
||||
|
margin: 0 !important; |
||||
|
} |
||||
|
</style> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue