|
|
@ -1,19 +1,17 @@ |
|
|
<template> |
|
|
<template> |
|
|
<view class="container"> |
|
|
<view class="container"> |
|
|
|
|
|
<scroll-view class="scroll-view" scroll-y @scrolltolower="loadMore" :show-scrollbar="false"> |
|
|
<view v-for="(item, index) in electionList" :key="index" class="election-item"> |
|
|
<view v-for="(item, index) in electionList" :key="index" class="election-item"> |
|
|
<view class="year-title"> |
|
|
<view class="year-title"> |
|
|
<view class="headpart"> |
|
|
<view class="headpart"> |
|
|
<text class="title">{{ item.title }}</text> |
|
|
<text class="title">{{ item.title }}</text> |
|
|
<view |
|
|
<view class="type" :style=" |
|
|
class="type" |
|
|
|
|
|
:style=" |
|
|
|
|
|
item.type == '投票中' |
|
|
item.type == '投票中' |
|
|
? 'background: #DBEAFE;color: #3B82F6;' |
|
|
? 'background: #DBEAFE;color: #3B82F6;' |
|
|
: item.type == '当选' |
|
|
: item.type == '当选' |
|
|
? 'background: #DCFCE7;color: #10B981' |
|
|
? 'background: #DCFCE7;color: #10B981' |
|
|
: 'background: #F3F4F6;color: #4B5563' |
|
|
: 'background: #F3F4F6;color: #4B5563' |
|
|
" |
|
|
"> |
|
|
> |
|
|
|
|
|
{{ item.type }} |
|
|
{{ item.type }} |
|
|
</view> |
|
|
</view> |
|
|
</view> |
|
|
</view> |
|
|
@ -22,12 +20,11 @@ |
|
|
<view style="display: grid"> |
|
|
<view style="display: grid"> |
|
|
<view |
|
|
<view |
|
|
v-for="(candidate, cIndex) in item.candidates.slice(0, expandedStates[index] ? item.candidates.length : 1)" |
|
|
v-for="(candidate, cIndex) in item.candidates.slice(0, expandedStates[index] ? item.candidates.length : 1)" |
|
|
:key="cIndex" |
|
|
:key="cIndex" class="candidate-item"> |
|
|
class="candidate-item" |
|
|
|
|
|
> |
|
|
|
|
|
<view class="info-section"> |
|
|
<view class="info-section"> |
|
|
<view style="display: flex; align-items: center"> |
|
|
<view style="display: flex; align-items: center"> |
|
|
<img style="width: 96rpx; height: 96rpx; border-radius: 50%" :src="item.img" alt="" /> |
|
|
<img style="width: 96rpx; height: 96rpx; border-radius: 50%" :src="item.img" |
|
|
|
|
|
alt="" /> |
|
|
<view style="margin-left: 24rpx; display: grid"> |
|
|
<view style="margin-left: 24rpx; display: grid"> |
|
|
<text class="name">{{ candidate.name }}</text> |
|
|
<text class="name">{{ candidate.name }}</text> |
|
|
<text class="college">{{ candidate.college }}</text> |
|
|
<text class="college">{{ candidate.college }}</text> |
|
|
@ -47,128 +44,42 @@ |
|
|
</view> |
|
|
</view> |
|
|
</view> |
|
|
</view> |
|
|
</view> |
|
|
</view> |
|
|
|
|
|
</scroll-view> |
|
|
</view> |
|
|
</view> |
|
|
</template> |
|
|
</template> |
|
|
|
|
|
|
|
|
<script setup> |
|
|
<script setup> |
|
|
import { ref, watch } from 'vue' |
|
|
import { |
|
|
|
|
|
ref, |
|
|
const electionList = ref([ |
|
|
watch |
|
|
{ |
|
|
} from 'vue' |
|
|
type: '投票中', |
|
|
import { |
|
|
title: '2024学生会主席选举', |
|
|
getMyvote |
|
|
candidates: [ |
|
|
} from '../../api/votingElection' |
|
|
{ |
|
|
|
|
|
img: '../../static/redpacket.png', |
|
|
|
|
|
name: '陈思远', |
|
|
const electionList = ref([]) |
|
|
college: '计算机科学与技术学院', |
|
|
const page = ref(1) |
|
|
choice: 1 |
|
|
const pageSize = ref(10) |
|
|
}, |
|
|
const loading = ref(false) |
|
|
{ |
|
|
const noMoreData = ref(false) |
|
|
img: '../../static/redpacket.png', |
|
|
|
|
|
name: '陈思远2号', |
|
|
|
|
|
college: '计算机科学与技术学院', |
|
|
|
|
|
choice: 0 |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
img: '../../static/redpacket.png', |
|
|
|
|
|
name: '陈思远2号', |
|
|
|
|
|
college: '计算机科学与技术学院', |
|
|
|
|
|
choice: 2 |
|
|
|
|
|
} |
|
|
|
|
|
] |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
type: '投票中', |
|
|
|
|
|
title: '2024学生会主席选举', |
|
|
|
|
|
candidates: [ |
|
|
|
|
|
{ |
|
|
|
|
|
img: '../../static/redpacket.png', |
|
|
|
|
|
name: '陈思远', |
|
|
|
|
|
college: '计算机科学与技术学院', |
|
|
|
|
|
choice: 1 |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
img: '../../static/redpacket.png', |
|
|
|
|
|
name: '陈思远2号', |
|
|
|
|
|
college: '计算机科学与技术学院', |
|
|
|
|
|
choice: 0 |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
img: '../../static/redpacket.png', |
|
|
|
|
|
name: '陈思远2号', |
|
|
|
|
|
college: '计算机科学与技术学院', |
|
|
|
|
|
choice: 2 |
|
|
|
|
|
} |
|
|
|
|
|
] |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
type: '投票中', |
|
|
|
|
|
title: '2024学生会主席选举', |
|
|
|
|
|
candidates: [ |
|
|
|
|
|
{ |
|
|
|
|
|
img: '../../static/redpacket.png', |
|
|
|
|
|
name: '陈思远', |
|
|
|
|
|
college: '计算机科学与技术学院', |
|
|
|
|
|
choice: 1 |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
img: '../../static/redpacket.png', |
|
|
|
|
|
name: '陈思远2号', |
|
|
|
|
|
college: '计算机科学与技术学院', |
|
|
|
|
|
choice: 0 |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
img: '../../static/redpacket.png', |
|
|
|
|
|
name: '陈思远2号', |
|
|
|
|
|
college: '计算机科学与技术学院', |
|
|
|
|
|
choice: 2 |
|
|
|
|
|
} |
|
|
|
|
|
] |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
type: '当选', |
|
|
|
|
|
title: '2023优秀班干部评选', |
|
|
|
|
|
candidates: [ |
|
|
|
|
|
{ |
|
|
|
|
|
img: '../../static/redpacket.png', |
|
|
|
|
|
name: '李雨晴', |
|
|
|
|
|
college: '工商管理学院', |
|
|
|
|
|
choice: 0 |
|
|
|
|
|
} |
|
|
|
|
|
] |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
type: '未当选', |
|
|
|
|
|
title: '2023最佳社团负责人', |
|
|
|
|
|
candidates: [ |
|
|
|
|
|
{ |
|
|
|
|
|
img: '../../static/redpacket.png', |
|
|
|
|
|
name: '王浩然', |
|
|
|
|
|
college: '艺术设计学院', |
|
|
|
|
|
choice: 2 |
|
|
|
|
|
} |
|
|
|
|
|
] |
|
|
|
|
|
} |
|
|
|
|
|
]) |
|
|
|
|
|
|
|
|
|
|
|
// 展开状态管理 |
|
|
// 展开状态管理 |
|
|
const expandedStates = ref([]) |
|
|
const expandedStates = ref([]) |
|
|
watch( |
|
|
watch( |
|
|
() => electionList.value, |
|
|
() => electionList.value, |
|
|
(newVal) => { |
|
|
(newVal) => { |
|
|
expandedStates.value = newVal.map(() => false) |
|
|
expandedStates.value = newVal.map(() => false) |
|
|
}, |
|
|
}, { |
|
|
{ |
|
|
|
|
|
immediate: true |
|
|
immediate: true |
|
|
} |
|
|
} |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
const toggleExpand = (index) => { |
|
|
const toggleExpand = (index) => { |
|
|
expandedStates.value[index] = !expandedStates.value[index] |
|
|
expandedStates.value[index] = !expandedStates.value[index] |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const choiceClass = (choice) => { |
|
|
const choiceClass = (choice) => { |
|
|
switch (choice) { |
|
|
switch (choice) { |
|
|
case 1: |
|
|
case 1: |
|
|
return 'agree' |
|
|
return 'agree' |
|
|
@ -179,27 +90,56 @@ const choiceClass = (choice) => { |
|
|
default: |
|
|
default: |
|
|
return '' |
|
|
return '' |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
const choiceText = (choice) => { |
|
|
const choiceText = (choice) => { |
|
|
return ( |
|
|
return ({ |
|
|
{ |
|
|
|
|
|
1: '同意', |
|
|
1: '同意', |
|
|
0: '反对', |
|
|
0: '反对', |
|
|
2: '弃权' |
|
|
2: '弃权' |
|
|
}[choice] || '' |
|
|
} [choice] || '') |
|
|
) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 获取数据 |
|
|
|
|
|
const getList = async () => { |
|
|
|
|
|
try { |
|
|
|
|
|
loading.value = true |
|
|
|
|
|
|
|
|
|
|
|
// 模拟接口请求(替换为你的真实接口) |
|
|
|
|
|
const mockData = await getMyvote().then((res)=> { |
|
|
|
|
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
// 处理数据 |
|
|
|
|
|
dataList.value = [...dataList.value, ...mockData] |
|
|
|
|
|
|
|
|
|
|
|
// 判断是否还有数据 |
|
|
|
|
|
noMoreData.value = mockData.length < pageSize.value |
|
|
|
|
|
} finally { |
|
|
|
|
|
loading.value = false |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 加载更多 |
|
|
|
|
|
const loadMore = () => { |
|
|
|
|
|
if (loading.value || noMoreData.value) return |
|
|
|
|
|
page.value += 1 |
|
|
|
|
|
getList() |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
onMounted(() => { |
|
|
|
|
|
getList() |
|
|
|
|
|
}) |
|
|
</script> |
|
|
</script> |
|
|
|
|
|
|
|
|
<style scoped lang="scss"> |
|
|
<style scoped lang="scss"> |
|
|
.container { |
|
|
.container { |
|
|
padding: 20rpx; |
|
|
padding: 20rpx; |
|
|
background-color: #f9fafb; |
|
|
background-color: #f9fafb; |
|
|
height: 100vh; |
|
|
height: 100vh; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.election-item { |
|
|
.election-item { |
|
|
margin-bottom: 30rpx; |
|
|
margin-bottom: 30rpx; |
|
|
padding: 34rpx; |
|
|
padding: 34rpx; |
|
|
border-radius: 24rpx; |
|
|
border-radius: 24rpx; |
|
|
@ -207,9 +147,9 @@ const choiceText = (choice) => { |
|
|
box-sizing: border-box; |
|
|
box-sizing: border-box; |
|
|
border: 2rpx solid #f3f4f6; |
|
|
border: 2rpx solid #f3f4f6; |
|
|
box-shadow: 0rpx 2rpx 4rpx 0rpx rgba(0, 0, 0, 0.05); |
|
|
box-shadow: 0rpx 2rpx 4rpx 0rpx rgba(0, 0, 0, 0.05); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.year-title { |
|
|
.year-title { |
|
|
font-size: 32rpx; |
|
|
font-size: 32rpx; |
|
|
font-weight: bold; |
|
|
font-weight: bold; |
|
|
color: #333; |
|
|
color: #333; |
|
|
@ -242,91 +182,91 @@ const choiceText = (choice) => { |
|
|
border-radius: 24rpx; |
|
|
border-radius: 24rpx; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.candidate-item { |
|
|
.candidate-item { |
|
|
display: flex; |
|
|
display: flex; |
|
|
justify-content: space-between; |
|
|
justify-content: space-between; |
|
|
align-items: center; |
|
|
align-items: center; |
|
|
padding: 20rpx 0; |
|
|
padding: 20rpx 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.info-section { |
|
|
.info-section { |
|
|
flex: 1; |
|
|
flex: 1; |
|
|
display: flex; |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
flex-direction: column; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.name { |
|
|
.name { |
|
|
font-family: Roboto; |
|
|
font-family: Roboto; |
|
|
font-size: 28rpx; |
|
|
font-size: 28rpx; |
|
|
font-weight: 500; |
|
|
font-weight: 500; |
|
|
letter-spacing: normal; |
|
|
letter-spacing: normal; |
|
|
color: #000000; |
|
|
color: #000000; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.college { |
|
|
.college { |
|
|
font-family: Roboto; |
|
|
font-family: Roboto; |
|
|
font-size: 24rpx; |
|
|
font-size: 24rpx; |
|
|
font-weight: normal; |
|
|
font-weight: normal; |
|
|
letter-spacing: normal; |
|
|
letter-spacing: normal; |
|
|
color: #6b7280; |
|
|
color: #6b7280; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.choice-tag { |
|
|
.choice-tag { |
|
|
display: flex; |
|
|
display: flex; |
|
|
justify-content: center; |
|
|
justify-content: center; |
|
|
align-items: center; |
|
|
align-items: center; |
|
|
font-family: Roboto; |
|
|
font-family: Roboto; |
|
|
font-size: 28rpx; |
|
|
font-size: 28rpx; |
|
|
font-weight: normal; |
|
|
font-weight: normal; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.agree { |
|
|
.agree { |
|
|
color: #3b82f6; |
|
|
color: #3b82f6; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.oppose { |
|
|
.oppose { |
|
|
color: #f44336; |
|
|
color: #f44336; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.abstain { |
|
|
.abstain { |
|
|
color: #9ca3af; |
|
|
color: #9ca3af; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.year-title { |
|
|
.year-title { |
|
|
display: flex; |
|
|
display: flex; |
|
|
justify-content: space-between; |
|
|
justify-content: space-between; |
|
|
align-items: center; |
|
|
align-items: center; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.expand-btn { |
|
|
.expand-btn { |
|
|
display: flex; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
align-items: center; |
|
|
color: #666; |
|
|
color: #666; |
|
|
font-size: 26rpx; |
|
|
font-size: 26rpx; |
|
|
padding: 10rpx 20rpx; |
|
|
padding: 10rpx 20rpx; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.arrow { |
|
|
.arrow { |
|
|
display: inline-block; |
|
|
display: inline-block; |
|
|
width: 0; |
|
|
width: 0; |
|
|
height: 0; |
|
|
height: 0; |
|
|
margin-left: 10rpx; |
|
|
margin-left: 10rpx; |
|
|
border-left: 10rpx solid transparent; |
|
|
border-left: 10rpx solid transparent; |
|
|
border-right: 10rpx solid transparent; |
|
|
border-right: 10rpx solid transparent; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.down { |
|
|
.down { |
|
|
border-top: 15rpx solid #999; |
|
|
border-top: 15rpx solid #999; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.up { |
|
|
.up { |
|
|
border-bottom: 15rpx solid #999; |
|
|
border-bottom: 15rpx solid #999; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* 优化候选人项间距 */ |
|
|
/* 优化候选人项间距 */ |
|
|
.candidate-item:last-child { |
|
|
.candidate-item:last-child { |
|
|
border-bottom: none; |
|
|
border-bottom: none; |
|
|
} |
|
|
} |
|
|
</style> |
|
|
</style> |