预览效果

投票小程序之活动管理Vue + Element UI前端实现_小程序投票小程序之活动管理Vue + Element UI前端实现_vue_02

投票小程序之活动管理Vue + Element UI前端实现_vue_03投票小程序之活动管理Vue + Element UI前端实现_小程序_04

投票小程序之活动管理Vue + Element UI前端实现_小程序_05投票小程序之活动管理Vue + Element UI前端实现_springboot_06

活动管理获取接口

vote\src\api\vote.js


import request from '@/utils/request'

// 获取活动列表
export function fetchList(params) {
return request({
url: '/pmsVote/listPage',
method:'GET',
params:params
})
}
// 创建活动
export function createVote(data) {
return request({
url:'/pmsVote/create',
method:'POST',
data:data
})
}
// 删除活动
export function deleteVote(id) {
return request({
url:'/pmsVote/delete/'+id,
method:'DELETE',
})
}
// 查看活动详情
export function getVote(id) {
return request({
url:'/pmsVote/view/'+id,
method:'GET',
})
}
// 修改活动
export function updateVote(id,data) {
return request({
url:'/pmsVote/update/'+id,
method:'PUT',
data:data
})
}

投票小程序之活动管理Vue + Element UI前端实现_springboot_07

活动管理页面组件

vote\src\views\pms\vote\index.vue

活动首页


<template> 
<div class="app-container">
<el-card class="filter-container" shadow="never">
<div>
<i class="el-icon-search"></i>
<span>筛选搜索</span>

</div>
<div style="margin-top: 15px">
<el-form :inline="true" :model="listQuery" size="small" label-width="140px">
<el-form-item label="输入搜索:">
<el-input style="width: 203px" v-model="listQuery.keyword" placeholder="活动主题/关键字"></el-input>
</el-form-item>
<el-form-item label="活动类型:">
<el-select v-model="listQuery.activityType" placeholder="请选择">
<el-option
v-for="item in activityTypes"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="状态:">
<el-select v-model="listQuery.voteStatus" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-button
style="margin-left:20px"
@click="searchVoteList()"
type="primary"
size="small">
查询结果
</el-button>
</el-form>
</div>
</el-card>
<el-card class="operate-container" shadow="never">
<i class="el-icon-tickets"></i>
<span>数据列表</span>
<el-button
class="btn-add"
type="success"
@click="addVote()"
size="mini">
添加
</el-button>
</el-card>
<div class="table-container">
<el-table ref="voteTable"
:data="list"
style="width: 100%"
v-loading="listLoading"
border>
<el-table-column label="编号" width="100" align="center">
<template slot-scope="scope">{{scope.row.id}}</template>
</el-table-column>
<el-table-column label="主题" align="center">
<template slot-scope="scope">{{scope.row.voteTitle}}</template>
</el-table-column>
<el-table-column label="活动类型" align="center">
<template slot-scope="scope">
<span v-if="scope.row.activityType == 10">报名投票</span>
<span v-if="scope.row.activityType == 20">仅限报名</span>
</template>
</el-table-column>
<el-table-column label="是否开放报名" align="center">
<template slot-scope="scope">
<span v-if="scope.row.isOpenSignup == 0">否</span>
<span v-if="scope.row.isOpenSignup == 1">是</span>
</template>
</el-table-column>
<el-table-column label="报名开始时间" align="center">
<template slot-scope="scope">{{scope.row.signupBeginTime}}</template>
</el-table-column>
<el-table-column label="报名结束时间" align="center">
<template slot-scope="scope">{{scope.row.signupEndTime}}</template>
</el-table-column>
<el-table-column label="投票开始时间" width="150" align="center">
<template slot-scope="scope">{{scope.row.voteBeginTime}}</template>
</el-table-column>
<el-table-column label="投票结束时间" width="150" align="center">
<template slot-scope="scope">{{scope.row.voteEndTime}}</template>
</el-table-column>
<el-table-column label="排序" width="100" align="center">
<template slot-scope="scope">{{scope.row.voteSort}}</template>
</el-table-column>

<el-table-column label="状态" align="center">
<template slot-scope="scope">
<span v-if="scope.row.voteStatus == 10">已保存</span>
<span v-if="scope.row.voteStatus == 20">已生效</span>
<span v-if="scope.row.voteStatus == 30">已失效</span>
</template>
</el-table-column>

<el-table-column label="操作" align="center">
<template slot-scope="scope">
<el-button type="primary" class="btn_o" @click="handleSignup(scope.$index, scope.row)" size="mini">报名管理</el-button>
<el-button type="primary" class="btn_o" @click="handleUpdate(scope.$index, scope.row)" size="mini">修改活动</el-button>
<el-button type="danger" class="btn_o" @click="handleDelete(scope.$index, scope.row)" size="mini">删&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;除</el-button>
</template>
</el-table-column>
</el-table>
</div>

<div class="pagination-container">
<el-pagination
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
layout="total, sizes,prev, pager, next,jumper"
:page-size="listQuery.pageSize"
:page-sizes="[5,10,15]"
:current-page.sync="listQuery.pageNum"
:total="total">
</el-pagination>
</div>
</div>
</template>
<script>
import {fetchList, deleteVote} from '@/api/vote'
export default {
name: 'voteList',
data() {
return {
listQuery: {
keyword: null,
voteStatus:null,
pageNum: 1,
pageSize: 10
},
list: null,
total: null,
listLoading: true,
options: [{
value:'',
label:'全部'
},{
value: 10,
label: '已保存'
}, {
value: 20,
label: '已生效'
}, {
value: 30,
label: '已失效'
}],
activityTypes:[{
value:'',
label:'全部'
},{
value: 10,
label: '报名投票'
}, {
value: 20,
label: '仅限报名'
}],
}
},
created() {
this.getList();
},
methods: {
getList() {
this.listLoading = true;
fetchList(this.listQuery).then(response => {
this.listLoading = false;
this.list = response.rows;
this.total = response.pageInfo.totalRecords;
this.totalPage = response.pageInfo.totalPage;
this.pageSize = response.pageInfo.pageSize;
});
},

handleUpdate(index, row) {
this.$router.push({path: '/pms/updateVote', query: {id: row.id}})
},
handleSignup(index,row){
this.$router.push({path: '/pms/signup', query: {voteId: row.id}})
},
handleDelete(index, row) {
this.$confirm('是否要删除该活动', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteVote(row.id).then(response => {
this.$message({
message: '删除成功',
type: 'success',
duration: 1000
});
this.getList();
});
});
},
handleSizeChange(val) {
this.listQuery.pageNum = 1;
this.listQuery.pageSize = val;
this.getList();
},
handleCurrentChange(val) {
this.listQuery.pageNo = val;
this.getList();
},
searchVoteList() {
this.listQuery.pageNum = 1;
this.getList();
},
addVote() {
this.$router.push({path: '/pms/addVote'})
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>

.btn_o{
display: block;
margin: 5px auto;
}
</style>

投票小程序之活动管理Vue + Element UI前端实现_vue_08

活动编辑组件


<template> 
<el-card class="form-container" shadow="never">
<el-form :model="vote" :rules="rules" ref="voteFrom" label-width="150px">
<el-form-item label="活动主题:" :rules="[
{ required: true, message: '请输入活动主题', trigger: 'blur' },
{ min: 4, max: 50, message: '长度在 4 到 50 个字符', trigger: 'blur' }]" prop="voteTitle">
<el-input v-model="vote.voteTitle"></el-input>
</el-form-item>
<el-form-item label="封面(700px*300px):" :rules="[
{ required: true, message: '请上传封面', trigger: 'blur' }]" prop="voteBanner">
<single-upload v-model="vote.voteBanner"></single-upload>
</el-form-item>
<el-form-item label="活动形式:" :rules="[
{ required: true, message: '请选择活动形式', trigger: 'blur' }]" prop="activityType">
<el-radio-group v-model="vote.activityType">
<el-radio :label="20">仅限报名</el-radio>
<el-radio :label="10">报名投票</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="报名形式:" v-if="vote.activityType == 10" :rules="[
{type:'array', required: true, message: '请选择报名形式', trigger: 'change' }]" prop="checkList">
<el-checkbox-group v-model="vote.checkList">
<el-checkbox label="10" >图片</el-checkbox>
<el-checkbox label="20" >视频</el-checkbox>
<el-checkbox label="30" >文档</el-checkbox>
</el-checkbox-group>
</el-form-item>

<el-form-item label="是否开放报名:" v-if="vote.activityType == 10" :rules="[
{ required: true, message: '请选择是否开放报名', trigger: 'blur' }]" prop="isOpenSignup">
<el-radio-group v-model="vote.isOpenSignup">
<el-radio :label="1">是</el-radio>
<el-radio :label="0">否</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="报名时间:" :rules="[
{ required: true, message: '请选择报名时间', trigger: 'blur' }]" v-if="vote.activityType == 20 || vote.isOpenSignup == 1">
<el-date-picker
v-model="time"
type="datetimerange"
@change="dateChange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
align="right">
</el-date-picker>
</el-form-item>
<el-form-item label="投票时间:" v-if="vote.activityType == 10" :rules="[
{ required: true, message: '请选择投票时间', trigger: 'blur' }]">
<el-date-picker
v-model="time2"
type="datetimerange"
@change="dateChange2"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
align="right">
</el-date-picker>
</el-form-item>
<el-form-item label="每日投票次数:" v-if="vote.activityType == 10" :rules="[
{ required: true, message: '请输入每日投票次数', trigger: 'blur' }]" prop="everydayVoteNum">
<el-input v-model.number="vote.everydayVoteNum"></el-input>
</el-form-item>
<el-form-item label="是否重复投票:" v-if="vote.activityType == 10" :rules="[
{ required: true, message: '请选择是否重复投票', trigger: 'blur' }]" prop="isRepeatVote">
<el-radio-group v-model="vote.isRepeatVote">
<el-radio :label="1">是</el-radio>
<el-radio :label="0">否</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="是否首页展示:" :rules="[
{ required: true, message: '请选择是否首页展示', trigger: 'blur' }]" prop="isShow">
<el-radio-group v-model="vote.isShow">
<el-radio :label="1">是</el-radio>
<el-radio :label="0">否</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="动态报名字段:">
<el-tag
:key="tag"
v-for="tag in vote.dynamicField"
closable
:disable-transitions="false"
@close="handleClose(tag)">
{{tag}}
</el-tag>
<el-input
class="input-new-tag"
v-if="inputVisible"
v-model="inputValue"
ref="saveTagInput"
size="small"
@keyup.enter.native="handleInputConfirm()"
@blur="handleInputConfirm()"
>
</el-input>
<el-button v-else class="button-new-tag" size="small" @click="showInput()">+ 新增字段</el-button>
<span>(示例:电话必填-> "电话|1", 微信非必填-> "微信|0")</span>
</el-form-item>

<!-- <el-form-item label="分享图片(未上传默认为封面图片):">
<single-upload v-model="vote.shareImg"></single-upload>
</el-form-item> -->
<el-form-item label="主办方:">
<el-input v-model="vote.sponsor"></el-input>
</el-form-item>
<el-form-item label="主办方电话:">
<el-input v-model="vote.sponsorPhone"></el-input>
</el-form-item>
<el-form-item label="浏览量:">
<el-input v-model.number="vote.browse"></el-input>
</el-form-item>
<el-form-item label="排序:">
<el-input v-model.number="vote.voteSort"></el-input>
</el-form-item>
<el-form-item label="活动介绍:" :rules="[
{ required: true, message: '请输入活动介绍', trigger: 'blur' },
{ min: 10, message: '长度不能少于10个字符', trigger: 'blur' }]" prop="voteIntroduce">
<tinymce :width="695" :height="600" v-model="vote.voteIntroduce"></tinymce>
</el-form-item>
<el-form-item label="活动奖励:" v-if="vote.activityType == 10" :rules="[
{ required: true, message: '请输入活动奖励', trigger: 'blur' },
{ min: 10, message: '长度不能少于10个字符', trigger: 'blur' }]" prop="voteReward">
<tinymce :width="695" :height="600" v-model="vote.voteReward"></tinymce>
</el-form-item>

<el-form-item style="text-align:center">
<el-button type="primary" @click="onSubmit('voteFrom',10)">保存</el-button>
<el-button type="primary" @click="onSubmit('voteFrom',20)">发布</el-button>
<el-button type="info" v-if="!isEdit" @click="resetForm('voteFrom')">重置</el-button>
<el-button @click="back()">返回</el-button>
</el-form-item>
</el-form>
</el-card>
</template>
<script>
import {createVote, getVote, updateVote} from '@/api/vote'
import SingleUpload from '@/components/Upload/singleUpload'
import Tinymce from '@/components/Tinymce'
const defaultVote={
voteTitle:'',
voteBanner:'',
activityType:20,
signupBeginTime:'',
signupEndTime:'',
voteBeginTime:'',
voteEndTime:'',
isOpenSignup:1,
everydayVoteNum:null,
isRepeatVote:1,
shareImg:'',
isShow:1,
sponsor:'',
sponsorPhone:'',
browse:null,
voteStatus:10,
voteReward:'',
voteType:'',
checkList:[],
dynamicField:[]
};
export default {
name: 'VoteDetail',
components:{SingleUpload,Tinymce},
props: {
isEdit: {
type: Boolean,
default: false
},
},
data() {
return {
vote:Object.assign({}, defaultVote),
time:[],
time2:[],
rules: {

},
inputVisible: false,
inputValue: ''
}
},
created() {
if (this.isEdit) {
getVote(this.$route.query.id).then(response => {
this.vote = response.data;
this.time.push(this.vote.signupBeginTime)
this.time.push(this.vote.signupEndTime)
this.time2.push(this.vote.voteBeginTime)
this.time2.push(this.vote.voteEndTime)
console.log(this.vote.voteType)
if (this.vote.voteType) {
this.vote.checkList = this.vote.voteType.split(",")
}
if (this.vote.dynamicField) {
this.vote.dynamicField = JSON.parse(this.vote.dynamicField);
} else {
this.vote.dynamicField = [];
}
});
}else{
this.vote = Object.assign({},defaultVote);
}
},
methods: {
dateChange(){
if (this.vote.activityType == 10 ) {
if (this.time2.length > 0 && new Date(this.time2[0]) < new Date(this.time[0])) {
this.$message({
message: '报名时间不能在投票时间之后',
type: 'error',
duration:1000
});
this.time = [];
return false;
}
}
this.vote.signupBeginTime=this.time[0]
this.vote.signupEndTime=this.time[1]
},
dateChange2(){
if (this.time.length > 0 && new Date(this.time2[0]) < new Date(this.time[0])) {
this.$message({
message: '投票时间不能在报名时间之前',
type: 'error',
duration:1000
});
this.time2 = [];
return false;
}
this.vote.voteBeginTime=this.time2[0]
this.vote.voteEndTime=this.time2[1]
},
onSubmit(formName,status) {
if (this.vote.isOpenSignup == 1) {
if (this.time.length <= 0) {
this.$message({
message: '请选择报名时间',
type: 'error',
duration:1000
});
return false;
}
}

if (this.vote.activityType == 10 ) {
if (this.time2.length <= 0 || !this.time2[0] || !this.time2[1]) {
this.$message({
message: '请选择投票时间',
type: 'error',
duration:1000
});
return false;
}
}


this.vote.voteType = this.vote.checkList.join(",")
console.log(this.vote.checkList.join(","))
let title = "是否提交数据";
if (status === 20) {
title = "确定发布"
}
this.vote.voteStatus = status;
this.$refs[formName].validate((valid) => {
if (valid) {
this.$confirm(title, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
if (this.isEdit) {
updateVote(this.$route.query.id, this.vote).then(response => {
//this.$refs[formName].resetFields();
this.$message({
message: '修改成功',
type: 'success',
duration:1000
});
this.$router.back();
});
} else {
createVote(this.vote).then(response => {
//this.$refs[formName].resetFields();
this.vote = Object.assign({},defaultVote);
this.$message({
message: '提交成功',
type: 'success',
duration:1000
});
this.$router.back();
});
}
});

} else {
this.$message({
message: '验证失败',
type: 'error',
duration:1000
});
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
this.vote = Object.assign({},defaultVote);
},
back(){
this.$router.back();
},
handleClose(tag) {
this.vote.dynamicField.splice(this.vote.dynamicField.indexOf(tag), 1);
},

showInput() {
this.inputVisible = true;
this.$nextTick(_ => {
this.$refs.saveTagInput.$refs.input.focus();
});
},

handleInputConfirm() {
let inputValue = this.inputValue;
if (inputValue) {
this.vote.dynamicField.push(inputValue);
}
this.inputVisible = false;
this.inputValue = '';
}

}

}
</script>
<style>
.el-tag + .el-tag {
margin-left: 10px;
}
.button-new-tag {
margin-left: 10px;
height: 32px;
line-height: 30px;
padding-top: 0;
padding-bottom: 0;
}
.input-new-tag {
width: 90px;
margin-left: 10px;
vertical-align: bottom;
}
</style>

投票小程序之活动管理Vue + Element UI前端实现_vue_09

活动添加


<template> 
<vote-detail :is-edit='false'></vote-detail>
</template>
<script>
import VoteDetail from './components/VoteDetail'
export default {
name: 'addVote',
components: { VoteDetail }
}
</script>
<style>
</style>

投票小程序之活动管理Vue + Element UI前端实现_小程序_10

活动修改


<template> 
<vote-detail :is-edit='true'></vote-detail>
</template>
<script>
import VoteDetail from './components/VoteDetail'
export default {
name: 'updateVote',
components: { VoteDetail }
}
</script>
<style>
</style>

投票小程序之活动管理Vue + Element UI前端实现_java_11

活动管理对应的路由

vote\src\router\index.js


{
path: 'vote',
name: 'vote',
component: () => import('@/views/pms/vote'),
meta: {title: '活动管理', icon: 'product'}
},
{
path: 'addVote',
name: 'addVote',
component: () => import('@/views/pms/vote/add'),
meta: {title: '添加活动'},
hidden: true
},
{
path: 'updateVote',
name: 'updateVote',
component: () => import('@/views/pms/vote/update'),
meta: {title: '修改活动'},
hidden: true
},

投票小程序之活动管理Vue + Element UI前端实现_springboot_12