锋哥原创的uniapp微信小程序投票系统实战:
后端,根据id查询投票帖子信息:
/**
* 根据id查询
* @param id
* @return
*/
@GetMapping("/{id}")
public R findById(@PathVariable(value = "id")Integer id){
Vote vote = voteService.getById(id);
WxUserInfo wxUserInfo = wxUserInfoService.getOne(new QueryWrapper<WxUserInfo>().eq("openid", vote.getOpenid()));
vote.setWxUserInfo(wxUserInfo);
List<VoteItem> voteItemList = voteItemService.list(new QueryWrapper<VoteItem>().eq("vote_id", id));
vote.setVoteItemList(voteItemList);
Map<String,Object> map=new HashMap<>();
map.put("vote",vote);
return R.ok(map);
}
映射加下:
registry.addResourceHandler("/image/coverImgs/**").addResourceLocations("file:D:\\uniapp\\coverImgs\\");
registry.addResourceHandler("/image/voteItemImgs/**").addResourceLocations("file:D:\\uniapp\\voteItemImgs\\");
新建帖子页面
{
"path": "pages/vote/vote",
"style": {
"navigationBarTitleText": ""
}
},
投票列表页面投票项 加下onclick点击跳转帖子页面
goVotePage:function(voteId){
uni.navigateTo({
url:"/pages/vote/vote?id="+voteId
})
}
vote.vue
<template>
<view class="promoter_info">
<view class="promoter">
<view class="user_image">
<image :src="this.baseUrl+'/image/userAvatar/'+vote.wxUserInfo.avatarUrl" ></image>
</view>
<view class="user_name_wrap">
<text class="nick_name">{{vote.wxUserInfo.nickName}}</text>
<text class="info">投票发起人</text>
</view>
</view>
<view class="share">
<button open-type="share" size="mini"> 分享 </button>
</view>
</view>
<view class="vote">
<view class="cover_title">
<view class="cover" v-if="vote.coverImage!=''">
<image :src="this.baseUrl+'/image/coverImgs/'+vote.coverImage" ></image>
</view>
<view class="title_wrap">
<view class="title">{{vote.title}}</view>
<view class="explanation" v-if="vote.explanation!=''">{{vote.explanation}}</view>
</view>
<view class="explain">
<view class="item">1, 本次投票为单选投票,实名投票</view><br/>
<view class="item">2, 本次投票 {{vote.voteEndTime}} 后截止</view>
</view>
</view>
</view>
<view class="action">
<view class="item" @click="goHomePage()">
<view class="voteManageItem"></view>
<text class="text" >首页</text>
</view>
<view class="item" @click="goCustomerPage()">
<view class="voteManageItem"></view>
<text class="text">客服</text>
</view>
<view class="item" v-if="vote.openid==currentUserOpenId" @click="actionSet()">
<view class="voteManageItem"></view>
<text class="text">管理</text>
</view>
<view class="item" @click="goVoteDetailPage()">
<view class="voteManageItem"></view>
<text class="text" >明细</text>
</view>
<view class="item" @click="goRankPage(vote.id)">
<view class="voteManageItem"></view>
<text class="text">排行</text>
</view>
</view>
<view class="options" v-if="vote.type==1">
<radio-group @change="radioChange">
<view class="option" v-for="item in vote.voteItemList">
<view class="name_vote_number">
<text class="name">{{item.name}}</text>
<view class="number">共 {{item.number}} 票</view>
</view>
<view>
<radio :value="item.id"></radio>
</view>
</view>
</radio-group>
</view>
<view class="options" v-if="vote.type==2">
<radio-group @change="radioChange">
<view class="option" v-for="item in vote.voteItemList">
<view class="name_vote_number">
<text class="name">{{item.name}}</text>
<view class="img"><image :src="this.baseUrl+'/image/voteItemImgs/'+item.image" ></image></view>
<view class="number">共 {{item.number}} 票</view>
</view>
<view>
<radio :value="item.id"></radio>
</view>
</view>
</radio-group>
</view>
<view class="vote_btn" >
<view class="btn1">
<button type="primary" @click="submitVote" v-if="judgeDate(vote.voteEndTime)<0 && sItem>0">立即提交投票</button>
<button type="default" disabled="true" v-if="judgeDate(vote.voteEndTime)<0 && sItem==-1">请选择投票项</button>
<button type="default" disabled="true" v-if="judgeDate(vote.voteEndTime)>=0">该投票已截止</button>
</view>
</view>
</template>
<script>
import {getBaseUrl, requestUtil} from "../../utils/requestUtil.js"
import {isEmpty} from "../../utils/stringUtil.js"
import {judgeDate} from "../../utils/dateUtil.js"
export default{
data(){
return{
vote:{},
baseUrl:'',
currentUserOpenId:'',
sItem:-1
}
},
onLoad(e) {
console.log(e.id);
this.baseUrl=getBaseUrl();
// 通过id获取实体信息,渲染页面
this.getVoteInfo(e.id)
this.currentUserOpenId=uni.getStorageSync("openid");
console.log("currentUserOpenId="+this.currentUserOpenId)
},
methods:{
getVoteInfo:async function(id){
const result=await requestUtil({url:"/vote/"+id,method:"get"});
console.log(result)
this.vote=result.vote;
},
judgeDate:function(toDate){
return judgeDate(toDate);
},
radioChange: function(evt) {
console.log(evt.detail.value)
this.sItem=evt.detail.value;
}
}
}
</script>
<style lang="scss">
@import "/common/css/iconfont.css";
.promoter_info{
padding: 15px;
display: flex;
justify-content: space-between;
background-color: white;
.promoter{
display: flex;
flex-direction: row;
.user_image{
width: 100rpx;
height: 100rpx;
text-align: center;
padding: 0rpx;
margin: 0rpx;
image{
width: 90rpx;
height: 90rpx;
}
}
.user_name_wrap{
display: flex;
flex-direction: column;
padding-left: 10px;
.nick_name{
}
.info{
padding-top: 10rpx;
font-size: 25rpx;
}
}
}
button{
border-radius: 15px;
background-color: lightblue;
}
}
.vote{
padding: 10px;
margin-bottom: 0px;
.cover_title{
background-color: white;
border-radius: 10px;
padding-bottom: 10px;
.cover{
padding: 10px;
padding-bottom: 0px;
text-align: center;
image{
width: 650rpx;
height: 300rpx;
border-radius: 10px;
}
}
.title_wrap{
padding-top: 10px;
margin-left: 15px;
margin-right: 15px;
padding-bottom: 15px;
border-bottom: 1px solid #e4e4e4;
.title{
font-size: 20px;
font-weight: bolder;
}
.explanation{
padding-top: 10px;
}
}
.explain{
padding: 15px;
padding-bottom: 5px;
.item{
font-size: 13px;
height: 20px;
}
}
}
}
.action{
margin: 10px;
margin-top: 0px;
padding: 10px;
border-radius: 10px;
background-color: white;
display: flex;
text-align: center;
.item{
flex:1;
text-align: center;
font-size: 12px;
}
}
.options{
margin-top: 0px;
padding: 10px;
padding-top: 0px;
padding-bottom: 70px;
.option{
margin-top: 10px;
display: flex;
justify-content: space-between;
padding: 15px;
border-radius: 10px;
background-color: white;
.name_vote_number{
.name{
padding-left: 2px;
font-weight: bolder;
}
.number{
margin-top: 10px;
padding: 5px;
border-radius: 10px;
background-color: #e6eeff;
font-size: 12px;
width: 55px;
text-align: center;
}
.img{
padding: 5px;
padding-left: 0px;
image{
border-radius: 10px;
width: 450rpx;
height: 300rpx;
}
}
}
}
}
.vote_btn{
height: 120rpx;
width: 100%;
background-color: white;
position: fixed;
bottom: 0;
border-top: 1px solid #e4e4e4;
display: flex;
button{
margin: 10px;
}
.btn1{
flex: 1;
}
}
</style>