锋哥原创的uniapp微信小程序投票系统实战:

uniapp微信小程序投票系统实战课程 (SpringBoot2+vue3.2+element plus ) ( 火爆连载更新中... )_哔哩哔哩_bilibiliuniapp微信小程序投票系统实战课程 (SpringBoot2+vue3.2+element plus ) ( 火爆连载更新中... )共计21条视频,包括:uniapp微信小程序投票系统实战课程 (SpringBoot2+vue3.2+element plus ) ( 火爆连载更新中... )、第2讲 投票项目后端架构搭建、第3讲 小程序端 TabBar搭建等,UP主更多精彩视频,请关注UP账号。uniapp微信小程序投票系统实战 (SpringBoot2+vue3.2+element plus ) -投票帖子详情实现-LMLPHPhttps://www.bilibili.com/video/BV1ea4y137xf/

uniapp微信小程序投票系统实战 (SpringBoot2+vue3.2+element plus ) -投票帖子详情实现-LMLPHP

uniapp微信小程序投票系统实战 (SpringBoot2+vue3.2+element plus ) -投票帖子详情实现-LMLPHP

后端,根据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点击跳转帖子页面

uniapp微信小程序投票系统实战 (SpringBoot2+vue3.2+element plus ) -投票帖子详情实现-LMLPHP

		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">&#xe739;&nbsp;分享&nbsp;</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, 本次投票&nbsp;{{vote.voteEndTime}}&nbsp;后截止</view>
			</view>
		</view>
	</view>
	<view class="action">
		<view class="item" @click="goHomePage()">
			<view class="voteManageItem">&#xe64f;</view>
			<text class="text" >首页</text>
		</view>
		<view class="item" @click="goCustomerPage()">
			<view class="voteManageItem">&#xec2e;</view>
			<text class="text">客服</text>
		</view>
		<view class="item" v-if="vote.openid==currentUserOpenId" @click="actionSet()">
			<view class="voteManageItem">&#xeb61;</view>
			<text class="text">管理</text>
		</view>
		<view class="item" @click="goVoteDetailPage()">
			<view class="voteManageItem">&#xe643;</view>
			<text class="text" >明细</text>
		</view>
		<view class="item" @click="goRankPage(vote.id)">
			<view class="voteManageItem">&#xe613;</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>
01-12 06:32