沈明 1 year ago
parent
commit
139708e509
  1. 4
      .gitignore
  2. 4
      src/pages.json
  3. 331
      src/pages/myElection/index.vue
  4. 54
      src/pages/votingElection/index.vue
  5. 2
      src/uni.scss
  6. 181
      uni.css

4
.gitignore

@ -25,4 +25,6 @@ yarn-error.log*
.hbuilderx .hbuilderx
package-lock.josn package-lock.josn
pnpm-lock.yaml pnpm-lock.yaml
/types/auto-imports.d.ts

4
src/pages.json

@ -41,7 +41,7 @@
"style": { "style": {
"navigationBarTitleText": "我的选举", "navigationBarTitleText": "我的选举",
"navigationBarTextStyle": "white", "navigationBarTextStyle": "white",
"enablePullDownRefresh": false "enablePullDownRefresh": true
} }
}, },
{ {
@ -78,7 +78,7 @@
"color": "#9CA3AF", "color": "#9CA3AF",
"selectedColor": "#2563EB", "selectedColor": "#2563EB",
"borderStyle": "white", "borderStyle": "white",
"backgroundColor": "#F9FAFB", "backgroundColor": "#FFFFFF",
"list": [ "list": [
{ {
"pagePath": "pages/votingElection/index", "pagePath": "pages/votingElection/index",

331
src/pages/myElection/index.vue

@ -1,7 +1,332 @@
<template> <template>
<view>我的选举</view> <view class="container">
<view v-for="(item, index) in electionList" :key="index" class="election-item">
<view class="year-title">
<view class="headpart">
<text class="title">{{ item.title }}</text>
<view
class="type"
:style="
item.type == '投票中'
? 'background: #DBEAFE;color: #3B82F6;'
: item.type == '当选'
? 'background: #DCFCE7;color: #10B981'
: 'background: #F3F4F6;color: #4B5563'
"
>
{{ item.type }}
</view>
</view>
</view>
<view class="flex-center-between" style="display: flex">
<view style="display: grid">
<view
v-for="(candidate, cIndex) in item.candidates.slice(0, expandedStates[index] ? item.candidates.length : 1)"
:key="cIndex"
class="candidate-item"
>
<view class="info-section">
<view style="display: flex; align-items: center">
<img style="width: 96rpx; height: 96rpx; border-radius: 50%" :src="item.img" alt="" />
<view style="margin-left: 24rpx; display: grid">
<text class="name">{{ candidate.name }}</text>
<text class="college">{{ candidate.college }}</text>
</view>
</view>
<view style="display: flex; margin-top: 24rpx">
我的选择
<view :class="['choice-tag', choiceClass(candidate.choice)]">
{{ choiceText(candidate.choice) }}
</view>
</view>
</view>
</view>
</view>
<view class="expand-btn" @click="toggleExpand(index)">
<text :class="['arrow', expandedStates[index] ? 'up' : 'down']"></text>
</view>
</view>
</view>
</view>
</template> </template>
<script lang="ts" setup></script> <script setup>
import { ref, watch } from 'vue'
<style lang="scss" scoped></style> const electionList = ref([
{
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: '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([])
watch(
() => electionList.value,
(newVal) => {
expandedStates.value = newVal.map(() => false)
},
{
immediate: true
}
)
const toggleExpand = (index) => {
expandedStates.value[index] = !expandedStates.value[index]
}
const choiceClass = (choice) => {
switch (choice) {
case 1:
return 'agree'
case 0:
return 'oppose'
case 2:
return 'abstain'
default:
return ''
}
}
const choiceText = (choice) => {
return (
{
1: '同意',
0: '反对',
2: '弃权'
}[choice] || ''
)
}
</script>
<style scoped lang="scss">
.container {
padding: 20rpx;
background-color: #f9fafb;
height: 100vh;
}
.election-item {
margin-bottom: 30rpx;
padding: 40rpx;
border-radius: 24rpx;
background: linear-gradient(0deg, rgba(0, 0, 0, 0.001), rgba(0, 0, 0, 0.001)), #ffffff;
box-sizing: border-box;
border: 2rpx solid #f3f4f6;
box-shadow: 0rpx 2rpx 4rpx 0rpx rgba(0, 0, 0, 0.05);
}
.year-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
.headpart {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
.title {
font-family: Roboto;
font-size: 32rpx;
font-weight: 500;
letter-spacing: normal;
color: #000000;
}
.type {
font-family: Roboto;
font-size: 24rpx;
font-weight: normal;
/* 自动布局 */
display: flex;
flex-direction: column;
padding: 4rpx 16rpx;
gap: 0rpx 20rpx;
flex-wrap: wrap;
align-content: flex-start;
border-radius: 24rpx;
}
}
}
.candidate-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx 0;
}
.info-section {
flex: 1;
display: flex;
flex-direction: column;
}
.name {
font-family: Roboto;
font-size: 28rpx;
font-weight: 500;
letter-spacing: normal;
color: #000000;
}
.college {
font-family: Roboto;
font-size: 24rpx;
font-weight: normal;
letter-spacing: normal;
color: #6b7280;
}
.choice-tag {
display: flex;
justify-content: center;
align-items: center;
font-family: Roboto;
font-size: 28rpx;
font-weight: normal;
}
.agree {
color: #3b82f6;
}
.oppose {
color: #f44336;
}
.abstain {
color: #9ca3af;
}
.year-title {
display: flex;
justify-content: space-between;
align-items: center;
}
.expand-btn {
display: flex;
align-items: center;
color: #666;
font-size: 26rpx;
padding: 10rpx 20rpx;
}
.arrow {
display: inline-block;
width: 0;
height: 0;
margin-left: 10rpx;
border-left: 10rpx solid transparent;
border-right: 10rpx solid transparent;
}
.down {
border-top: 15rpx solid #999;
}
.up {
border-bottom: 15rpx solid #999;
}
/* 优化候选人项间距 */
.candidate-item:last-child {
border-bottom: none;
}
</style>

54
src/pages/votingElection/index.vue

@ -9,29 +9,39 @@ const doSearch = (_formData: { page: number; limit: number }, onSuccess: Functio
data: { data: {
data: [ data: [
{ {
id: 1,
img: '/static/img/grxx.png', img: '/static/img/grxx.png',
name: '陈志远', name: '陈志远',
class: '现任财务总监' class: '现任财务总监',
yijian: ''
}, },
{ {
id: 2,
img: '/static/img/grxx.png', img: '/static/img/grxx.png',
name: '陈志远', name: '陈志远',
class: '现任财务总监' class: '现任财务总监',
yijian: ''
}, },
{ {
id: 3,
img: '/static/img/grxx.png', img: '/static/img/grxx.png',
name: '陈志远', name: '陈志远',
class: '现任财务总监' class: '现任财务总监',
yijian: ''
}, },
{ {
id: 4,
img: '/static/img/grxx.png', img: '/static/img/grxx.png',
name: '陈志远', name: '陈志远',
class: '现任财务总监' class: '现任财务总监',
yijian: ''
}, },
{ {
id: 5,
img: '/static/img/grxx.png', img: '/static/img/grxx.png',
name: '陈志远', name: '陈志远',
class: '现任财务总监' class: '现任财务总监',
yijian: ''
} }
], ],
total: 0 total: 0
@ -39,34 +49,39 @@ const doSearch = (_formData: { page: number; limit: number }, onSuccess: Functio
}) })
} }
const selectIndex = ref(0)
const buttlist = ref([ const buttlist = ref([
{ {
type: 'agree',
butname: '同意' butname: '同意'
}, },
{ {
type: 'disagree',
butname: '反对' butname: '反对'
}, },
{ {
type: 'neutral',
butname: '弃权' butname: '弃权'
} }
]) ])
const selectBut = (index: number) => { const selectBut = (data: any, cardid: any, type: string) => {
selectIndex.value = index const target = data.find((card: { id: any }) => card.id === cardid)
if (target) {
target.yijian = target.yijian === type ? null : type
}
} }
</script> </script>
<template> <template>
<!-- 你的页面内容 --> <!-- 你的页面内容 -->
<view class="box"> <view class="box">
<ex-list ref="reListRef" custom-list-type="scroll" :on-form-search="doSearch" empty-text=""> <view class="headpart">
<view class="title">2024年度董事会成员选举</view>
<view class="time">投票开始时间2024年3月15日 18:00</view>
<view class="time">投票截止时间2024年3月15日 18:00</view>
</view>
<ex-list ref="reListRef" custom-list-type="custom" :on-form-search="doSearch">
<template v-slot="{ data }"> <template v-slot="{ data }">
<view class="headpart">
<view class="title">2024年度董事会成员选举</view>
<view class="time">投票开始时间2024年3月15日 18:00</view>
<view class="time">投票截止时间2024年3月15日 18:00</view>
</view>
<view class="tppart"> <view class="tppart">
<view class="tpone" v-for="(row, index) of data" :key="'tpone' + index"> <view class="tpone" v-for="(row, index) of data" :key="'tpone' + index">
<view class="topp"> <view class="topp">
@ -83,10 +98,10 @@ const selectBut = (index: number) => {
<view class="bottomp"> <view class="bottomp">
<view <view
class="minbut" class="minbut"
v-for="(item, index) in buttlist" v-for="(item, ele) in buttlist"
:key="'minbut' + index" :key="ele"
@click="selectBut(index)" @click="selectBut(data, row.id, item.type)"
:class="{ active: selectIndex === index }" :class="{ active: row.yijian === item.type }"
> >
{{ item.butname }} {{ item.butname }}
</view> </view>
@ -105,11 +120,10 @@ const selectBut = (index: number) => {
<style scoped lang="scss"> <style scoped lang="scss">
.box { .box {
width: 100%; width: 100%;
height: 100vh;
background-color: #f9fafb; background-color: #f9fafb;
.headpart { .headpart {
width: 86%; width: 92%;
height: 194rpx; height: 194rpx;
border-radius: 24rpx; border-radius: 24rpx;
background-color: #eff6ff; background-color: #eff6ff;

2
src/uni.scss

@ -1,4 +1,4 @@
@import 'uview-plus/theme.scss'; // @import 'uview-plus/theme.scss';
// @use 'uview-plus/theme.scss'; // @use 'uview-plus/theme.scss';
#app { #app {

181
uni.css

@ -0,0 +1,181 @@
@charset "UTF-8";
#app {
box-sizing: border-box;
background-color: #f5f5f5;
}
/* 颜色变量 */
/*============================= 文字尺寸 =============================*/
image {
width: 100%;
height: 100%;
box-sizing: border-box;
}
view {
box-sizing: border-box;
}
/*============================= 弹性盒子 =============================*/
.flex-end-evenly, .flex-end-around, .flex-end-between, .flex-end-end, .flex-end-center, .flex-end-start, .flex-center-evenly, .flex-center-around, .flex-center-between, .flex-center-end, .flex-center-start, .flex-start-evenly, .flex-start-around, .flex-start-between, .flex-start-end, .flex-start-center, .flex-start-start, .flex {
display: flex;
flex-wrap: nowrap;
}
.flex {
align-items: center;
justify-content: center;
}
.flex-start-start {
align-items: flex-start;
justify-content: flex-start;
}
.flex-start-center {
align-items: flex-start;
justify-content: center;
}
.flex-start-end {
align-items: flex-start;
justify-content: flex-end;
}
.flex-start-between {
align-items: flex-start;
justify-content: space-between;
}
.flex-start-around {
align-items: flex-start;
justify-content: space-around;
}
.flex-start-evenly {
align-items: flex-start;
justify-content: space-evenly;
}
.flex-center-start {
align-items: center;
justify-content: flex-start;
}
.flex-center-end {
align-items: center;
justify-content: flex-end;
}
.flex-center-between {
align-items: center;
justify-content: space-between;
}
.flex-center-around {
align-items: center;
justify-content: space-around;
}
.flex-center-evenly {
align-items: center;
justify-content: space-evenly;
}
.flex-end-start {
align-items: flex-end;
justify-content: flex-start;
}
.flex-end-center {
align-items: flex-end;
justify-content: center;
}
.flex-end-end {
align-items: flex-end;
justify-content: flex-end;
}
.flex-end-between {
align-items: flex-end;
justify-content: space-between;
}
.flex-end-around {
align-items: flex-end;
justify-content: space-around;
}
.flex-end-evenly {
align-items: flex-end;
justify-content: space-evenly;
}
[class*=flex-].nowrap,
[class^=flex].nowrap {
flex-wrap: nowrap;
}
[class*=flex-].stretch,
[class^=flex].stretch {
align-items: stretch;
}
[class*=flex-].row,
[class^=flex].row {
flex-direction: row;
}
[class*=flex-].row-reverse,
[class^=flex].row-reverse {
flex-direction: "row-reverse";
}
[class*=flex-].column,
[class^=flex].column {
flex-direction: column;
}
[class*=flex-].column-reverse,
[class^=flex].column-reverse {
flex-direction: "column-reverse";
}
[class*=flex-].wrap,
[class^=flex].wrap {
flex-wrap: wrap;
}
[class*=flex-].wrap-reverse,
[class^=flex].wrap-reverse {
flex-wrap: "wrap-reverse";
}
.flex1 {
flex: 1;
}
.flex2 {
flex: 2;
}
.flex3 {
flex: 3;
}
.flex4 {
flex: 4;
}
/*============================= 文字溢出 =============================*/
.text-ellipsis {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.text-ellipsis-2 {
overflow: hidden;
white-space: normal;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
line-clamp: 1;
-webkit-line-clamp: 2;
}
.text-ellipsis-3 {
overflow: hidden;
white-space: normal;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
line-clamp: 1;
-webkit-line-clamp: 3;
}
.text-ellipsis-4 {
overflow: hidden;
white-space: normal;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
line-clamp: 1;
-webkit-line-clamp: 4;
}
/*# sourceMappingURL=uni.css.map */
Loading…
Cancel
Save