一、后端
1、xmlsql
<select id="voteList" resultMap="BaseResultMap" >
select
<include refid="Base_Column_List" />
from t_oa_meeting_info
where 1=1
<if test="state!=null">
and state=#{state}
</if>
<if test="title!=null">
and title like concat('%',#{title},'%')
</if>
</select>
<select id="voteList" resultMap="BaseResultMap" >
select
<include refid="Base_Column_List" />
from t_oa_meeting_info
where 1=1
<if test="state!=null">
and state=#{state}
</if>
<if test="title!=null">
and title like concat('%',#{title},'%')
</if>
</select>
2、实现接口
编写接口方法
package com.zking.ssm.mapper;
import com.zking.ssm.model.Info;
import java.util.List;
public interface InfoMapper {
int deleteByPrimaryKey(Long id);
int insert(Info record);
int insertSelective(Info record);
Info selectByPrimaryKey(Long id);
int updateByPrimaryKeySelective(Info record);
int updateByPrimaryKey(Info record);
List<Info> list(Info info);
List<Info> voteList(Info info);
}
package com.zking.ssm.mapper;
import com.zking.ssm.model.Option;
public interface OptionMapper {
int deleteByPrimaryKey(String id);
int insert(Option record);
int insertSelective(Option record);
Option selectByPrimaryKey(String id);
int updateByPrimaryKeySelective(Option record);
int updateByPrimaryKey(Option record);
}
实现接口
package com.zking.ssm.service.impl;
import com.zking.ssm.mapper.InfoMapper;
import com.zking.ssm.mapper.WxUserMapper;
import com.zking.ssm.model.Info;
import com.zking.ssm.service.InfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @软件包名 com.zking.ssm.service.impl
* @用户 tgq
* @create 2023-10-24 上午11:24
* @注释说明:
*/
@Service
public class InfoServiceImpl implements InfoService {
@Autowired
private InfoMapper infoMapper;
@Override
public int updateByPrimaryKeySelective(Info record) {
return infoMapper.updateByPrimaryKeySelective(record);
}
@Override
public List<Info> voteList(Info info) {
return infoMapper.voteList(info);
}
}
package com.zking.ssm.service.impl;
import com.zking.ssm.mapper.OptionMapper;
import com.zking.ssm.model.Option;
import com.zking.ssm.service.OptionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @软件包名 com.zking.ssm.service.impl
* @用户 tgq
* @create 2023-10-24 下午9:57
* @注释说明:
*/
@Service
public class OptionServiceImpl implements OptionService {
@Autowired
private OptionMapper om;
@Override
public int insertSelective(Option record) {
return om.insertSelective(record);
}
}
3、编写Controller
package com.zking.ssm.wxcontroller;
import com.zking.ssm.mapper.InfoMapper;
import com.zking.ssm.model.Info;
import com.zking.ssm.util.ResponseUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
*/
@SuppressWarnings("all")
@RestController
@RequestMapping("/wx/info")
public class WxInfoController {
@Autowired
private InfoMapper infoMapper;
@RequestMapping("/list")
public Object list (Info info){
List<Info> list = infoMapper.list(info);
Map<Object, Object> data = new HashMap<Object, Object>();
data.put("infoList",list);
return ResponseUtil.ok(data);
}
@RequestMapping("/votelist")
public Object voteList (Info info){
List<Info> list = infoMapper.voteList(info);
Map<Object, Object> data = new HashMap<Object, Object>();
data.put("voteList",list);
return ResponseUtil.ok(data);
}
@RequestMapping("/update")
public Object update (Info info){
int i = infoMapper.updateByPrimaryKeySelective(info);
return ResponseUtil.ok(i);
}
}
package com.zking.ssm.wxcontroller;
import com.zking.ssm.mapper.InfoMapper;
import com.zking.ssm.mapper.OptionMapper;
import com.zking.ssm.model.Info;
import com.zking.ssm.model.Option;
import com.zking.ssm.util.ResponseUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Autho donkee
* @Since 2022/7/29
*/
@SuppressWarnings("all")
@RestController
@RequestMapping("/wx/option")
public class WxOptionController {
@Autowired
private OptionMapper optionMapper;
@RequestMapping("/insert")
public Object insertSelective(Option option) {
int i = optionMapper.insertSelective(option);
return ResponseUtil.ok(i);
}
}
二、前端
里面有一些技术这里就不多做讲解了,可以查看我的专栏微信小程序_无法自律的人的博客-CSDN博客。
在这里面运用到了一个小程序的插件Dialog 弹出框 - Vant Weapp (youzan.github.io)。在Vant Weapp里面有很多使用的插件,可以更便捷使用起来,主要引用需要自己查看官方文档了。
1、页面布置
wxml
<!--pages/vote/list/list.wxml-->
<!-- <text>投票</text> -->
<!-- <tabs inner-text='6666'></tabs> -->
<tabs tabList="{{tabs}}" bindtabsItemChange="tabsItemChange">
<view class="search-container">
<input class="search-input" bindblur="ontitle" bindblur="onBlur" placeholder="会议标题" />
<!-- <input class="search-input" bindinput="searchInputTwo" placeholder="投票标题" /> -->
<button type="primary" plain="true" size="mini" bindtap="likelist">搜索</button>
</view>
</tabs>
<!-- <view style="background-color: #aaa;height: 120rpx;"></view> -->
<view>
<view class="list" data-id="">
<view class="list-img al-center">
<image class="video-img" mode="scaleToFill" src=""></image>
</view>
<view class="list-detail">
<view class="list-title"><text><text style="margin-right: 13rpx;"></text></text></view>
<view class="list-title"><text></text></view>
<view class="list-tag">
<view class="state al-center"></view>
<view class="join al-center"><text class="list-count"></text></view>
</view>
<view class="list-info"><text style="font-weight: bold;"></text><text></text> <text style="float: right;"></text> </view>
<view>
<button class="btn"></button>
</view>
</view>
</view>
<!-- <wxs src="../../utils/capture.wxs" module="tools" /> -->
<wxs src="/utils/capture.wxs" module="tools" />
<block wx:for-items="{{lists}}" wx:for-item="item" wx:key="item.id">
<view class="list" data-id="{{item.id}}">
<view class="list-img al-center">
<image class="video-img" mode="scaleToFill" src="/static/persons/7.jpg"></image>
</view>
<view class="list-detail">
<view class="list-title"><text><text style="margin-right: 13rpx;"> 发 起 人</text> : {{item.zhuchiren}}</text></view>
<view class="list-title"><text>会议名称 : {{item.title}}</text></view>
<!-- <view class="list-title"><text>投票标题 : [ {{item.vote}} ]</text></view> -->
<view class="list-tag">
<view class="state al-center">{{tools.getState(item.state)}}</view>
<view class="join al-center"><text class="list-count">{{tools.getNumber(item.canyuze,item.liexize,item.zhuzhiren)}}</text>人参与会议</view>
</view>
<view class="list-info"><text style="font-weight: bold;">地址:</text><text>{{item.location}}</text> <text style="float: right;">开始时间:{{tools.formatDate(item.starttime,'YY-MM-DD hh-mm-ss')}}结束时间:{{tools.formatDate(item.endTime,'YY-MM-DD hh-mm-ss')}}</text> </view>
<view data-id="{{item.id}}" bindtap="{{data.state == 5 ? 'show1' : 'showPopup'}}">
<button class="btn">{{data.state == 5? '开启投票' : '参与投票'}}</button>
<!-- <button wx:if="{{data.state == 5}}" class="btn" bindtap="show1">开启投票</button>
<button wx:else="{{data.state == 6}}" class="btn" bindtap="showPopup">参与投票</button> -->
</view>
</view>
</view>
</block>
<view class="section bottom-line">
<text>到底啦</text>
</view>
</view>
<!-- 开启投票 弹窗-->
<van-dialog use-slot title="请添加投票选项" show="{{ show1 }}" show-cancel-button bind:close="onClose1" bind:confirm="getVoteState">
<view class="container">
<view class="input-box">
<input placeholder="请输入投票选项" bindblur="onOptionValue" bindinput="bindInput"></input>
</view>
<view class="checkbox-group">
<view class="checkbox-item" data-id="1" bindtap="toggleCheckbox">同意</view>
<view class="checkbox-item" data-id="2" bindtap="toggleCheckbox">不同意</view>
<view class="checkbox-item" data-id="3" bindtap="toggleCheckbox">保留意见</view>
<view class="checkbox-item" data-id="4" bindtap="toggleCheckbox">弃票</view>
</view>
</view>
</van-dialog>
<!-- 选择投票选项 弹窗 -->
<van-dialog use-slot title="选择投票" show="{{ show }}" show-cancel-button bind:close="onClose" bind:confirm="getVoteOption">
<view class="container">
<view class="input-box">
<!-- <input placeholder="请输入投票选项" bindinput="bindInput"></input> -->
</view>
<view class="checkbox-group">
<view class="checkbox-item {{ checkbox1 ? 'active' : '' }}" data-id="1" bindtap="toggleCheckbox">同意</view>
<view class="checkbox-item {{ checkbox2 ? 'active' : '' }}" data-id="2" bindtap="toggleCheckbox">不同意</view>
<view class="checkbox-item {{ checkbox3 ? 'active' : '' }}" data-id="3" bindtap="toggleCheckbox">保留意见</view>
<view class="checkbox-item {{ checkbox4 ? 'active' : '' }}" data-id="4" bindtap="toggleCheckbox">弃票</view>
</view>
</view>
</van-dialog>
2、功能实现
js
// pages/vote/list/list.js ../../config/api.js
const api = require('../../../config/api.js');
const util = require('../../../utils/util.js');
const app = getApp();
Page({
/**
* 页面的初始数据
*/
data: {
show: false,
show1: false,
tabs: ['未开启投票', '已开启投票'],
lists: [],
inputValue: '',//输入框内容
data: {
id: 0,
state: 5,
title: ''
},
option: {
meetingId: 0,
optionValue: ''
},
checkbox1: false,
checkbox2: false,
checkbox3: false,
checkbox4: false
},
onBlur: function (e) {//输入框获取事件
this.setData({
inputValue: e.detail.value
});
},
onOptionValue: function (e) {//弹窗1输入框获取
this.setData({
option: { optionValue: e.detail.value }
});
},
likelist() {//搜索事件
// console.log(this.data.inputValue);
this.data.data.title = this.data.inputValue
this.InfoVote();
},
tabsItemChange(e) {//是否投票
var tolists;
if (e.detail.index == 0) {
tolists = 5;
this.data.data.state = 5
// tolists = this.data.lists;
} else if (e.detail.index == 1) {
// tolists = this.data.lists;
tolists = 6;
this.data.data.state = 6
}
this.setData({
data: {
state: tolists
}
})
console.log(e.detail, this.data.Profile, this.data.data, tolists);
this.InfoVote();
},
InfoVote() {//初始化数据
util.request(api.MettingInfoVote, this.data.data).then(res => {
// console.log(res)
this.setData({
lists: res.data.voteList
})
}).catch(res => {
console.log('服器没有开启,使用模拟数据!')
})
},
toggleCheckbox: function (e) {
var checkboxId = e.currentTarget.dataset.id;
var data = {}; // 更新的状态数据
// 遍历每个复选框的状态变量,根据点击的复选框的id确定是否选中
Object.keys(this.data).forEach(key => {
if (key.includes('checkbox') && key !== `checkbox${checkboxId}` && this.data[key]) {
data[key] = false; // 将其他复选框的状态设为false
}
});
// 切换当前复选框的选中状态
data[`checkbox${checkboxId}`] = !this.data[`checkbox${checkboxId}`];
this.setData(data);
},
// 1弹窗
show1(e) {
// console.log(e, e.currentTarget.dataset.id)
this.setData({
data: {
id: e.currentTarget.dataset.id
},
})
this.setData({
show1: true
})
// console.log(e.currentTarget.dataset.id, this.data.data)
},
getVoteState(e) {//开启投票确认事件
console.log(e, this.data.data, this.data.option.meetingId);
var optiondata = {
meetingId: this.data.data.id,
optionValue: this.data.option.optionValue
}
// console.log(optiondata)
util.request(api.MettingOptionInsert, optiondata).then(res => {//添加投票选项
// console.log(api.MettingOptionInsert);
if (res.errno == 0) {
wx.showToast({
title: '开启投票成功',
icon: 'none',
duration: 1500//持续的时间
})
util.request(api.MettingInfoupdate, { id: optiondata.meetingId, state: 6 }).then(r => {//更改会议状态
// console.log(api.MettingInfoupdate);
// this.InfoVote('');
if (res.errno == 0) {
this.data.data.state = 5
this.InfoVote('');
}
}).catch(res => {
console.log('服器没有开启,使用模拟数据!')
})
}
}).catch(res => {
console.log('服器没有开启,使用模拟数据!')
})
// console.log(123,i)
},
onClose1() {
this.setData({ show1: false });
},
// 2弹窗
showPopup(e) {
this.setData({
show: true,
data: {
id: e.currentTarget.dataset.id
}
})
},
getVoteOption(e) {//参与投票确认事件
console.log(2, e.detail);
},
onClose() {
this.setData({ show: false });
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
// this.data.Profile=true
this.InfoVote('');
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
})
3、页面美化
wxss
/* pages/vote/list/list.wxss */
.search-container {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
background-color: #ffffff;
border: cornsilk;
}
.search-input {
width: 45%;
padding: 8px;
border-radius: 20px;
border: 1px solid rgb(255, 255, 255);
font-size: 14px;
transition: border-color 0.3s;
border: cornsilk;
}
.search-input:focus {
outline: none;
border-color: #51a7f9;
}
.search-input::placeholder {
color: #999;
}
.search-input::-webkit-input-placeholder {
color: #999;
}
.search-input::-moz-placeholder {
color: #999;
}
.search-input:-ms-input-placeholder {
color: #999;
}
/* .search-container {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
background-color: #f0f0f0;
}
.search-input {
width: 45%;
padding: 8px;
border-radius: 4px;
border: 1px solid #ccc;
font-size: 14px;
} */
.list {
display: flex;
flex-direction: row;
width: 100%;
padding: 0 20rpx 0 0;
background-color: seashell;
border-bottom: 1px solid #cecece;
margin-bottom: 5rpx;
height: 350rpx;
}
.list-img {
display: flex;
margin: 10rpx 10rpx;
width: 160rpx;
height: 250rpx;
justify-content: center;
align-items: center;
flex-direction: column;
}
.list-img .video-img {
width: 140rpx;
height: 160rpx;
border-radius: 6px;
}
.list-detail {
margin: 10rpx 10rpx;
display: flex;
flex-direction: column;
width: 600rpx;
height: 300rpx;
}
.list-title text {
font-size: 9pt;
color: #333;
font-weight: bold;
}
.list-detail {
display: flex;
height: 100rpx;
}
.list-tag {
display: flex;
}
.state {
font-size: 9pt;
color: blue;
width: 120rpx;
height: 40rpx;
border: 1px solid blue;
border-radius: 2px;
margin: 10rpx 0rpx;
display: flex;
justify-content: center;
align-items: center;
}
.join {
font-size: 11pt;
color: #bbb;
margin-left: 20rpx;
display: flex;
justify-content: center;
align-items: center;
}
.list-count {
margin-right: 10rpx;
font-size: 11pt;
color: red;
}
.list-info {
font-size: 9pt;
color: #bbb;
}
.btn {
/* width: 10rpx;
height: 40rpx;
background-color: #3388ff;
color: #fff;
text-align: center;
font-size: 16rpx;
display: flex;
justify-content: center;
align-items: center; */
background-color: #3388ff;
color: #fff;
border-radius: 4rpx;
font-size: 16rpx;
padding: 10rpx 20rpx;
/* background-color: #3388ff;
color: #fff;
border-color: #3388ff; */
/* width: 100rpx;
height: 40rpx;
border: 1rpx solid #3388ff;
border-radius: 4rpx;
font-size: 16rpx;
background-color: #3388ff;
color: #fff;
outline: none;
box-shadow: 0 0 5rpx #3388ff; */
/* width: 60rpx;
height: 30rpx;
border-radius: 4rpx;
font-size: 16rpx; */
/* width: 40rpx;
height: 40rpx;
background-color: transparent;
border: none;
font-size: 24rpx;
color: #666; */
}
.bottom-line {
display: flex;
height: 60rpx;
justify-content: center;
align-items: center;
background-color: #f3f3f3;
}
.bottom-line text {
font-size: 9pt;
color: #666;
}
/* 弹窗 */
.container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.input-box {
margin-top: 20px;
}
.checkbox-group {
display: flex;
flex-direction: column;
margin-top: 15px;
}
.checkbox-item {
width: 100px;
height: 40px;
background-color: #eaf0f4;
margin-bottom: 10px;
display: flex;
justify-content: center;
align-items: center;
}
.container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.input-box {
margin-top: 20px;
}
.checkbox-group {
display: flex;
flex-direction: column;
margin-top: 15px;
}
.checkbox-item {
width: 100px;
height: 40px;
background-color: #eaf0f4;
margin-bottom: 10px;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #ccc;
}
.checkbox-item.active {
background-color: #4285f4;
color: white;
border-color: #4285f4;
}
4、效果演示
演示效果较长,请耐心观看等待.....