java实现年会微信签到,签到后在大屏中展示,导出签到信息
java实现微信签到,签到后在活动大屏中实时展示签到人信息,也可以导出签到人信息用于抽奖。
一、微信公众号申请及配置
1.微信公众号申请,请参考https://jingyan.baidu.com/article/f25ef254a6b2bc482c1b82bb.html
2.微信公众号配置,请参考https://blog.****.net/qq_36313726/article/details/81027366
二、微信签到组成部分
年会微信签到三部曲:
1. 关注“聚合缘新材料公众号”(若已关注过,忽略此步骤)。
2. 在聚合缘公众号中回复“签到”,公众号会自动回复签到地址(效果如下图)。
3. 点击“{签到地址}”,打开签到界面(如下图),输入大屏显示的姓名后,点“签到”,就成功完成签到。
大屏签到信息显示:
1. 用浏览器访问http://wx.jhyxcl.com/wsignin/signIn,效果如下:
年会签到人员信息管理:
1. 浏览器中访问http://wx.jhyxcl.com/siteindex/index后,显示所有签到人员信息,用于导出签到图片和签到数据
三、微信签到核心代码
1. 在聚合缘公众号中回复“签到”,公众号会自动回复签到地址的代码如下:
/**
* 处理文本消息
* @param requestMap
* @return
*/
public String processTextMessage(Map<String, String> requestMap,HttpServletRequest request){
String openid = requestMap.get(Constants.FROM_USER_NAME);
try {
JSONObject userInfo = GetUserInfo.Openid_userinfo(openid);
wXUserSignInService.save(openid, userInfo.getString("nickname"),
userInfo.getString("headimgurl"),
userInfo.getString("province"),
userInfo.getString("city"),
userInfo.getString("sex"));
String curpath = request.getSession().getServletContext()
.getRealPath("static/miniapp/wxheadpic");
wXUserSignInService.saveHeadPic(userInfo.getString("headimgurl"), openid,curpath);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String returnMsg = "";
// 回复文本消息
TextMessage textMessage = new TextMessage();
textMessage.setToUserName(requestMap.get(Constants.FROM_USER_NAME));
textMessage.setFromUserName(requestMap.get(Constants.TO_USER_NAME));
textMessage.setCreateTime(new Date().getTime());
textMessage.setMsgType(Constants.REQ_MESSAGE_TYPE_TEXT);
if("签到".equals(requestMap.get("Content"))){
textMessage.setContent("签到地址为:http://wx.jhyxcl.com/wsignin/wxSignIn?openId="+openid);
}else{
textMessage.setContent("如果有什么问题,请致电聚合缘全国热线0371-55636500");
}
returnMsg = WeiXinUtil.textMessageToXml(textMessage);
return returnMsg;
}
2. 点击“{签到地址}”,打开签到界面(如下图),输入大屏显示的姓名后,点“签到”,就成功完成签到的代码如下:
前端代码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE HTML>
<!DOCTYPE html PUBLIC "" ""><HTML><HEAD><META content="IE=11.0000"
http-equiv="X-UA-Compatible">
<TITLE>年会签到</TITLE>
<base href="<%=basePath%>">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta content="no" name="apple-touch-fullscreen">
<meta name="MobileOptimized" content="320"/>
<meta name="format-detection" content="telephone=no">
<meta name=apple-mobile-web-app-capable content=yes>
<meta name=apple-mobile-web-app-status-bar-style content=black>
<meta http-equiv="pragma" content="nocache">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8">
<style>
*{margin: 0;padding: 0;}
img{max-width: 100%;height:auto;border:none;}
a{text-decoration: none;color: black;}
body{font-family:"Microsoft YaHei",Arial,Helvetica,sans-serif;-webkit-text-size-adjust:none;}
input[type='number'],input[type='reset'],input[type='submit'],input[type='button'],input[type='tel'],button,textarea{-webkit-appearance:none;border-radius: 0;border:1px solid #ddd;} /*去掉苹果的默认UI来渲染按钮*/
.clear{clear: both; display: block; height: 0; overflow: hidden; visibility: hidden; width: 0;}
ol,ul {list-style: none;}
h1,h2,h3,h4,h5,h6 {font-weight: normal;}
body{background-color: #f8f8f8;}
.tou{width: 100%;}
.tou img{display:block;width: 22%;margin: 70px auto 30px; border: 1px solid #fff;border-radius: 50%;}
.logintext{font-size: 0;margin: 0 auto;}
.logintext input{display: inline-block;margin-top: 10px;height: 27px; width: 60%;border:none;}
.usernameDiv{height: 45px;border: 1px solid #ddd;border-bottom: none;border-radius: 3px 3px 0 0;text-indent: 30%;font-size: 18px;background-color: #fff;}
.passwordDiv{height: 45px;border: 1px solid #ddd;border-radius: 0 0 3px 3px;text-indent: 30%;font-size: 19px;background-color: #fff;}
.btulog{display:block;width: 76%;margin:30px auto 0;color: #fff;padding: 15px 0;border-radius: 3px;border:none;font-size: 21px;font-weight: 600;}
p{color: #c9cacb;font-size: 14px;text-align: center;margin-top: 10px;}
a{color: #c9cacb;}
input:-webkit-autofill {-webkit-box-shadow: 0 0 0px 1000px white inset;}
</style><LINK href="static/miniapp/static/amazeui.min.css" rel="stylesheet" type="text/css">
<LINK href="static/miniapp/static/css_orange.css" rel="stylesheet" type="text/css">
<LINK href="static/miniapp/static/global_login_order.css" rel="stylesheet" type="text/css">
<LINK href="static/miniapp/static/global_login.css" rel="stylesheet" type="text/css">
<LINK href="static/miniapp/static/newShop.css" rel="stylesheet" type="text/css">
<SCRIPT src="static/miniapp/static/jquery.min.js" type="text/javascript"></SCRIPT>
<SCRIPT src="static/miniapp/static/amazeui.js" type="text/javascript"></SCRIPT>
<SCRIPT src="static/miniapp/static/global.js" type="text/javascript"></SCRIPT>
<SCRIPT src="static/miniapp/static/loading.js" type="text/javascript"></SCRIPT>
<SCRIPT src="static/miniapp/static/jquery.ellipsis.js"></SCRIPT>
<SCRIPT src="static/miniapp/static/jquery.ellipsis.unobtrusive.js"></SCRIPT>
<SCRIPT src="static/miniapp/static/common.js" type="text/javascript"></SCRIPT>
<SCRIPT src="static/miniapp/static/visitor_cart.js" type="text/javascript"></SCRIPT>
<SCRIPT type="text/javascript">
var sms_check = 0;
</SCRIPT>
<SCRIPT src="static/miniapp/static/bind_phone.js"></SCRIPT>
<META name="GENERATOR" content="MSHTML 11.00.10570.1001"></HEAD>
<BODY><!--<div class="tou">
<img src="./images/login.png">
</div>-->
<DIV class="topicBox">
<INPUT id="openId" name="openId" type="hidden" value="${om.openId }">
</DIV>
<FORM name="checkuser_login" id="checkuser_login">
<DIV class="phoneEdit">
<DIV class="area"><SPAN>真实姓名<font style="color: red;">*</font></SPAN></DIV>
<DIV class="phoneTxt">
<INPUT name="username" class="username" id="username" value="${om.userName }" type="text" style="Border:1px solid red">
</DIV>
</DIV><DIV class="phoneEdit">
<DIV class="area"><SPAN>手机号</SPAN></DIV>
<DIV class="phoneTxt">
<INPUT name="username" class="userMobile" id="userMobile" value="${om.userMobile }" type="text" style="Border:1px solid red">
</DIV>
</DIV><BUTTON class="btn" οnclick="signin();" type="button"><SPAN>签到</SPAN></BUTTON>
</FORM><SCRIPT type="text/javascript">
function signin(){
var openId = $("#openId").val();
var userName = $("#username").val();
var userMobile=$("#userMobile").val();
if(userName==null||userName=="" ){
showAlertMsg ("提示:","姓名不能为空!请重新输入!","知道了");
return false;
}
$.ajax({
type:"POST",
url:"wsignin/saveSignIn.do",
dataType:"json",
data:{openId:openId,userName:userName,userMobile:userMobile},
success:function(result){
if(result.result){
showAlertMsg ("提示:","签到成功,请入座!","知道了");
}else{
showAlertMsg ("提示:","已签到,不能重复签到。","知道了");
}
}
});}
</SCRIPT>
</BODY></HTML>
后端代码:
@RequestMapping(value = "/wxSignIn", method = { RequestMethod.GET,
RequestMethod.POST })
public ModelAndView wxSignIn(HttpServletRequest request, Page page) {
ModelAndView mv = this.getModelAndView();
String openId=request.getParameter("openId");
try {
mv.addObject("om", wXUserSignInService.queryByOpenId(openId));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mv.setViewName("minimanage/signin/signin");
return mv;
}
@RequestMapping(value = "/saveSignIn", method = {RequestMethod.POST })
@ResponseBody
public Object saveSignIn(HttpServletRequest request) {
String openId=request.getParameter("openId");
String userName=request.getParameter("userName");
String userMobile=request.getParameter("userMobile");
if(userName!=null){
userName=userName.trim();
}
if(userMobile!=null){
userMobile=userMobile.trim();
}
try {
String curpath = request.getSession().getServletContext()
.getRealPath(headpicpath);
return returnObject(wXUserSignInService.signIn(curpath,openId, userName,userMobile),"");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return returnObject(false,"");
}
3.大屏签到信息显示的代码
前端代码:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html>
<html lang="en">
<head>
<base href="<%=basePath%>">
<title>年会签到</title>
<meta name="description" content="overview & stats" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="static/css/bootstrap.min.css" rel="stylesheet" />
<link href="static/css/bootstrap-responsive.min.css" rel="stylesheet" />
<link rel="stylesheet" href="static/css/font-awesome.min.css" />
<!-- 引入 -->
<script type="text/javascript">window.jQuery || document.write("<script src='static/js/jquery-1.9.1.min.js'>\x3C/script>");</script>
<script src="static/js/bootstrap.min.js"></script>
<script src="static/js/ace-elements.min.js"></script>
<script src="static/js/ace.min.js"></script>
<script type="text/javascript" src="static/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="static/js/jquery.dataTables.bootstrap.js"></script>
<script type="text/javascript" src="static/js/bootstrap-datepicker.min.js"></script><!-- 日期框 -->
<script type="text/javascript" src="static/js/bootbox.min.js"></script><!-- 确认窗口 -->
<script type="text/javascript" src="static/js/jquery.tips.js"></script><!--提示框-->
</head>
<script type="text/javascript">
function search(){
document.getElementById("form").submit();
}
</script>
<style>
.td{
text-align: center;
}
.jhybg{
background:url(http://http://wx.jhyxcl.com/static/miniapp/static/yearsignin.jpg);
filter:"progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='scale')";
-moz-background-size:100% 100%;
background-size:100% 100%;
}
</style>
<body style="width:1300px;height:700px;background-image: url(http://wx.jhyxcl.com/static/miniapp/static/yearsignin3.jpg);background-repeat:no-repeat;">
<div style="width: 200px;height:770px;text-align: left;background-color: #f9f9f9;float:left;overflow:scroll; ">
<table id="table_report" class="table table-bordered" style="width: 200px;height:700px;" >
<tbody id="leftdata" style="width: 200px;height:700px;" >
<c:forEach items="${omList}" var="om" varStatus="index">
<tr height="23px">
<td style="text-align: left;vertical-align:top;height:23px;">
${om.signInNum}${om.userName}
<a href="${om.headImgUrl}" target="_blank">
<img src="${om.headImgUrl}" width="20px" height="20px">
</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
<div class="container-fluid" id="main-container">
<div id="page-content" class="clearfix">
<form action="<%=basePath%>wsignin/list.do" method="post" id="form">
<div class="row-fluid">
<div class="row-fluid">
<br/>
<br/>
<table id="table_report" class="table table-bordered table-hover" style="width: 500px;text-align: center;background-color: #f9f9f9;" align="center">
<thead>
<tr style="background-color: #DCE2F3;font-size: 16px;">
<th style="text-align: center;width:200px;">序号</th>
<th style="text-align: center;width:200px;">头像</th>
<th style="text-align: center;width:800px;">姓名</th>
</tr>
</thead>
<tbody id="data">
<c:forEach items="${omList2}" var="om" varStatus="index">
<tr >
<td style="text-align: center;vertical-align:middle;">
<font size="20px" color="red">${om.signInNum}</font>
</td>
<td style="text-align: center;vertical-align:middle;">
<a href="${om.headImgUrl}" target="_blank">
<img src="${om.headImgUrl}" width="100px" height="100px">
</a>
</td>
<td style="text-align: center;vertical-align:middle; ">
<font size="18px">${om.userName}</font>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
</form>
</div>
</div>
</body>
<script type="text/javascript">
document.onreadystatechange = subSomething;//当页面加载状态改变的时候执行这个方法.
function subSomething()
{
//getSignIn();
}
setInterval(getSignIn,3000);
// getSignIn();
var maxline=8;
function getSignIn(){
$.ajax({
type: "POST",
url: '<%=basePath%>wsignin/getSignIn',
data: {tm:new Date().getTime()},
dataType:'json',
cache: false,
success: function(data){
if(data.result){
var dataResult=data.data;
//firstElementChild
for(var i=0;i<dataResult.length;i++){
var oldtr=$("#data").find("tr");
if(oldtr.length>=maxline){
$("#data tr:first").remove();
}
var result=dataResult[i];
var userName=result.userName;
if(userName.length>=5){
userName=userName.substr(0,5);
}
var html='<tr >';
html=html+'<td style="text-align: center;vertical-align:middle;"><font size="20px" color="red">'+result.signInNum+'</font></td>';
html=html+'<td style="text-align: center;vertical-align:middle;">';
html=html+' <a href="'+result.headImgUrl+'" target="_blank">';
html=html+'<img src="'+result.headImgUrl+'" width="100px" height="100px">';
html=html+'</a>';
html=html+'</td>';
html=html+'<td style="text-align: center;vertical-align:middle;"><font size="18px">'+userName+'</font></td>';
html=html+'</tr>';
$('#data').append(html);
var leftonedata='<tr >';
leftonedata=leftonedata+'<td style="text-align: left;vertical-align:top;">';
leftonedata=leftonedata+result.signInNum+result.userName;
leftonedata=leftonedata+' <a href="'+result.headImgUrl+'" target="_blank">';
leftonedata=leftonedata+' <img src="'+result.headImgUrl+'" width="20px" height="20px">';
leftonedata=leftonedata+' </a>';
leftonedata=leftonedata+'</td>';
leftonedata=leftonedata+'</tr>';
$('#leftdata').append(leftonedata);
}
}
}
});
}
</script>
</html>
后端代码:
待续……
4.年会签到人员信息管理的代码
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html>
<html lang="en">
<head>
<base href="<%=basePath%>">
<title>签到用户列表</title>
<meta name="description" content="overview & stats" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="static/css/bootstrap.min.css" rel="stylesheet" />
<link href="static/css/bootstrap-responsive.min.css" rel="stylesheet" />
<link rel="stylesheet" href="static/css/font-awesome.min.css" />
<!-- 引入 -->
<script type="text/javascript">window.jQuery || document.write("<script src='static/js/jquery-1.9.1.min.js'>\x3C/script>");</script>
<script src="static/js/bootstrap.min.js"></script>
<script src="static/js/ace-elements.min.js"></script>
<script src="static/js/ace.min.js"></script>
<script type="text/javascript" src="static/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="static/js/jquery.dataTables.bootstrap.js"></script>
<script type="text/javascript" src="static/js/bootstrap-datepicker.min.js"></script><!-- 日期框 -->
<script type="text/javascript" src="static/js/bootbox.min.js"></script><!-- 确认窗口 -->
<script type="text/javascript" src="static/js/jquery.tips.js"></script><!--提示框-->
</head>
<script type="text/javascript">
function search(){
document.getElementById("form").submit();
}
function clearuser(){
if(confirm("确定清空所有签到时间和签到排名吗?清空后,签到排名重新计数,但不会删除用户信息")){
$.ajax({
type:"POST",
url:"wsignin/clear.do",
dataType:"json",
data:{},
success:function(result){
alert("成功清空签到信息!");
window.location.href="<%=basePath%>wsignin/list.do";
}
});
}}
function doExport() {
$("#form").attr("action","<%=basePath%>wsignin/exportwxuser.do");
$("#form").submit();
$("#form").attr("action", "<%=basePath%>wsignin/list.do");
}
function exportpic() {
if(confirm("确定导出所有微信签到头像吗?")){
$.ajax({
type:"POST",
url:"wsignin/exportpic.do",
dataType:"json",
data:{},
success:function(result){
parent.location.href="<%=basePath%>static/miniapp/wxheadpic.zip";
}
});
}
}
</script>
<body>
<div class="container-fluid" id="main-container">
<div id="page-content" class="clearfix">
<form action="<%=basePath%>wsignin/list.do" method="post" id="form">
<div class="row-fluid">
<div class="row-fluid">
<div>
<table align="center" style="width: 100%;">
<br>
<tr align="center">
<td align="left">
昵称:<input type="text" name="nickName" id="nickName" value="${pd.nickName}" placeholder="请输入微信昵称" style="width:120px;"/>
姓名:<input type="text" name="userName" id="userName" value="${pd.userName}" placeholder="请输入微信姓名" style="width:120px;"/>
签到:<select name="signStatus" id="signStatus" style="width:80px;">
<option value="" <c:if test="${pd.signStatus == ''}" >selected="selected"</c:if>>全部</option>
<option value="1" <c:if test="${pd.signStatus =='1'}" >selected="selected"</c:if>>未签到</option>
<option value="2" <c:if test="${pd.signStatus =='2'}" >selected="selected"</c:if>>已签到</option>
</select>
<input type="button" value="查询" οnclick="javacript:search();" style="width: 80px;height: 30px;border-top-width: -10px;" class='btn btn-lg btn-danger' />
</td>
<td align="right">
<input type="button" value="清空签到" οnclick="javacript:clearuser();" style="width: 80px;height: 30px;border-top-width: -10px;" class='btn btn-lg btn-danger' />
<input type="button" value="导出签到人员信息" οnclick="javacript:doExport();" style="width: 140px;height: 30px;border-top-width: -10px;" class='btn btn-lg btn-danger' />
<input type="button" value="导出图片" οnclick="javacript:exportpic();" style="width: 80px;height: 30px;border-top-width: -10px;" class='btn btn-lg btn-danger' />
</td>
</tr>
</table>
</div>
<table id="table_report" class="table table-striped table-bordered table-hover">
<thead>
<tr style="background-color: #DCE2F3;">
<th>签到时间</th>
<th>签到昵称</th>
<th>签到姓名</th>
<th>签到手机</th>
<th>签到排名</th>
<th>是否显示</th>
<th>创建时间</th>
<th>微信性别</th>
<th>头像</th>
</tr>
</thead>
<tbody>
<c:set var="page" value="${page}" />
<c:forEach items="${omList}" var="om" varStatus="index">
<tr>
<td>${om.signInTime}</td>
<td>${om.nickName}</td>
<td>${om.userName}</td>
<td>${om.userMobile}</td>
<td>${om.signInNum}</td>
<td>
<c:choose>
<c:when test="${om.signInNumShow=='0'}">未显示</c:when>
<c:when test="${om.signInNumShow=='1'}">已显示</c:when>
<c:otherwise>未签到</c:otherwise>
</c:choose>
</td>
<td>${om.createTime}</td>
<td>
<c:choose>
<c:when test="${om.sex=='1'}">男</c:when>
<c:when test="${om.sex=='2'}">女</c:when>
<c:otherwise>未知</c:otherwise>
</c:choose>
</td>
<td>
<a href="${om.headImgUrl}" target="_blank">
<img src="${om.headImgUrl}" width="50px" height="50px">
</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
</form>
<div class="page-header position-relative">
<table style="width:100%;">
<tr>
<td style="vertical-align:top;">
<div class="pagination" style="float: right;padding-top: 0px;margin-top: 0px;">
${page.pageStr}
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
</body>
</html>
先做个简单备忘记录,后期有时间了,把整个源码附在这篇博客的后面。下载源码
源码中包含完整的MyEclipse项目和源码使用手册,使用手册结构如下: