Browse Source

投票名单页面

master
maziyang 6 days ago
parent
commit
61c1be8fc3
  1. 2
      src/apis/vote.js
  2. 8
      src/apis/voteDetail.js
  3. 3
      src/main.js
  4. 12
      src/router/index.js
  5. 15
      src/stores/voteDetail.js
  6. 5
      src/utils/request.js
  7. 45
      src/views/Article/Article.vue
  8. 159
      src/views/VoteDetail/VoteDetail.vue

2
src/apis/vote.js

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

8
src/apis/voteDetail.js

@ -1,4 +1,8 @@
import { request } from "@/utils/request";
export const apiGetAllVoteDetails = async (voteId)=>request.get(`/user/getAllVoteDetail?userId=${voteId}`);
export const apiGetSelectVoteDetails = async(condition) => request.get(`/user/selectVoteDetail`,condition);
export const apiGetAllVoteDetails = async (condition)=>request.get(`/vote/getAllVoteDetail`,{
params: condition
});
export const apiGetExportVoteDetailList = async(condition) => request.get(`/vote/getExportVoteDetail`,{
params: condition
});

3
src/main.js

@ -3,6 +3,7 @@ import './assets/main.css'
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import ElementPlus from 'element-plus'
import zhCN from 'element-plus/dist/locale/zh-cn.mjs'
import 'element-plus/dist/index.css'
import App from './App.vue'
import router from './router'
@ -10,7 +11,7 @@ import router from './router'
const app = createApp(App)
app.use(createPinia())
app.use(ElementPlus)
app.use(ElementPlus,{locale:zhCN})
app.use(router)
app.mount('#app')

12
src/router/index.js

@ -26,13 +26,11 @@ const router = createRouter({
path: 'voteRecord',
name: 'voteRecord',
component: () => import('@/views/VoteRecord/VoteRecord.vue'),
children: [
{
path: 'voteDetail',
name: 'voteDetail',
component: () => import('@/views/VoteDetail/VoteDetail.vue'),
}
]
},
{
path: 'voteDetail',
name: 'voteDetail',
component: () => import('@/views/VoteDetail/VoteDetail.vue'),
},
]
},

15
src/stores/voteDetail.js

@ -0,0 +1,15 @@
import { apiGetAllVoteDetails, apiGetExportVoteDetailList } from "@/apis/voteDetail";
import { defineStore } from "pinia";
export const useVoteDetailStore = defineStore("VoteDetail", () => {
const getVoteDetail = async (condition) => {
return await apiGetAllVoteDetails(condition);
};
const getExportVoteDetail = async (condition) => {
return await apiGetExportVoteDetailList(condition)
};
return {
getVoteDetail,
getExportVoteDetail
};
});

5
src/utils/request.js

@ -3,5 +3,8 @@ import axios from 'axios';
export const request = axios.create({
baseURL: 'http://127.0.0.1:8000',
timeout:10000
timeout:10000,
headers: {
'Content-Type': 'application/json'
},
})

45
src/views/Article/Article.vue

@ -1,5 +1,5 @@
<template>
<el-form :model="form" label-width="auto" :rules="rules" ref="elFormRef" style="max-width: 600px">
<el-form :model="form" label-width="auto" :rules="rules" ref="elFormRef" style="max-width: 600px">
<el-form-item label="文章标题" prop="articleTitle">
<el-input v-model="form.articleTitle" />
</el-form-item>
@ -42,32 +42,36 @@
</div>
<el-form-item>
<div class="publish-article">
<el-button type="primary" @click="onSubmit">发表</el-button>
<el-button type="primary" @click="onSubmit" :loading="buttonLoading">发表</el-button>
</div>
</el-form-item>
</el-form>
</template>
<script setup>
import { reactive, ref } from 'vue'
import {ElMessage, ElMessageBox, ElForm } from 'element-plus'
import { Delete, Plus } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox, ElForm } from 'element-plus'
import { useArticleStore } from '@/stores/article'
import { useUserStore } from '@/stores/user'
const elFormRef = ref()
let elFormRef = ref()
let optionIndex = ref(3)
let buttonLoading = ref(false)
//
const clearVoteInfomation = () =>{
optionIndex.value = 3
form.voteTitle = '';
form.deadlineTime = '';
form.multiOption = false
form.optionList = []
}
const handleVoteToggle = (value) => {
clearVoteInfomation()
if (value) {
optionIndex.value = 3
form.voteTitle = '';
form.optionList = [
{ optionIndex: 1, optionContent: '' },
{ optionIndex: 2, optionContent: '' }
];
form.deadlineTime = '';
} else {
form.optionList = []
}
}
};
//
const addOption = () => {
@ -86,18 +90,19 @@ const removeOption = (index) => {
form.optionList.splice(index, 1);
}
};
const form = reactive({
let form = reactive({
articleTitle: '',
articleContent: '',
voteStatus: false,
voteTitle: '',
optionList: [],
multiOption:false,
deadlineTime: ''
})
const rules = reactive({
articleTitle: [
{ required: true, message: '请输入文章标题', trigger: 'blur' },
{ min: 3, max: 50, message: '标题长度在5~100字范围内', trigger: 'blur' }
{ min: 5, max: 50, message: '标题长度在5~100字范围内', trigger: 'blur' }
],
articleContent: [
{ required: true, message: '请输入文章内容', trigger: 'change' }
@ -136,18 +141,24 @@ const onSubmit = async () => {
try {
valid = await elFormRef.value.validate()
} catch (error) {
// throw
console.log('表单验证失败', error)
}
if (valid) {
buttonLoading.value = true
console.log('表单验证通过')
try {
form.userId = useUserStore().userId
console.log(form)
const submitRes = await useArticleStore().addArticle(form)
console.log('提交成功', submitRes)
await useArticleStore().addArticle(form)
ElMessage.success('发表成功!')
form.articleTitle = ''
form.articleContent = ''
form.voteStatus = false
clearVoteInfomation()
} catch (error) {
console.log('请求失败',error)
ElMessage.error('发布失败,请重试!')
console.log( error)
} finally{
buttonLoading.value = false
}
}

159
src/views/VoteDetail/VoteDetail.vue

@ -1,5 +1,158 @@
<template>
<div>
ddd
<div class="filter-container">
<el-input v-model="condition.username" placeholder="请输入用户名" clearable style="width: 200px;" />
<el-input v-model="condition.account" placeholder="请输入精网号" clearable style="width: 200px;" />
<el-input v-model="condition.area" placeholder="请输入地区" clearable style="width: 200px;" />
<el-input v-model="condition.optionContent" placeholder="请输入选项" clearable style="width: 200px;" />
<el-button type="danger" @click="fetchVoteData">
搜索
</el-button>
<el-button type="danger" @click="exportDataFrontend">
导出数据
</el-button>
</div>
</template>
<el-table :data="tableData" show-overflow-tooltip style="width: 100%">
<!-- <el-table-column type="selection" width="55" /> -->
<el-table-column property="username" label="名字" width="120" />
<el-table-column property="account" label="精网号" width="120" />
<el-table-column property="area" label="地区" width="120" />
<el-table-column label="投票标题" width="180">
<template #default>
{{ voteInfo.voteTitle }}
</template>
</el-table-column>
<el-table-column label="文章/视频标题" width="180">
<template #default>
{{ voteInfo.articleTitle }}
</template>
</el-table-column>
<el-table-column property="optionContents" label="选项" width="240" />
<el-table-column property="createTime" label="投票时间" />
</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 { useVoteDetailStore } from '@/stores/voteDetail'
import { ref, onMounted, reactive } from 'vue'
import { useRoute } from 'vue-router';
const route = useRoute();
// const voteId = ref(route.params.voteId);
const voteInfo = reactive({
// voteId: Number(route.query.voteId),
voteId: route.query.voteId,
voteTitle: route.query.voteTitle,
articleTitle:route.query.articleTitle,
})
const tableData = ref([])
const totalCount = ref(0)
const pageInfo = reactive({
pageNum: 1,
pageSize: 50
})
const condition = reactive({
username: '',
account: '',
area: '',
optionContents: ''
})
//
const fetchVoteData = async () => {
try {
let params = reactive({
voteId: 1,
page: pageInfo.pageNum,
size: pageInfo.pageSize,
username: condition.username,
account: condition.account,
area: condition.area,
optionContent: condition.optionContent
})
console.log(params)
const res = await useVoteDetailStore().getVoteDetail(params)
console.log(res)
tableData.value = res.data.data.voteList
totalCount.value = res.data.data.totalCount
} catch (err) {
console.error('请求失败', err)
}
}
onMounted(async () => {
fetchVoteData()
// try {
// const res = await useVoteDetailStore().getVoteDetail(1)
// tableData.value = res.data.data
// totalCount.value = res.data.data.length
// } catch (err) {
// console.log('', error)
// }
})
const handleSizeChange = async (newSize) => {
pageInfo.pageSize = newSize
pageInfo.pageNum = 1
await fetchVoteData()
}
const handleCurrentChange = async (newPage) => {
pageInfo.pageNum = newPage
await fetchVoteData()
}
const exportDataFrontend = async () => {
let exportData = ref([])
let params = reactive({
voteId: 1,
username: condition.username,
account: condition.account,
area: condition.area,
optionContent: condition.optionContent
})
const res = await useVoteDetailStore().getExportVoteDetail(params)
exportData.value = res.data.data.voteList
let csvContent = "名字,精网号,地区,投票标题,文章/视频标题,选项,投票时间\n"
exportData.value.forEach(item => {
const row = [
`"${item.username}"`,
`"${item.account}"`,
`"${item.area}"`,
`"${voteInfo.voteTitle}"`,
`"${voteInfo.articleTitle}"`,
`"${item.optionContents}"`,
`"${item.createTime}"`
].join(',')
csvContent += row + '\n'
})
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' })
const link = document.createElement('a')
const url = URL.createObjectURL(blob)
link.setAttribute('href', url)
link.setAttribute('download', `投票详情_${new Date().toLocaleDateString()}.csv`)
link.style.visibility = 'hidden'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}
</script>
<style scoped>
.filter-container {
margin-bottom: 16px;
display: flex;
gap: 12px;
flex-wrap: wrap;
}
.pagination-container {
display: flex;
padding-top: 20px;
}
</style>
Loading…
Cancel
Save