本文主要分以下几个模块进行总结分析
项目要求:运用百度AI(人脸识别)通过本地与外网之间的信息交互(MQService),从而通过刷脸实现登陆、签字、会议签到等;
1.准备工作:
内网:单击事件按钮——签字、登陆
qm.js(用于封装调用签名弹出页面的方法)
sdkqz.jsp(用于签名模式的选取)
getitems.jsp(用于jQuery的ajax调用)
logininputbg.gif(用于人脸识别显示的动图--页面效果)
步骤:1.用户单击按钮(以签字为例) onclick="signature('<%=map.get("COL_ID")%>','<%=user.getUserId() %>','QM','')"
2.调用signature()
<script src="<%= path%>/js/qm.js"></script>
//签名
function signature(id, userid,lx,qzrq){
var path = '<%=path%>';
qm(path,id, userid,lx,qzrq);
}
3.进入qm.js中调用function通过ymPrompt打开sdkqz.jsp窗口
qm.js中内容(略)
sdkqz.jsp页面内容如下:

1 <%@page import="java.text.SimpleDateFormat"%> 2 <%@page import="java.net.InetAddress"%> 3 <%@page import="org.daisy.daisyframework.control.ApplicationContext"%> 4 <%@page import="org.daisy.daisyframework.token.AccessTokenManager"%> 5 <%@page import="com.cwai.logic.bean.User"%> 6 <%@page import="com.cwai.logic.dao.UserDAO"%> 7 <%@page import="com.cwai.db.DBA"%> 8 <%@page import="org.daisy.daisyframework.commons.persistent.db.DataManipulation"%> 9 <%@page import="com.cwai.ado.XDataConvert"%> 10 <%@page import="com.cwai.xtag.xtag"%> 11 <%@page import="com.cwai.startup.AppConfigDb"%> 12 <%@page import="com.cwai.cfg.Configs"%> 13 <%@page import="com.cwai.web.App"%> 14 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 15 <% 16 String path = request.getContextPath(); 17 if(null == session||session.getAttribute("LoginUser") == null){out.println("<script language='javascript'> function reLongin(){top.window.PAGE_FLAG = false;top.location = '"+path+"/fail.jsp?ID = 001'"+"}</script> ");out.println("<script language='javascript'> reLongin();</script> "); return; } 18 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 19 DataManipulation dataManipulation = (DataManipulation) ApplicationContext.getContext().getBean("dataManipulation"); 20 String windowTitle = Configs.getWinTitle(); 21 Object obj = session.getAttribute("rand_yzm"); 22 23 String userId = xtag.getParameter(request, "userId"); 24 String id = xtag.getParameter(request, "id").trim(); 25 String lx = xtag.getParameter(request, "lx"); 26 String qzrq = xtag.getParameter(request, "qzrq").trim(); 27 String hqshow = xtag.getParameter(request, "qzrq"); 28 29 AppConfigDb appConfig = AppConfigDb.getInstance(); 30 String username = xtag.getParameter(request, "username_v"); 31 username = username.trim(); 32 String password = xtag.getParameter(request, "password_v"); 33 //String mycode = xtag.getParameter(request, "code_v"); 34 String logic = xtag.getParameter(request, "logic"); 35 String login_result_js = ""; 36 String code = ""; 37 if(obj != null){ 38 code = (String) obj; 39 } 40 boolean hasDbsx = false; 41 String dlip = App.GetIP(request); 42 43 String qzzh = "";//签名账号 44 Map map_zh = dataManipulation.singleData("SELECT USERID,USERNAME,TRUENAME FROM BM_USER WHERE USERID = '"+userId+"' AND YXBZ = '1'", DBA.getConn(), new String[]{}, true); 45 qzzh = XDataConvert.TryToString(map_zh.get("USERNAME")); 46 String qzms = "";//签名模式 47 Map map_ms = dataManipulation.singleData("SELECT USERID,QZMS FROM BM_USER_INFO WHERE USERID = '"+userId+"'", DBA.getConn(), new String[]{}, true); 48 qzms = XDataConvert.TryToString(map_ms.get("QZMS")); 49 //System.out.println("qzms_____________"+qzms); 50 //获取用户电脑IP 51 InetAddress address = InetAddress.getLocalHost(); 52 String ip = address.getHostAddress().toString(); 53 54 //1 混合验证(默认密码) 2混合验证(默认人脸识别) 3仅密码验证 4仅人脸识别验证 55 %> 56 57 58 <!doctype html> 59 <html lang="us"> 60 <head> 61 <meta http-equiv="content-type" content="text/html; charset=UTF-8"> 62 <meta http-equiv="X-UA-Compatible" content="IE=Edge"> 63 <!-- 强制360使用极速模式 --> 64 <meta name="renderer" content="webkit"> 65 <base href="<%=basePath%>"> 66 <title><%= windowTitle%></title> 67 <meta http-equiv="pragma" content="no-cache"> 68 <meta http-equiv="cache-control" content="no-cache"> 69 <meta http-equiv="expires" content="0"> 70 <link href="<%= path%>/css/main.css" rel="stylesheet" type="text/css" /> 71 <script src="<%= path%>/js/jquery-1.11.3.js"></script> 72 <script src="<%= path%>/js/layer/layer.js"></script> 73 <script type="text/javascript"> 74 function enter(){ 75 var url = '<%=basePath%>home.jsp'; 76 var open_pattern = 2; 77 var w = screen.width + 8; 78 var h = screen.height + 7; 79 var l = 0; 80 var t = 0; 81 var window_style = ""; 82 if(open_pattern == 1) { 83 t = -30; 84 l = -4; 85 window_style = "toolbar=no,location=no,directories=no,status=yes,menubar=no,scrollbars=no,resizable=yes"; 86 var newwin = window.open(url, "_blank", window_style + ",width=" + w + ",height=" + h + ",top=" + t + ",left=" + l); 87 newwin.moveTo(l, t); 88 newwin.resizeTo(w, h); 89 window.opener = null; 90 window.close(); 91 } else if(open_pattern == 2) { 92 window.location.href = url; 93 } 94 } 95 window.onload = function page_init() { 96 if('<%= qzms%>' == '' || '<%= qzms%>' == '1' || '<%= qzms%>' == '3'){ 97 dlyz('1'); 98 } else if ('<%= qzms%>' == '2' || '<%= qzms%>' == '4') { 99 dlyz('2'); 100 } 101 showmsg(); 102 if(!$("#username").is(":hidden")){ 103 document.getElementById('username').focus(); 104 } 105 } 106 function showmsg(){ 107 <%=login_result_js%> 108 } 109 function refresh(obj) { 110 obj.src = "./code2.jsp?" + Math.random(); 111 } 112 113 </script> 114 <style type="text/css"> 115 body { 116 background-position: center; 117 background-repeat: no-repeat; 118 background-attachment: fixed; 119 font-family: Microsoft YaHei; 120 } 121 .cont{ 122 width:400px; 123 height:350px; 124 border:0px; 125 } 126 127 .contright { 128 align:center; 129 position: absolute; 130 width: 308px; 131 height: 300px; 132 right: 50px; 133 top: 10px; 134 border: 6px #D2E5F6 solid; 135 //background-color: #fff; 136 text-align: center; 137 background: url("<%= path%>/images/login/logininputbg.png") no-repeat; 138 } 139 140 .mimas { 141 display: inline-block; 142 width: 13px; 143 } 144 145 .yhdl { 146 margin-top: 25px; 147 font-size: 17px; 148 color: #666; 149 } 150 151 .checkcolor { 152 color: #191970; 153 font-weight: bold; 154 } 155 156 .logininput { 157 height: 25px; 158 font-size: 12px; 159 line-height: 25px; 160 border-left: 1px #C5DBEC solid; 161 border-top: 1px #C5DBEC solid; 162 border-bottom: 1px #C5DBEC solid; 163 border-right: 1px #C5DBEC solid; 164 padding-left: 5px; 165 outline: none; 166 } 167 168 .tdleft { 169 font-size: 12px; 170 } 171 .zhdl { 172 width: calc(50% - 1px); 173 border-right: 1px solid #f4f4f4; 174 display: inline-block; 175 } 176 .rlsb { 177 display: inline-block; 178 width: calc(50% - 10px); 179 } 180 .login-btn .btn-img { 181 border: 1px solid #ff9f00; 182 display: block; 183 width: 244px; 184 background: #ff9f00; 185 height: 31px; 186 line-height: 31px; 187 color: #fff; 188 font-size: 20px; 189 font-family: 'Microsoft YaHei'; 190 } 191 192 .contright table td { 193 font-weight: bold; 194 color: #191970; 195 height:65px; 196 } 197 198 .contright table tr { 199 height: 37px; 200 } 201 202 .jy_a { 203 pointer-events : none; 204 } 205 206 </style> 207 208 </head> 209 <body style="background-color: #e9f3fd;margin: 0px;padding: 0px;"> 210 <form action="" method="post" name="logonForm" id="logonForm"> 211 <input type="hidden" name="username_v" id="username_v" value=""> 212 <input type="hidden" name="password_v" id="password_v" value=""> 213 <input type="hidden" name="code_v" id="code_v" value=""> 214 <input type="hidden" name="logic" id="logic" value=""> 215 216 <div id="div1" class="cont"> 217 <div class="contright" style=""> 218 <div class="yhdl" > 219 <%if("1".equals(qzms) || "2".equals(qzms)){ %> 220 <div class="zhdl" > 221 <span id="zhdl_span" style="cursor: pointer;" onclick="dlyz('1')">密 码 签 字</span> 222 </div> 223 <div class="rlsb" > 224 <span id="rlsb_span" style="cursor: pointer;" onclick="dlyz('2')">面 部 识 别</span> 225 </div> 226 <%}else if("3".equals(qzms)){ %> 227 <div class="zhdl" > 228 <span id="zhdl_span" style="cursor: pointer;" onclick="dlyz('1')">密 码 签 字</span> 229 </div> 230 <%}else if("4".equals(qzms)){ %> 231 <div class="rlsb" > 232 <span id="rlsb_span" style="cursor: pointer;" onclick="dlyz('2')">面 部 识 别</span> 233 </div> 234 <%} %> 235 </div> 236 237 <div style="min-height: 210px;" align="center"> 238 <div id="zhdl_div"> 239 <br> 240 <br> 241 <table style=""> 242 <tr> 243 <td class="tdleft">签 字 账 号:</td> 244 <td> 245 <input id="username" name="username" maxlength="30" placeholder="用户名" type="text" style="width: 188px;" disabled="disabled" class="logininput" value="<%= qzzh%>"> 246 </td> 247 </tr> 248 <tr> 249 <td class="tdleft">签 字 密 码:</td> 250 <td> 251 <input id="password" name="password" maxlength="30" placeholder="密码" type="password" style="width: 188px;" class="logininput" onkeydown="if(event.keyCode==13) login()"> 252 </td> 253 </tr> 254 </table> 255 </div> 256 <div id="rlsb_div" style="height: 210px;"> 257 <br> 258 <img src="<%= path%>/images/login/logininputbg.gif" width="155px" height="155px" /> 259 <br> 260 <a style="color: #666;">签 字 账 号: <span style="font-weight: bold;font-size: 12px;color:#191970;" id="qzzh"><%= qzzh%></span></a> 261 <%-- 262 <a id="qhzh_a" style="float: right; margin-right: 31px;color:#191970;cursor: pointer;font-weight: bold;" onclick="qhzh()">切换账号</a> 263 --%> 264 </div> 265 </div> 266 <div class="login-btn" align="center"> 267 <a href="javascript:sendreq();" id="dl_a" class="btn-img"> 268 确 认<span id="fsqq"></span> 269 </a> 270 </div> 271 </div> 272 </div> 273 </form> 274 275 <script type="text/javascript"> 276 $(function(){ 277 divcenter(); 278 }) 279 280 $(window).resize(function () { //当浏览器大小变化时 281 divcenter(); 282 }); 283 284 function divcenter(){ 285 var left = $(window).width()/2 - 474; 286 var top = $(window).height()/2 - 272; 287 $("#div1").css('margin-top',top+'px'); 288 $("#div1").css('margin-left',left+'px'); 289 } 290 291 function dlyz(lx) { 292 if(lx == '1') { 293 $("#zhdl_div").show(); 294 $("#rlsb_div").hide(); 295 $("#zhdl_span").addClass("checkcolor"); 296 $("#rlsb_span").removeClass("checkcolor"); 297 } else { 298 $("#rlsb_div").show(); 299 $("#zhdl_div").hide(); 300 $("#rlsb_span").addClass("checkcolor"); 301 $("#zhdl_span").removeClass("checkcolor"); 302 } 303 } 304 305 var v_str = '用户名: <input type="text" id="lrxzh" name="lrxzh" placeholder="用户账号"/>'; 306 function zhlr(){ 307 layer.open({ 308 title: '账号录入', 309 content: v_str, 310 btn: '确定', 311 yes: function(index){ 312 if($("#lrxzh").val() != ''){ 313 $("#dqdlzh").html($("#lrxzh").val()); 314 layer.close(index); 315 } 316 } 317 }); 318 } 319 320 function sendreq() { 321 if($("#zhdl_div").is(":hidden")) {// 人脸识别校验 322 sendMsg(); 323 } else {//密码签字校验 324 dzqm(); 325 } 326 } 327 328 var id = '<%=id%>'; 329 var userid = '<%=userId%>'; 330 //用于签名时间(FORM_20170117050524000077.jsp) 331 var qzrq = '<%=qzrq%>'; 332 var ny = '<%= new SimpleDateFormat("yyyy-MM-dd").format(new Date())%>'; 333 var hqshow = '<%=hqshow%>'; 334 //电子签名 335 function dzqm(){ 336 var pass = document.getElementById("password").value; 337 $.ajax({ 338 type: "POST", 339 url: "<%=path%>/ajax/formdata.jsp", 340 data: {type: 'SIGNATURE',userid: userid,pass: pass}, 341 dataType: "json", 342 success:function(data){ 343 console.log(data); 344 if(data.code == 2){ 345 if("QM" == "<%=lx%>"){ 346 var src = "<%=path%>/work/common/view_image2.jsp?tpid=" + data.qzxxid; 347 window.parent.$("#"+id+"_img").attr("src",src); 348 window.parent.$("#"+id).val(data.qzxxid); 349 window.parent.$("#"+id+"_btn").hide(); 350 window.parent.$("#"+id+"_img").show(); 351 if("" != qzrq && null != qzrq ){ 352 window.parent.$("#"+qzrq).val(ny); 353 } 354 }else if("HQ" == "<%=lx%>"){ 355 window.parent.app.huiqian.push({ 356 userid: userid, 357 imgid: data.qzxxid 358 }); 359 if("0" == hqshow){ 360 window.parent.app.hqshow = false; 361 }else { 362 window.parent.$("#"+id+"_btn").hide(); 363 } 364 } 365 window.parent.ymPrompt.close(); 366 }else{ 367 layer.msg(data.msg, {icon: 2, time: 8000}); 368 } 369 } 370 }); 371 } 372 //人脸识别签名 373 function sendMsg() {//30秒请求时间间隔 374 //1: 获取方式 2:账号信息 3:发送异步请求[a.获取登陆模式 b.等待数据返还] 375 var id = '<%=id%>'; 376 if($("#qzzh").text() == '') {//当前登陆账号为空 377 zhlr(); 378 } else {//有数据, 开始发送请求ajax请求 379 time($("#dl_a")); 380 $.ajax ({ 381 url : '<%=path%>/ajax/getitems.jsp', 382 type: 'POST', 383 dataType : 'text', 384 async: true, 385 data : {"DMZL":"CHKSDK2", "queryValue": "<%= ip%>~<%= userId%>"}, 386 success: function(data) { 387 if(data.trim() == '0'){ 388 layer.msg("人脸识别信息发送失败!",{icon: 2, time: 3000}); 389 } else { 390 layer.msg("人脸识别信息已发送,请于一分钟内登陆钉钉验证!",{time:5000}); 391 var interval = setInterval( 392 function sdkLogin(){ 393 console.log("请求数据来了————————————"); 394 if(null != data && "" != data){ 395 $.ajax({ 396 url : 'ajax/getitems.jsp', 397 type : 'POST', 398 dataType : 'text', 399 data : {"DMZL":"CHKSDK_MSG", "queryValue": data }, 400 success : function(back){ 401 if(back.trim() == '2'){ 402 layer.msg("该签名信息已经过时,请重新发送申请!",{icon: 2, time: 100000}); 403 clearInterval(interval); 404 } else if(back.trim() == '3'){ 405 //layer.msg("您已取消该签名信息!",{icon: 2, time: 3000}); 406 clearInterval(interval); 407 } else if(back.trim() == '4'){ 408 //获取qzxxid 409 $.ajax({ 410 url : 'ajax/getitems.jsp', 411 type : 'POST', 412 dataType : 'text', 413 data : {"DMZL":"GETQZXXID", "queryValue": '<%= userId%>' }, 414 success : function(qzxx){ 415 //进行图片签字,显示图片 416 if("0" == qzxx.trim()){ 417 layer.msg("没有被应用的签字,请先设置签字!",{icon: 2, time: 3000}); 418 //停止时间函数 419 clearInterval(interval); 420 window.parent.ymPrompt.close(); 421 }else{ 422 if("QM" == "<%=lx%>"){ 423 var src = "<%=path%>/work/common/view_image2.jsp?tpid=" + qzxx.trim(); 424 window.parent.$("#"+id+"_img").attr("src",src); 425 window.parent.$("#"+id).val(qzxx.trim()); 426 window.parent.$("#"+id+"_btn").hide(); 427 window.parent.$("#"+id+"_img").show(); 428 if("" != qzrq && null != qzrq ){ 429 window.parent.$("#"+qzrq).val(ny); 430 } 431 }else if("HQ" == "<%=lx%>"){ 432 window.parent.app.huiqian.push({ 433 userid: userid, 434 imgid: qzxx.trim() 435 }); 436 if("0" == hqshow){ 437 window.parent.app.hqshow = false; 438 }else { 439 window.parent.$("#"+id+"_btn").hide(); 440 } 441 } 442 //停止时间函数 443 clearInterval(interval); 444 window.parent.ymPrompt.close(); 445 } 446 447 } 448 }); 449 } else if(back.trim() == '0'){ 450 //layer.msg("人脸识别信息已发送,请于一分钟内登陆叮叮验证!",{time:1000}); 451 } 452 } 453 }); 454 } 455 } 456 , 1000); 457 } 458 459 } 460 }); 461 } 462 } 463 464 var wait = 30; 465 function time(o) { 466 if (wait == 0) { 467 o.removeClass("jy_a"); 468 $("#qhzh_a").removeClass("jy_a"); 469 $("#fsqq").text(''); 470 wait = 30; 471 } else { 472 o.addClass("jy_a"); 473 $("#qhzh_a").addClass("jy_a"); 474 $("#fsqq").text('('+ wait +')'); 475 wait--; 476 setTimeout(function() { 477 time(o); 478 }, 479 1000) 480 } 481 } 482 483 function setWait(time){ 484 if(time != null){ 485 wait = time; 486 } 487 } 488 489 function qhzh() {//切换账号 490 zhlr(); 491 } 492 </script> 493 </body> 494 </html>
4.sdkqz.jsp中通过ajax调用getitems.jsp获取相应的数据
5.getitems.jsp中内容

1 <%@page import="org.daisy.daisyframework.commons.date.DateConvertor"%> 2 <%@page import="org.daisy.daisyframework.util.Xtag"%> 3 <%@page import="com.cwai.xtag.xtag"%> 4 <%@page import="net.sf.json.JSONObject"%> 5 <%@page import="net.sf.json.JSONArray"%> 6 <%@page import="com.cwai.pass.Md5"%> 7 <%@page import="com.cwai.logic.bean.User"%> 8 <%@page import="org.daisy.daisyframework.util.DataConvertor"%> 9 <%@page import="org.daisy.daisyframework.commons.persistent.db.PrimaryKeyDependent"%> 10 <%@page import="com.cwai.db.DBA"%> 11 <%@page import="org.daisy.daisyframework.commons.persistent.db.DataManipulation"%> 12 <%@ page language="java" import="java.util.*,com.cwai.bean.*,com.cwai.xbean.*,com.cwai.ado.*" pageEncoding="UTF-8"%> 13 <% 14 String path = request.getContextPath(); if(null==session||session.getAttribute("LoginUser")==null){out.println("<script language='javascript'> function reLongin(){top.window.PAGE_FLAG = false;top.location='"+path+"/fail.jsp?ID=001'"+"}</script> ");out.println("<script language='javascript'> reLongin();</script> ");return;} 15 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 16 User user = (User) session.getAttribute("LoginUser"); 17 %> 18 <% 19 //代码种类 20 String dmzl = request.getParameter("DMZL") == null ? "" : request.getParameter("DMZL").toUpperCase(); 21 //查询代码 22 String v = request.getParameter("queryValue") == null ? "" : request.getParameter("queryValue"); 23 try{ 24 if("GETQZXXID".equals(dmzl)){//根据userid获取签字信息ID 25 BaseDAO dao = new BaseDAO(); 26 String qzxxid = dao.getValue("SELECT QZXX_ID FROM BM_USER_DZQZ T WHERE USERID = '"+v.trim()+"' AND SFYY = 1 AND DQYX = 1", new Object[]{}); 27 System.out.println("map:"+qzxxid); 28 if("".equals(qzxxid) || null == qzxxid){ 29 out.println("0"); 30 }else{ 31 out.println(qzxxid.trim()); 32 } 33 }else if("CHKSDK_MSG".equals(dmzl)){//定时读取数据库SDK比对结果信息 34 DataManipulation dataManipulation = new DataManipulation(); 35 String dd_sdksql = "SELECT ID, USERID, CONTENT, STATUS, IP, LX FROM DD_SDKMESSAGE WHERE ID = '"+v.trim()+"' "; 36 Map map = dataManipulation.singleData(dd_sdksql, DBA.getConn(),new String[]{}, true); 37 //System.out.println("map:"+map); 38 out.println(XDataConvert.TryToString(map.get("STATUS"))); 39 40 }else if("CHKSDK2".equals(dmzl)){//创建一条即将比对的人脸比对信息 41 DataManipulation dataManipulation = new DataManipulation(); 42 //System.out.println("flag::_____"); 43 //更新表中已经存在大于30秒小于一分钟的数据 44 String dd_sdksql = "UPDATE DD_SDKMESSAGE SET STATUS = '3' , FINISH_TIME = SYSDATE WHERE STATUS = '0' AND USERID = '"+v.split("~")[1]+"'"; 45 //System.out.println("dd_sdksql:"+dd_sdksql); 46 boolean f = dataManipulation.execute(dd_sdksql,DBA.getConn(),new String[]{}, true); 47 String xx_id = PrimaryKeyDependent.getDateRandomKey(); 48 String content = "您收到一条新的签字(人脸识别)提醒,请于一分钟内进行验证!"; 49 String dd_sdk = "INSERT INTO DD_SDKMESSAGE(ID, USERID, CONTENT, STATUS, IP, LX) " 50 + " SELECT '"+ xx_id +"', '"+ v.split("~")[1] +"', '"+ content +"', '0', '" + v.split("~")[0] +"', '0' FROM DUAL WHERE 1 = 1 "; 51 //System.out.println("dd_sdksql:"+dd_sdksql); 52 boolean flag = dataManipulation.execute(dd_sdk, DBA.getConn(),new String[]{}, true); 53 //System.out.println("flag::_____"+flag); 54 if(flag){ 55 out.println(xx_id); 56 }else{ 57 out.println("0"); 58 }
6.定时获取数据库中信息,查看处理情况
外网(手机端钉钉):
分两种模式,模式1:打开钉钉直接进行面部比对;模式2:打开钉钉消息,进入主页面,通过单击按钮,进行签字(电子签名、面部识别)
JAVA代码:
AuthService.java(获取百度AI的token类)
Base64ImageUtils.java(本地或者网络图片资源转为Base64字符串 )
FileUtil.java(文件读取工具类)

1 package com.cwai.service.dd; 2 3 import java.io.BufferedReader; 4 import java.io.InputStreamReader; 5 import java.net.HttpURLConnection; 6 import java.net.URL; 7 import java.util.List; 8 import java.util.Map; 9 10 import org.json.JSONObject; 11 12 import com.cwai.cfg.Configs; 13 14 /** 15 * 获取token类 16 */ 17 public class AuthService { 18 19 /** 20 * 获取权限token 21 * @return 返回示例: 22 * { 23 * "access_token": "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567", 24 * "expires_in": 2592000 25 * } 26 */ 27 public static String getAuth() { 28 29 //String[] pro = FileUtil.getPro().split("~");//已不再使用 30 // 官网获取的 API Key 更新为你注册的 31 String clientId = Configs.BAIDU_AI_API_KEY; //百度云应用的AK 32 // 官网获取的 Secret Key 更新为你注册的 33 String clientSecret = Configs.BAIDU_AI_SECRET_KEY; //百度云应用的SK 34 return getAuth(clientId, clientSecret); 35 } 36 37 /** 38 * 获取API访问token 39 * 该token有一定的有效期,需要自行管理,当失效时需重新获取. 40 * @param ak - 百度云官网获取的 API Key 41 * @param sk - 百度云官网获取的 Securet Key 42 * @return assess_token 示例: 43 * "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567" 44 */ 45 public static String getAuth(String ak, String sk) { 46 // 获取token地址 47 String authHost = "https://aip.baidubce.com/oauth/2.0/token?"; 48 String getAccessTokenUrl = authHost 49 // 1. grant_type为固定参数 50 + "grant_type=client_credentials" 51 // 2. 官网获取的 API Key 52 + "&client_id=" + ak 53 // 3. 官网获取的 Secret Key 54 + "&client_secret=" + sk; 55 try { 56 URL realUrl = new URL(getAccessTokenUrl); 57 // 打开和URL之间的连接 58 HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection(); 59 connection.setRequestMethod("GET"); 60 connection.connect(); 61 // 获取所有响应头字段 62 Map<String, List<String>> map = connection.getHeaderFields(); 63 // 遍历所有的响应头字段 64 for (String key : map.keySet()) { 65 System.err.println(key + "--->" + map.get(key)); 66 } 67 System.err.println("getAccessTokenUrl:" + getAccessTokenUrl); 68 // 定义 BufferedReader输入流来读取URL的响应 69 BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); 70 System.err.println("result1:" + getAccessTokenUrl); 71 String result = ""; 72 String line; 73 while ((line = in.readLine()) != null) { 74 result += line; 75 } 76 /** 77 * 返回结果示例 78 */ 79 System.err.println("result:" + result); 80 JSONObject jsonObject = new JSONObject(result); 81 String access_token = jsonObject.getString("access_token"); 82 return access_token; 83 } catch (Exception e) { 84 System.err.printf("获取token失败!"); 85 e.printStackTrace(System.err); 86 } 87 return null; 88 } 89 90 }


1 package com.cwai.util; 2 3 import java.io.FileInputStream; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 import java.io.InputStream; 7 import java.io.OutputStream; 8 import java.net.HttpURLConnection; 9 import java.net.URL; 10 11 import sun.misc.BASE64Decoder; 12 import sun.misc.BASE64Encoder; 13 14 /** 15 * 16 * 本地或者网络图片资源转为Base64字符串 17 */ 18 public class Base64ImageUtils { 19 /** 20 * @Title: GetImageStrFromUrl 21 * @Description: 将一张网络图片转化成Base64字符串 22 * @param imgURL 网络资源位置 23 * @return Base64字符串 24 */ 25 public static String GetImageStrFromUrl(String imgURL) { 26 byte[] data = null; 27 try { 28 // 创建URL 29 URL url = new URL(imgURL); 30 // 创建链接 31 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 32 conn.setRequestMethod("GET"); 33 conn.setConnectTimeout(5 * 1000); 34 InputStream inStream = conn.getInputStream(); 35 data = new byte[inStream.available()]; 36 inStream.read(data); 37 inStream.close(); 38 } catch (IOException e) { 39 e.printStackTrace(); 40 } 41 // 对字节数组Base64编码 42 BASE64Encoder encoder = new BASE64Encoder(); 43 // 返回Base64编码过的字节数组字符串 44 return encoder.encode(data); 45 } 46 47 /** 48 * @Title: GetImageStrFromPath 49 * @Description: (将一张本地图片转化成Base64字符串) 50 * @param imgPath 51 * @return 52 */ 53 public static String GetImageStrFromPath(String imgPath) { 54 InputStream in = null; 55 byte[] data = null; 56 // 读取图片字节数组 57 try { 58 in = new FileInputStream(imgPath); 59 data = new byte[in.available()]; 60 in.read(data); 61 in.close(); 62 } catch (IOException e) { 63 e.printStackTrace(); 64 } 65 // 对字节数组Base64编码 66 BASE64Encoder encoder = new BASE64Encoder(); 67 // 返回Base64编码过的字节数组字符串 68 return encoder.encode(data); 69 } 70 71 /** 72 * @Title: GenerateImage 73 * @Description: base64字符串转化成图片 74 * @param imgStr 75 * @param imgFilePath 图片文件名,如“E:/tmp.jpg” 76 * @return 77 */ 78 public static boolean saveImage(String imgStr,String imgFilePath) { 79 if (imgStr == null) // 图像数据为空 80 return false; 81 BASE64Decoder decoder = new BASE64Decoder(); 82 try { 83 // Base64解码 84 byte[] b = decoder.decodeBuffer(imgStr); 85 for (int i = 0; i < b.length; ++i) { 86 if (b[i] < 0) {// 调整异常数据 87 b[i] += 256; 88 } 89 } 90 // 生成jpeg图片 91 OutputStream out = new FileOutputStream(imgFilePath); 92 out.write(b); 93 out.flush(); 94 out.close(); 95 return true; 96 } catch (Exception e) { 97 return false; 98 } 99 } 100 }
HttpUtil.java(http 工具类)
PropertiesUtil.java(.properties文件内容获取——本项目未使用直接调用类中的常量)
SDKMatch.java(图片比对——本项目只是针对两张图片进行比较,如果需要则可根据下方逻辑进行实现)
SQLUtils.java(SQL类不做解释)
AutoSendSDKMessage.java(实时获取数据库新建的信息,并处理-给用户发送钉钉消息)

1 package com.cwai.util; 2 3 import java.io.BufferedReader; 4 import java.io.DataOutputStream; 5 import java.io.InputStreamReader; 6 import java.net.HttpURLConnection; 7 import java.net.URL; 8 import java.util.List; 9 import java.util.Map; 10 11 /** 12 * http 工具类 13 */ 14 public class HttpUtil { 15 public static String post(String requestUrl, String accessToken, String params) throws Exception { 16 String generalUrl = requestUrl + "?access_token=" + accessToken; 17 System.out.println("generalUrl:" + generalUrl); 18 URL url = new URL(generalUrl); 19 // 打开和URL之间的连接 20 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 21 connection.setRequestMethod("POST"); 22 // 设置通用的请求属性 23 connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 24 connection.setRequestProperty("Connection", "Keep-Alive"); 25 connection.setUseCaches(false); 26 connection.setDoOutput(true); 27 connection.setDoInput(true); 28 29 // 得到请求的输出流对象 30 DataOutputStream out = new DataOutputStream(connection.getOutputStream()); 31 out.writeBytes(params); 32 out.flush(); 33 out.close(); 34 35 // 建立实际的连接 36 connection.connect(); 37 // 获取所有响应头字段 38 Map<String, List<String>> headers = connection.getHeaderFields(); 39 // 遍历所有的响应头字段 40 for (String key : headers.keySet()) { 41 System.out.println(key + "--->" + headers.get(key)); 42 } 43 // 定义 BufferedReader输入流来读取URL的响应 44 BufferedReader in = null; 45 if (requestUrl.contains("nlp")) 46 in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "GBK")); 47 else 48 in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8")); 49 String result = ""; 50 String getLine; 51 while ((getLine = in.readLine()) != null) { 52 result += getLine; 53 } 54 in.close(); 55 System.out.println("result:" + result); 56 return result; 57 } 58 }

1 package com.cwai.util; 2 3 import java.io.BufferedInputStream; 4 import java.io.FileInputStream; 5 import java.io.FileOutputStream; 6 import java.io.InputStream; 7 import java.util.Iterator; 8 import java.util.Map; 9 import java.util.Properties; 10 11 public class PropertiesUtil { 12 public static Properties prop = new Properties(); 13 /** 14 * 取出值 15 * @param k 16 * @param filepath 17 * @return 18 */ 19 public static String getValue(String k, String filepath){ 20 InputStream in; 21 try { 22 in = new BufferedInputStream(new FileInputStream(filepath)); 23 prop.load(in); ///加载属性列表 24 Iterator<String> it=prop.stringPropertyNames().iterator(); 25 while(it.hasNext()){ 26 String key=it.next(); 27 if (key.equals(k)){ 28 return prop.getProperty(key); 29 } 30 } 31 in.close(); 32 } catch (Exception e) { 33 e.printStackTrace(); 34 } 35 return ""; 36 } 37 /** 38 * 设置键值 39 * @param filepath 40 * @param map 41 */ 42 public static void setValue(String filepath, Map<String, String> map){ 43 ///保存属性到b.properties文件 44 FileOutputStream oFile ; 45 try { 46 System.out.println("s"+filepath); 47 oFile = new FileOutputStream(filepath, false); 48 //true表示追加打开 49 System.out.println(map.get("key")+",,,"+map.get("value")); 50 prop.setProperty(map.get("key"), map.get("value")); 51 //prop.put(map.get("key"), map.get("value")); 52 prop.store(oFile, "The New properties file"); 53 oFile.close(); 54 } catch (Exception e) { 55 // TODO 自动生成的 catch 块 56 e.printStackTrace(); 57 } 58 } 59 }

1 package com.cwai.util; 2 3 import java.util.Arrays; 4 import java.util.HashMap; 5 import java.util.List; 6 import java.util.Map; 7 8 import org.json.JSONObject; 9 10 import com.baidu.aip.face.AipFace; 11 import com.baidu.aip.http.AipRequest; 12 import com.cwai.ado.XDataConvert; 13 import com.cwai.cfg.Configs; 14 import com.cwai.dao.DBManager; 15 16 public class SDKMatch { 17 18 19 /** 20 * 作用:进行人脸识别比对(手机端拍照图片与数据库中图片比较)获取结果 21 * @param url 网上文件地址 22 * @return 返回是否登录结果 23 * @throws Exception 24 */ 25 public static String faceCompare(String url,String userID) throws Exception{ 26 // /zczhgzpt_out/src/config/SDK.properties 27 //String[] pro = FileUtil.getPro().split("~"); 28 //初始化一个FaceClient 29 AipFace face = new AipFace(Configs.BAIDU_AI_API_APP_ID, Configs.BAIDU_AI_API_KEY, Configs.BAIDU_AI_SECRET_KEY); 30 System.out.println("APP_ID_____________________________-"+Configs.BAIDU_AI_API_APP_ID); 31 System.out.println("API_KEY_____________________________-"+Configs.BAIDU_AI_API_KEY); 32 System.out.println("SECRET_KEY_____________________________-"+Configs.BAIDU_AI_SECRET_KEY); 33 //可选:设置网络连接参数 34 face.setConnectionTimeoutInMillis(60000); 35 face.setSocketTimeoutInMillis(60000); 36 //调用API 37 HashMap map = new HashMap(); 38 //所选属性,根据项目要求进行选择 39 map.put("ext_fields", "qualities"); 40 //对第一张图片(线上拍照图片)进行活体检测 41 map.put("image_liveness", "faceliveness,"); 42 map.put("types", "7,13"); 43 //方式1 44 //使用图片地址 45 46 //方式2 47 48 //获取数据库数据 49 List list = SQLUtils.getPhotoList(userID); 50 System.out.println("list__________________________________________:"+list); 51 byte[][] images = new byte[list.size()+1][] ; 52 //获取网上图片内容 53 byte[] image0 = FileUtil.loadByteFromURL(url); 54 images[0] = image0; 55 if(list.size() > 0 && list != null){ 56 for(int i=0;i<list.size();i++){ 57 HashMap map_sj = (HashMap) list.get(i); 58 String userId = XDataConvert.TryToString(map_sj.get("USERID")); 59 String tpid = XDataConvert.TryToString(map_sj.get("TPID")); 60 byte[] image = new DBManager().getBlob("SELECT PHOTO FROM USER_PHOTO P WHERE USERID = '"+userId+"' AND TPID = '"+tpid+"'", new String[]{}); 61 images[i+1] = image; 62 } 63 AipRequest aipRequest = new AipRequest(); 64 aipRequest.setBody(map); 65 JSONObject obj = face.match(images, map); 66 String result = SDKMatch.compareResult(obj); 67 System.out.println("result_______________________________________:"+result); 68 return SDKMatch.resultAnalysis(result); 69 }else{ 70 return "MAP_NO"; 71 } 72 73 } 74 /** 75 * 作用:对图片进行比对得到结果 76 * @param obj 比对后的JSON串 77 * @return 78 * @throws Exception 79 */ 80 public static String compareResult(JSONObject obj ) throws Exception{ 81 String result = ""; 82 83 String re = obj.get("result").toString(); 84 String l = re.substring(1, re.length()-1).replace("},{", "}@{"); 85 if(!"".equals(l.trim()) && l != null ){ 86 Object[] str = l.trim().split("@"); 87 List<Object> list = Arrays.asList(str); 88 int index_j = 0; 89 int index_i = 0; 90 double maxlik = 0.00; 91 for(int i=0; i<list.size();i++){ 92 String ll = list.get(i).toString();//获取当前比较项的数据(String) 93 //Pattern p = Pattern.compile("[\\{\\}\\=\\, ]++");//StringToMap转换方式 94 String p = ll.replace("}", ""); 95 p = p.replace("{", ""); 96 p = p.replace("\"", ""); 97 System.out.println("结果串:___________________________"+p); 98 String[] split = p.split(","); 99 String[] score = split[2].split(":"); 100 String[] in_j = split[0].split(":"); 101 String[] in_i = split[1].split(":"); 102 double lik = Double.parseDouble(XDataConvert.TryToString(score[1])); 103 if(lik >= maxlik && ("0".equals(in_j[1]) || "0".equals(in_i[1]))){ //仅查询与人脸识别图片(第一张图片,即登陆图片)作比较的选项 104 maxlik = lik; 105 index_j = Integer.parseInt(XDataConvert.TryToString(in_j[1])); 106 index_i = Integer.parseInt(XDataConvert.TryToString(in_i[1])); 107 } 108 } 109 result = index_j+","+index_i+","+maxlik; 110 }else{ 111 result = "0,0,0"; 112 } 113 114 115 //获取活体值 116 String ext_info = obj.get("ext_info").toString(); 117 Map map_info = FileUtil.string2Map(ext_info); 118 String faceliveness=(String) map_info.get("faceliveness"); 119 System.out.println("faceliveness的值为:______________________________-"+faceliveness); 120 result = result + "," + faceliveness; 121 122 return result; 123 } 124 125 /** 126 * 作用:用于得分设定(控制阀阀值) 127 * @param result 128 * @return 129 */ 130 public static String resultAnalysis(String result){ 131 String[] r = result.split(","); 132 //System.out.println("r3:------------------------------"+r[3]); 133 if(!"0".equals(r[2]) && !"".equals(r[3])){ 134 double score = Double.parseDouble(r[2]); 135 double liveness = Double.parseDouble(r[3]);//获取第一张图片的活体比对得分数 136 if(score >=80 && score <= 100 ){ 137 if(liveness < 0.393241){//活体判断 138 return "LIVE_NO"; 139 }else{ 140 return "OK"; 141 } 142 } 143 return "NO"; 144 }else{ 145 return "FACE_NO"; 146 } 147 } 148 }

1 package com.cwai.util; 2 3 import java.util.List; 4 import java.util.Map; 5 6 import com.cwai.dao.DBManager; 7 public class SQLUtils { 8 public static List getPhotoList(String userId) throws Exception{ 9 //数据库直连方式 10 // String DriverName="oracle.jdbc.driver.OracleDriver"; 11 // String DBname="jdbc:oracle:thin:@118.190.95.111:1521:cwai"; //jdbc:oracle:thin:@计算机名:1521:数据库实例名 12 // String DBuser="zczhgzpt"; 13 // String DBcode="oracle"; 14 List list = null; 15 try { 16 String sql = "SELECT USERID,SCSJ,ZTX,TPID FROM USER_PHOTO WHERE ZTX = '1' AND USERID = '"+userId+"' ";//ZTX = '1' and 17 System.out.println(sql); 18 list = new DBManager().list(sql,new String[]{}); 19 } catch (Exception e) { 20 // TODO Auto-generated catch block 21 e.printStackTrace(); 22 } 23 return list; 24 } 25 /** 26 * 作用:用于判断当前比对的信息情况 27 * @param userId 28 * @return 29 * @throws Exception 30 */ 31 public static Map getSDKMessageMap(String ID) throws Exception{ 32 Map map = null; 33 try { 34 String sql = "SELECT ID,USERID,STATUS FROM DD_SDKMESSAGE WHERE ID = '"+ID+"' "; 35 map = new DBManager().singleData(sql,new String[]{}); 36 } catch (Exception e) { 37 e.printStackTrace(); 38 } 39 return map; 40 } 41 }

1 package com.cwai.startup; 2 3 import java.util.ArrayList; 4 import java.util.Date; 5 import java.util.HashMap; 6 import java.util.List; 7 import java.util.Map; 8 9 import org.daisy.daisyframework.mobile.dd.message.MsgResponse; 10 import org.json.JSONArray; 11 import org.json.JSONObject; 12 13 import com.cwai.ado.XDataConvert; 14 import com.cwai.cfg.Configs; 15 import com.cwai.dao.DBManager; 16 /** 17 * 作用:通过百度AI进行线上人脸识别,比对,该文件用于获取数据库中发送的消息并给接收者发送叮叮消息 18 * @author wsf 19 * 20180423 20 */ 21 public class AutoSendSDKMessage implements Runnable { 22 23 public void execute(){ 24 25 try { 26 sendDDMessage(); 27 } catch (Exception e) { 28 e.printStackTrace(); 29 System.out.println("========================定时发送钉钉消息失败!"); 30 } 31 } 32 private String min = "ROUND(TO_NUMBER(SYSDATE - CREATE_TIME)*1440)"; 33 private String sec = "ROUND(TO_NUMBER(SYSDATE - CREATE_TIME)*86400)"; 34 35 private void sendDDMessage() throws Exception{ 36 String sql = "SELECT * FROM (SELECT " 37 + "T.ID,T.USERID,T.STATUS,TO_CHAR(T.CREATE_TIME, 'YYYY-MM-DD HH24:MI:SS') CREATE_TIME,T.FINISH_TIME,T.IP,T.LX,T.CONTENT,B.USERID_DDPT " 38 + "FROM DD_SDKMESSAGE T " 39 + "JOIN BM_USER B ON B.USERID = T.USERID " 40 + "WHERE STATUS = '0' AND DDSFFS = '0' AND "+sec+" < 50 ORDER BY T.CREATE_TIME " 41 + ") WHERE ROWNUM < 15"; 42 43 List list = DBManager.list(sql, new String[]{}); 44 String ids = ""; 45 Date date_before = new Date(); 46 //System.out.println("---------------------"); 47 //System.out.println("---------------------"); 48 //System.out.println("---------------------"); 49 System.out.println("准备发送钉钉消息..." + date_before.toLocaleString()); 50 List sql_list = new ArrayList<String>(); 51 for (int i = 0; i < list.size(); i++) { 52 Map map = (HashMap)list.get(i); 53 if(!"".equals(map.get("USERID"))) { 54 JSONArray json=new JSONArray(); 55 JSONObject json1 = new JSONObject(); 56 json1.put("key", "[验证IP]:"); 57 json1.put("value", XDataConvert.TryToString(map.get("IP"))); 58 json.put(json1); 59 60 String lx = XDataConvert.TryToString(map.get("LX")); 61 String lx_mc = "签名人脸识别"; 62 if("1".equals(lx)){ 63 lx_mc = "系统登录人脸识别"; 64 }else if("2".equals(lx)){ 65 lx_mc = "会议签到人脸识别"; 66 } 67 JSONObject json2 = new JSONObject(); 68 json2.put("key", "[验证类型]:"); 69 json2.put("value", lx_mc); 70 json.put(json2); 71 72 String create_time = XDataConvert.TryToDateTimeString(map.get("CREATE_TIME")); 73 JSONObject json3 = new JSONObject(); 74 json3.put("key", "[申请时间]:"); 75 json3.put("value", create_time); 76 json.put(json3); 77 78 JSONObject json4 = new JSONObject(); 79 json4.put("key", "[消息提醒]:"); 80 json4.put("value", "请首先确认是否您本人发起,如非本人,您的身份可能正在被冒用,否则,请点击本消息完成验证。"); 81 json.put(json4); 82 String check_url = Configs.getWww_location() + "work/common/sdk_xxpd.jsp?userid=" + XDataConvert.TryToString(map.get("USERID")) + "&ip=" + XDataConvert.TryToString(map.get("IP")) + "&createtime=" + (create_time.replace(" ", "").replace(":", "").replace("-", "")) + "&lx=" + lx + "&id=" + XDataConvert.TryToString(map.get("ID")) ; 83 //System.out.println("check_url_____________________________________________________"+check_url); 84 MsgResponse.sendOAMsg("ding41243d806b31cad2",XDataConvert.TryToString(map.get("USERID_DDPT")), "", Configs.getAgentid(), check_url, "面部识别验证提醒", json, "@lADOADmaWMzazQKA",""); 85 System.out.println("--发送完毕:" + XDataConvert.TryToString(map.get("USERID"))); 86 } 87 ids += map.get("ID") + ","; 88 } 89 //修改消息的发送状态 90 String sql_xxfs = "UPDATE DD_SDKMESSAGE SET DDSFFS = '1' WHERE ID IN ("+XDataConvert.toSqlInValues(ids)+")";//此处只是用来作为已发送的参照 91 sql_list.add(sql_xxfs); 92 //修改未进行验证已超时的信息状态(其中状态1,5的情况不作处理) 93 String sql_2 = "UPDATE DD_SDKMESSAGE SET STATUS = '2' WHERE STATUS = '0' AND FINISH_TIME IS NULL AND ROUND(TO_NUMBER(SYSDATE - CREATE_TIME)*1440) > 1 "; 94 sql_list.add(sql_2); 95 96 //查询要删除的信息 97 98 99 String sql_insert = "INSERT INTO DD_SDKMESSAGE_LOG (ID,USERID,STATUS,CREATE_TIME,FINISH_TIME,IP,LX,DDSFFS) " 100 + " select ID,USERID,STATUS,CREATE_TIME,FINISH_TIME,IP,LX,DDSFFS from DD_SDKMESSAGE where STATUS <> '0' AND "+min+" > 10 "; 101 sql_list.add(sql_insert); 102 103 //删除大于十分钟的信息 104 String sql_del = "DELETE FROM DD_SDKMESSAGE WHERE STATUS <> '0' AND "+min+" > 10 "; 105 sql_list.add(sql_del); 106 107 108 boolean flag = DBManager.executeBatch(sql_list); 109 110 111 System.out.println("--------消息更新发送--------"+flag); 112 Date date_end = new Date(); 113 System.out.println("发送钉钉消息完毕..." + date_end.toLocaleString() + "-----" + "本次用时:" + ((date_end.getTime() - date_before.getTime()) / 1000) + "秒"); 114 } 115 116 117 public void init() { 118 AutoSendSDKMessage service = new AutoSendSDKMessage(); 119 Thread thread = new Thread(service); 120 thread.start(); 121 } 122 123 public void run() { 124 while (true){ 125 try{ 126 execute(); 127 Thread.currentThread().sleep(4000); 128 } catch(Exception e) { 129 e.printStackTrace(); 130 return; 131 } 132 } 133 } 134 }
JSP、JS文件:
sdk_xxpd.jsp
camera.jsp
camera_out.jsp
getitems.jsp(用于jQuery的ajax调用)
单击事件按钮——签字、登陆
qm.js(用于封装调用签名弹出页面的方法)
步骤1(模式1):
1.AutoSendSDKMessage.java实时读取、发送消息到钉钉,
2.打开钉钉消息,进入sdk_xxpd.jsp页面,对当前打开的信息进行判断

1 <%@page import="java.text.SimpleDateFormat"%> 2 <%@page import="com.cwai.util.SQLUtils"%> 3 <%@page import="com.cwai.dao.DBManager"%> 4 <%@page import="com.cwai.pass.Md5"%> 5 <%@page import="com.cwai.pass.Security"%> 6 <%@page import="java.io.OutputStream"%> 7 <%@page import="org.daisy.daisyframework.commons.persistent.db.PrimaryKeyDependent"%> 8 <%@page import="org.apache.commons.fileupload.FileItem"%> 9 <%@page import="org.daisy.daisyframework.commons.io.upload.apacheupload.ApacheUploadRequest"%> 10 <%@ page language="java" import="java.util.*,com.cwai.xtag.*,com.cwai.web.*,com.cwai.ado.*,com.cwai.bean.*,com.cwai.xbean.*" pageEncoding="UTF-8"%> 11 <%@page import="com.cwai.logic.bean.User"%> 12 <jsp:directive.page import="com.cwai.ado.XDataConvert"/> 13 <jsp:directive.page import="org.daisy.daisyframework.commons.persistent.db.DataManipulation"/> 14 <jsp:directive.page import="org.daisy.daisyframework.control.ApplicationContext"/> 15 <% 16 String path = request.getContextPath(); 17 String basePath = request.getScheme()+"://"+ request.getServerName() + ":"+ request.getServerPort() + path + "/"; 18 String userId = xtag.getParameter(request, "userId"); 19 String msg = ""; 20 21 String userid = xtag.getParameter(request, "userid"); 22 String lx = xtag.getParameter(request, "lx"); 23 String ip = xtag.getParameter(request, "ip"); 24 String id = xtag.getParameter(request, "id"); 25 String create_time = xtag.getParameter(request, "createtime"); 26 //对当前登陆验证消息进行判断 27 //-获取数据库当前时间 28 String time_now = DBManager.getValue("select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual",new String[]{}); 29 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); 30 Date date1 = sdf.parse(time_now); 31 String ss = create_time.substring(0, 4) + "-" + create_time.substring(4, 6) + "-" + create_time.substring(6, 8) + " " + create_time.substring(8, 10) + ":" + create_time.substring(10, 12) + ":" + create_time.substring(12, 14); 32 Date date2 = sdf.parse(ss); 33 long minutes=(date1.getTime()-date2.getTime())/(1000);//秒 34 if( minutes > 60){ 35 msg = "该条信息已过时!"; 36 }else{ 37 Map map = new HashMap(); 38 map = SQLUtils.getSDKMessageMap(id); 39 if(map == null || (map.size() == 0) || "null".equals(map.get("STATUS")) || "".equals(map.get("STATUS"))){ 40 msg = "该条信息已过时!"; 41 }else if("2".equals(XDataConvert.TryToString(map.get("STATUS")))){ 42 msg = "该条信息已过时!"; 43 }else if("3".equals(XDataConvert.TryToString(map.get("STATUS")))){ 44 msg = "该条信息已取消处理,请操作最新发送的申请!"; 45 }else if("4".equals(XDataConvert.TryToString(map.get("STATUS")))){ 46 msg = "该信息已处理,无法进行操作!"; 47 } 48 } 49 50 %> 51 <!DOCTYPE html> 52 <html lang="en"> 53 <head> 54 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> 55 <meta charset="utf-8" /> 56 <base href="<%= basePath%>"> 57 <title>面部识别验证中</title> 58 <meta name="description" content="Static & Dynamic Tables" /> 59 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> 60 <link rel="stylesheet" href="./css/ace/css/bootstrap.css" /> 61 <link rel="stylesheet" href="./css/ace/css/font-awesome.css" /> 62 <link rel="stylesheet" href="./css/ace/css/bootstrap-datepicker3.css" /> 63 <link rel="stylesheet" href="./css/ace/css/bootstrap-datetimepicker.css" /> 64 <link rel="stylesheet" href="./css/ace/css/ace-fonts.css" /> 65 <link rel="stylesheet" href="./css/ace/css/ace.css" class="ace-main-stylesheet" id="main-ace-style" /> 66 <link rel="stylesheet" href="./css/ace/css/jquery-ui.custom.css" /> 67 <link rel="stylesheet" href="./css/ace/css/jquery.gritter.css" /> 68 <link rel="stylesheet" href="./css/dialog-skin/simple/ymPrompt.css" /> 69 <!--webuploader CSS--> 70 <link href="<%=basePath %>css/zui/css/zui.min.css" rel="stylesheet"> 71 <link rel="stylesheet" type="text/css" href="<%=basePath %>css/zui/lib/datetimepicker/datetimepicker.css"> 72 <link rel="stylesheet" type="text/css" href="<%=basePath %>css/zui/lib/kindeditor/kindeditor.min.css"> 73 <script src="<%=path%>/js/ymPrompt.js"></script> 74 <!--[if lte IE 9]> 75 <link rel="stylesheet" href="./css/ace/css/ace-part2.css" class="ace-main-stylesheet" /> 76 <![endif]--> 77 <!--[if lte IE 9]> 78 <link rel="stylesheet" href="./css/ace/css/ace-ie.css" /> 79 <![endif]--> 80 <!-- inline styles related to this page --> 81 <!-- ace settings handler --> 82 <script src="./css/ace/js/ace-extra.js"></script> 83 <!-- HTML5shiv and Respond.js for IE8 to support HTML5 elements and media queries --> 84 <!--[if lte IE 8]> 85 <script src="./css/ace/js/html5shiv.js"></script> 86 <script src="./css/ace/js/respond.js"></script> 87 <![endif]--> 88 <link rel="stylesheet" href="./css/zui/css/zui.min.css" /> 89 <link rel="stylesheet" href="./css/ace/css/chosen.css" /> 90 <!-- jQuery (ZUI中的Javascript组件依赖于jQuery) --> 91 <script src="<%=basePath %>js/jquery-2.2.0.min.js"></script> 92 <!-- ZUI Javascript组件 --> 93 <script src="<%=basePath %>css/ace/js/bootstrap.js"></script> 94 <script src="<%=basePath %>css/ace/js/chosen.jquery.js"></script> 95 <script src="<%=basePath %>css/ace/js/ace/ace.js"></script> 96 <script src="<%=basePath %>css/zui/js/zui.min.js"></script> 97 <script src="<%=basePath %>css/zui/lib/datetimepicker/datetimepicker.js"></script> 98 <script src="<%=basePath %>css/zui/lib/kindeditor/kindeditor.min.js"></script> 99 <style type="text/css"> 100 .chosen-choices {padding: 0px;} 101 table tr{ 102 height:25px; 103 } 104 table tr td{ 105 padding: 4px; 106 } 107 </style> 108 <script type="text/javascript"> 109 window.onload = function page_init() { 110 if('' == '<%= msg%>' || 'null' == '<%= msg%>'){ 111 window.location.href = '<%= path%>/work/common/camera.jsp?userid=<%= userid%>&lx=<%=lx%>&ip=<%=ip%>&id=<%=id%>'; 112 }else{ 113 //ymPrompt.alert('<%= msg%>'); 114 //$("#outMessage").html('<%= msg%>'); 115 //$("#outMessage").val('<%= msg%>'); 116 var data = '<%= msg%>'; 117 if(null!=data&&""!=data.trim()){ 118 new $.zui.Messager(data, { 119 type: 'warning' ,// 定义颜色主题 120 icon: 'warning-sign', 121 placement: 'top_left', 122 close: false, 123 time: 0 , //0 为不自动隐藏 124 }).show(); 125 } 126 } 127 } 128 129 130 //$("#outMessage").html(result_message); 131 </script> 132 </head> 133 <body class="no-skin" style="background-color: #fff;"> 134 <%-- 135 <div align="center" > 136 <div class="alert alert-warning-inverse" id="outMessage" style="font-size: 18pt;margin-top: 20px"></div> 137 </div> 138 --%> 139 <%-- 140 <div id="outMessage"> 141 </div> 142 --%> 143 <!-- basic scripts --> 144 145 <!--[if !IE]> --> 146 <script type="text/javascript"> 147 window.jQuery || document.write("<script src='./css/ace/js/jquery.js'>"+"<"+"/script>"); 148 </script> 149 150 <!-- <![endif]--> 151 <!--[if IE]> 152 <script type="text/javascript"> 153 window.jQuery || document.write("<script src='./css/ace/js/jquery1x.js'>"+"<"+"/script>"); 154 </script> 155 <![endif]--> 156 <script type="text/javascript"> 157 if('ontouchstart' in document.documentElement) document.write("<script src='./css/ace/js/jquery.mobile.custom.js'>"+"<"+"/script>"); 158 </script> 159 <script src="./css/ace/js/bootstrap.js"></script> 160 <script src="./css/ace/js/chosen.jquery.js"></script> 161 <!-- CESHI --> 162 163 <script src="./css/ace/js/date-time/moment.js"></script> 164 <script src="./css/ace/js/date-time/bootstrap-datepicker.js"></script> 165 <script src="./css/ace/js/date-time/bootstrap-datetimepicker.js"></script> 166 <script src="./css/ace/js/ace/elements.scroller.js"></script> 167 <script src="./css/ace/js/ace/elements.scroller.js"></script> 168 <script src="./css/ace/js/ace/elements.colorpicker.js"></script> 169 <script src="./css/ace/js/ace/elements.fileinput.js"></script> 170 <script src="./css/ace/js/ace/elements.typeahead.js"></script> 171 <script src="./css/ace/js/ace/elements.wysiwyg.js"></script> 172 <script src="./css/ace/js/ace/elements.spinner.js"></script> 173 <script src="./css/ace/js/ace/elements.treeview.js"></script> 174 <script src="./css/ace/js/ace/elements.wizard.js"></script> 175 <script src="./css/ace/js/ace/elements.aside.js"></script> 176 <script src="./css/ace/js/ace/ace.js"></script> 177 <script src="./css/ace/js/bootbox.js"></script> 178 <script src="./css/ace/js/ace/ace.ajax-content.js"></script> 179 <script src="./css/ace/js/ace/ace.touch-drag.js"></script> 180 <script src="./css/ace/js/ace/ace.sidebar.js"></script> 181 <script src="./css/ace/js/ace/ace.sidebar-scroll-1.js"></script> 182 <script src="./css/ace/js/ace/ace.submenu-hover.js"></script> 183 <script src="./css/ace/js/ace/ace.widget-box.js"></script> 184 <script src="./css/ace/js/ace/ace.settings.js"></script> 185 <script src="./css/ace/js/ace/ace.settings-rtl.js"></script> 186 <script src="./css/ace/js/ace/ace.settings-skin.js"></script> 187 <script src="./css/ace/js/ace/ace.widget-on-reload.js"></script> 188 <script src="./css/ace/js/ace/ace.searchbox-autocomplete.js"></script> 189 <!-- the following scripts are used in demo only for onpage help and you don't need them --> 190 <link rel="stylesheet" href="./css/ace/css/ace.onpage-help.css" /> 191 <link rel="stylesheet" href="./css/ace/js/themes/sunburst.css" /> 192 <script type="text/javascript"> ace.vars['base'] = '..'; </script> 193 <script src="./css/ace/js/ace/elements.onpage-help.js"></script> 194 <script src="./css/ace/js/ace/ace.onpage-help.js"></script> 195 <script src="./css/ace/js/rainbow.js"></script> 196 <script src="./css/ace/js/language/generic.js"></script> 197 <script src="./css/ace/js/language/html.js"></script> 198 <script src="./css/ace/js/language/css.js"></script> 199 <script src="./css/ace/js/language/javascript.js"></script> 200 <script src="./js/js.js"></script> 201 <script src="<%= path%>/js/layer/layer.js"></script> 202 <script type="text/javascript"> 203 $(function(){ 204 dyreg('panel1', '12'); 205 }) 206 //当浏览器大小变化时 207 $(window).resize(function () { 208 dyreg('panel1', '12'); 209 }); 210 </script> 211 </body> 212 </html>
3.如果OK,进入camera.jsp页面调用摄像头进行拍照。

1 <%@page import="com.cwai.xtag.xTable"%> 2 <%@page import="com.cwai.logic.dao.PageDD"%> 3 <%@page import="com.cwai.ado.PageList"%> 4 <%@page import="com.cwai.logic.task.sql.TaskSQL"%> 5 <%@page import="com.cwai.logic.bean.User"%> 6 <%@page import="com.cwai.dao.DBManager"%> 7 <%@page import="com.cwai.ado.XDataConvert"%> 8 <%@page import="com.cwai.xtag.xtag"%> 9 <%@page import="com.cwai.cfg.Configs"%> 10 <%@page import="org.daisy.daisyframework.mobile.dd.AuthHelper"%> 11 <%@ page language="java" import="java.util.*" contentType="text/html;charset=utf-8"%> 12 <% 13 String path = request.getContextPath(); 14 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 15 String agentId = XDataConvert.TryToString(session.getAttribute("agentId")); 16 if("".equals(agentId)) { 17 agentId = Configs.getAgentid(); 18 } 19 String userid = xtag.getParameter(request, "userid"); 20 String lx = xtag.getParameter(request, "lx"); 21 String ip = xtag.getParameter(request, "ip"); 22 String id = xtag.getParameter(request, "id"); 23 24 %> 25 <!DOCTYPE html> 26 <html> 27 <head> 28 <meta charset="utf-8"> 29 <meta http-equiv=Content-Type content="text/html;charset=utf-8"> 30 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 31 <meta content="yes" name="apple-mobile-web-app-capable"/> 32 <meta content="black" name="apple-mobile-web-app-status-bar-style"> 33 <meta content="telephone=no" name="format-detection"/> 34 <meta content="yes" name="apple-touch-fullscreen"/> 35 <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no" /> 36 <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0"> 37 38 <script src="<%=basePath%>js/jqueyweui/lib/jquery-2.1.4.js"></script> 39 40 <title>全流程集成管理平台</title> 41 <script type="text/javascript" src="http://g.alicdn.com/dingding/open-develop/1.9.0/dingtalk.js"></script> 42 <script type="text/javascript" src="<%=path%>/www/ddpt/javascripts/logger.js"></script> 43 44 <link href="<%=basePath %>css/zui/css/zui.min.css" rel="stylesheet"> 45 <link rel="stylesheet" href="<%=basePath %>css/ace/css/bootstrap.css" /> 46 <link rel="stylesheet" href="<%=basePath %>css/ace/css/font-awesome.css" /> 47 <link rel="stylesheet" href="<%=basePath %>css/ace/css/ace-fonts.css" /> 48 <link rel="stylesheet" href="<%=basePath %>css/ace/css/ace.css" class="ace-main-stylesheet" id="main-ace-style" /> 49 <link rel="stylesheet" href="<%=basePath %>css/ace/css/ace.onpage-help.css" /> 50 <link rel="stylesheet" href="<%=basePath %>css/ace/js/themes/sunburst.css" /> 51 52 <link rel="stylesheet" href="<%=basePath %>css/ace/css/jquery-ui.custom.css" /> 53 <link rel="stylesheet" href="<%=basePath %>css/ace/css/jquery.gritter.css" /> 54 <link rel="stylesheet" href="<%=basePath %>css/dialog-skin/simple/ymPrompt.css" /> 55 56 <!--webuploader CSS--> 57 <link rel="stylesheet" type="text/css" href="<%=basePath %>css/zui/lib/datetimepicker/datetimepicker.css"> 58 <link rel="stylesheet" type="text/css" href="<%=basePath %>css/zui/lib/kindeditor/kindeditor.min.css"> 59 <script type="text/javascript"> 60 window.jQuery || document.write("<script src='<%= path%>/css/ace/js/jquery.js'>"+"<"+"/script>"); 61 </script> 62 63 64 <!-- ZUI Javascript组件 --> 65 66 <link rel="stylesheet" href="<%= path%>/css/dialog-skin/simple/ymPrompt.css" /> 67 <script src="<%= path%>/js/ymPrompt.js"></script> 68 69 <!-- jQuery (ZUI中的Javascript组件依赖于jQuery) --> 70 <script src="<%=basePath %>js/jquery-2.2.0.min.js"></script> 71 <!-- ZUI Javascript组件 --> 72 <script src="<%=basePath %>css/zui/js/zui.min.js"></script> 73 <script src="<%=basePath %>css/ace/js/bootstrap.js"></script> 74 <script src="<%=basePath %>css/ace/js/chosen.jquery.js"></script> 75 <script src="<%=basePath %>css/ace/js/ace/ace.js"></script> 76 <script src="<%=basePath %>css/zui/lib/datetimepicker/datetimepicker.js"></script> 77 <script src="<%=basePath %>css/zui/lib/kindeditor/kindeditor.min.js"></script> 78 <script src="<%= path%>/js/layer/layer.js"></script> 79 <link rel="stylesheet" href="<%= path%>/js/select2/css/select2.css" /> 80 <script src="<%= path%>/js/select2/js/select2.js"></script> 81 82 <script type="text/javascript"> 83 //在此拿到权限验证配置所需要的信息 钉钉平台拍照 84 var _config = <%= AuthHelper.getConfig(request, Configs.getCorpID(), agentId) %>; 85 dd.config({ 86 agentId : _config.agentid, 87 corpId : _config.corpId, 88 timeStamp : _config.timeStamp, 89 nonceStr : _config.nonceStr, 90 signature : _config.signature, 91 jsApiList : [ 'runtime.info', 'biz.contact.choose', 92 'device.notification.confirm', 'device.notification.alert', 93 'device.notification.prompt', 'biz.ding.post', 94 'biz.util.openLink', 'device.geolocation.get', 'biz.util.scan', 'biz.map.locate', 'biz.util.uploadImageFromCamera', 'biz.navigation.close'] 95 }); 96 97 function close_win() { 98 dd.biz.navigation.close({ 99 onSuccess : function(result) { 100 /*result结构 101 {} 102 */ 103 }, 104 onFail : function(err) {} 105 }); 106 } 107 108 dd.ready(function(){ 109 dd.biz.util.uploadImageFromCamera({ 110 compression: true,//(是否压缩,默认为true) 111 quality: 50, // 图片压缩质量, 112 resize: 50, // 图片缩放率 113 stickers: { // 水印信息 114 }, 115 onSuccess : function(result) { 116 var str = result +"~<%= userid%>~<%=id%>" ; 117 //var result_message = ajaxGetData("SDKRESULT",str);//getdata.jsp 118 $.ajax({ 119 url:"<%= path%>/ajax/getitems.jsp", //请求的url地址 120 dataType: "text", //返回格式为json 121 async: false, 122 data: {"DMZL" : "SDKRESULT", "queryValue" : str }, 123 type:"post", //请求方式 124 success:function(data){ 125 var re = new Array(); 126 re = data.split("~"); 127 128 if(null != re[1] && "" != re[1].trim()){ 129 130 if("OK" == re[0].trim()){ 131 new $.zui.Messager(re[1], { 132 type: 'success' ,// 定义颜色主题 133 icon: 'smile', 134 placement:'top-left', 135 close: false, 136 time: 0 //0 为不自动隐藏 137 }).show(); 138 //alert("成功音乐播放"); 139 //音乐播放 140 var file1 = []; 141 file1['mp3'] = '<%=path%>/sound/success.mp3';//文件路径 142 audioplayer('audioplane', file1, false); 143 }else{ 144 new $.zui.Messager(re[1], { 145 type: 'warning' ,// 定义颜色主题 146 icon: 'warning-sign', 147 placement:'top-left', 148 close: false, 149 time: 0 //0 为不自动隐藏 150 }).show(); 151 //alert("失败音乐播放"); 152 //音乐播放 153 var file2 = []; 154 file2['mp3'] = '<%=path%>/sound/fail.mp3';//文件路径 155 audioplayer('audioplane', file2, false); 156 } 157 158 setTimeout("close_win()", 2000); 159 } 160 } 161 }); 162 }, 163 onFail : function(err) { 164 //$("#outMessage").html(err); 165 if(null != err && "" != err.trim()){ 166 new $.zui.Messager(err, { 167 type: 'warning' ,// 定义颜色主题 168 icon: 'warning-sign', 169 placement:'top-left', 170 close: false, 171 time: 0 //0 为不自动隐藏 172 }).show(); 173 } 174 } 175 }); 176 }); 177 178 dd.error(function(err) { 179 alert('dd error: ' + JSON.stringify(err)); 180 }); 181 182 /* 183 用法示例: 184 var file = []; 185 file['mp3'] = '1.mp3'; 186 file['ogg'] = '1.ogg'; 187 // 播放 188 audioplayer('audioplane', file, true); 189 // 停止 190 audioplayer('audioplane'); 191 */ 192 /** 音乐播放器 * @param obj 播放器id * @param file 音频文件 mp3: ogg: * @param loop 是否循环 */ 193 function audioplayer(id, file, loop){ 194 var audioplayer = document.getElementById(id); 195 if(audioplayer!=null) 196 { 197 document.body.removeChild(audioplayer); 198 } 199 if(typeof(file)!='undefined') 200 { 201 if(navigator.userAgent.indexOf("MSIE")>0) 202 { 203 // IE 204 var player = document.createElement('bgsound'); 205 player.id = id; 206 player.src = file['mp3']; 207 player.setAttribute('autostart', 'true'); 208 if(loop){ player.setAttribute('loop', 'infinite'); 209 } 210 document.body.appendChild(player); 211 }else{ 212 // Other FF Chome Safari Opera 213 var player = document.createElement('audio'); 214 player.id = id; 215 player.setAttribute('autoplay', 'autoplay'); 216 if (loop) { 217 player.setAttribute('loop', 'loop'); 218 } 219 document.body.appendChild(player); 220 var mp3 = document.createElement('source'); 221 mp3.src = file['mp3']; 222 mp3.type = 'audio/mpeg'; 223 player.appendChild(mp3); 224 var ogg = document.createElement('source'); 225 ogg.src = file['ogg']; 226 ogg.type = 'audio/ogg'; 227 player.appendChild(ogg); 228 } 229 } 230 } 231 232 </script> 233 <style type="text/css"> 234 235 </style> 236 </head> 237 <body> 238 <div id="outMessage"></div> 239 </body> 240 </html>
4.调用Ajax对照片进行比对,返回结果,同时内网实时检测结果,并做出相应处理
步骤2(模式2):
1..java文件实时读取、发送消息到钉钉,
2.打开钉钉消息,进入主页面,显示【签字】按钮(同时用到遮罩层的实现)

1 1. 2 <%@page import="com.cwai.cfg.Configs"%> 3 <%@page import="org.daisy.daisyframework.mobile.dd.AuthHelper"%> 4 5 2. 6 //获取当前用户的签字模式 7 Map map_ms = DBManager.singleData("SELECT USERID,QZMS FROM BM_USER_INFO WHERE USERID = '"+user.getUserId()+"'", new String[]{}); 8 String qzms = XDataConvert.TryToString(map_ms.get("QZMS")); 9 10 3. 11 <!-- 遮罩层css代码(两种样式,看喜好选择) --> 12 <style type="text/css"> 13 .mask1 { 14 position: absolute; 15 left: 0px; 16 top: 0px; 17 right: 0px; 18 bottom: 0px; 19 display: none; 20 background: rgba(0, 0, 0, 0.4); 21 } 22 23 .mask2 { 24 position: fixed; 25 left: 0px; 26 top: 0px; 27 right: 0px; 28 bottom: 0px; 29 display: none; 30 background: rgba(0, 0, 0, 0.4); 31 } 32 </style> 33 4. 34 //单击事件绑定 35 onclick="signature('20161226024039000043','<%=user.getUserId() %>','QM','')" 36 37 5. 38 <!-- 遮罩层 --> 39 <div class="mask1"></div> 40 <div class="mask2"></div> 41 42 6. 43 //调用的JS 44 <script src="<%= path%>/js/qm.js"></script> 45 <!-- 用于调用摄像头 --> 46 <script type="text/javascript" src="http://g.alicdn.com/dingding/open-develop/1.9.0/dingtalk.js"></script> 47 <script type="text/javascript" src="<%=path%>/www/ddpt/javascripts/logger.js"></script> 48 49 50 51 7. 52 window.onload=function(){ 53 //初始化遮罩层隐藏 54 document.querySelector(".mask1").style.display = "none"; 55 document.querySelector(".mask2").style.display = "none"; 56 } 57 58 //获取使用的变量 59 var ny = '<%= new SimpleDateFormat("yyyy-MM-dd").format(new Date())%>'; 60 var qzms = "<%=qzms%>"; 61 var path = "<%=path%>"; 62 //签名 63 function signature(id,userid,lx,qzrq){ 64 //打开遮罩层 65 document.querySelector(".mask2").style.display = "block"; 66 //document.querySelector(".mask2").style.display = "block"; 67 qmxz(qzms,path,id,userid,lx,qzrq); 68 } 69 70 //用于调用摄像头 71 var _config = <%= AuthHelper.getConfig(request, Configs.getCorpID(), Configs.getAgentid()) %>; 72 dd.config({ 73 agentId : _config.agentid, 74 corpId : _config.corpId, 75 timeStamp : _config.timeStamp, 76 nonceStr : _config.nonceStr, 77 signature : _config.signature, 78 jsApiList : [ 'runtime.info', 'biz.contact.choose', 79 'device.notification.confirm', 'device.notification.alert', 80 'device.notification.prompt', 'biz.ding.post', 81 'biz.util.openLink', 'device.geolocation.get', 'biz.util.scan', 'biz.map.locate', 'biz.util.uploadImageFromCamera', 'biz.navigation.close'] 82 });
3.单击【签字】按钮,弹出选择签字模式对话框(本项目设4类 1 混合验证(默认密码) 2混合验证(默认人脸识别) 3仅密码验证 4仅人脸识别验证 )
如果是3、4情况则直接进入,不需要弹出选择对话框

//20180502人脸识别新增遮罩层 var v_result = ''; dd.error(function(err) { alert('dd error: ' + JSON.stringify(err)); }); /** * 弹出消息进行签字模式的选择 * @param qzms 签字模式 * @param path 项目地址 * @param id 获取图片的ID * @param userid 用户ID * @param lx 签名类型(会签:HQ 签名:QM) * @param qzrq 签字日期 * @param hqshow 会签签名按钮是否显示 0(false):否 1(true)是 */ function qmxz(qzms,path, id,userid,lx,qzrq,hqshow){ var title = "签名"; var url = path + "/images/login/logininputbg.gif"; var img = "<img src='" + url + "' />"; var content = ""; if("1" == qzms || "3" == qzms){ if("1" == qzms){ //content = "当前签字模式为<br>【密码验证】和【面部识别】验证<br>点击【关闭】按钮将取消验证"; layer.msg("", { time: 10000, //20s后自动关闭 btn: ['密码验证', '面部识别', '关闭'] ,yes:function (index){ layer.close(index); dzqm(path,id,userid,lx,qzrq,hqshow); },btn2:function (index){ layer.close(index); sdk(path,id,userid,lx,qzrq,hqshow); },btn3:function (index){ layer.close(index); document.querySelector(".mask1").style.display = "none"; document.querySelector(".mask2").style.display = "none"; } }); }else{ dzqm(path,id,userid,lx,qzrq,hqshow); } }else if("2" == qzms || "4" == qzms){ if("2" == qzms){ //content = "当前签字模式为【面部识别】验证<br>点击【切换】按钮切换至【密码验证】<br>点击【确认】按钮进行【面部识别】验证"; layer.msg("", { time: 10000, //20s后自动关闭 btn: ['密码验证', '面部识别', '关闭'] ,yes:function (index){ layer.close(index); dzqm(path,id,userid,lx,qzrq,hqshow); },btn2:function (index){ layer.close(index); sdk(path,id,userid,lx,qzrq,hqshow); },btn3:function (index){ layer.close(index); document.querySelector(".mask1").style.display = "none"; document.querySelector(".mask2").style.display = "none"; } }); }else{ sdk(path,id,userid,lx,qzrq,hqshow); } } } /** * 电子签名方式进行签名 * @param id * @param userid */ function dzqm(path, id, userid,lx,qzrq,hqshow){ layer.prompt({ title: '输入签字密码,并确认', formType: 1, btn2:function(index){ layer.close(index); document.querySelector(".mask1").style.display = "none"; document.querySelector(".mask2").style.display = "none"; } }, function(pass, index){ layer.close(index); $.ajax({ type: "POST", url: path + "/ajax/formdata.jsp", data: {type: 'SIGNATURE',userid: userid,pass: pass}, dataType: "json", success:function(data){ //console.log(data); if(data.code == 2){ if("QM" == lx.trim()){ var src = path + "/work/common/view_image2.jsp?tpid=" + data.qzxxid; $("#"+id+"_img").attr("src",src); $("#"+id).val(data.qzxxid); $("#"+id+"_btn").hide(); $("#"+id+"_img").show(); if("" != qzrq && null != qzrq ){ $("#"+qzrq).val(ny); } }else if("HQ" == lx.trim()){ app.huiqian.push({ userid: userid, imgid: data.qzxxid }); if("0" == hqshow){ app.hqshow = false; }else { $("#"+id+"_btn").hide(); } } document.querySelector(".mask1").style.display = "none"; document.querySelector(".mask2").style.display = "none"; }else{ layer.msg(data.msg, {icon: 2, time: 3000}); document.querySelector(".mask1").style.display = "none"; document.querySelector(".mask2").style.display = "none"; } } }) } ); } /** * 人脸识别方式进行签字 * @param path * @param id * @param userid * @param lx * @param qzrq * @param hqshow */ function sdk(path, id, userid,lx,qzrq,hqshow){ /* var index = layer.open({ type: 2, content: path + '/work/common/camera_out.jsp?userid='+userid+'&id='+id+'&lx='+lx+'&qzrq='+qzrq+'&hqshow='+hqshow, area: ['320px', '195px'], maxmin: true }); */ var v_path = path + '/work/common/camera_out.jsp?userid='+userid+'&id='+id+'&lx='+lx+'&qzrq='+qzrq+'&hqshow='+hqshow; dd.ready(function(){ dd.biz.util.uploadImageFromCamera({ compression: true,//(是否压缩,默认为true) quality: 50, // 图片压缩质量, resize: 50, // 图片缩放率 stickers: { // 水印信息 }, onSuccess : function(result) { if(document.getElementById("camera_frame") == null) { $("body").append("<iframe name='camera_frame' id='camera_frame' src='"+ v_path +"' style='display:none'/>"); } else { $("#camera_frame").attr("src", v_path);//注意src赋值的方式 } v_result = result; }, onFail : function(err) { } }); document.addEventListener('resume', function() { document.querySelector(".mask1").style.display = "none"; document.querySelector(".mask2").style.display = "none"; }); document.addEventListener('pause', function() { //alert("页面不可见");// 在这里处理你的业务逻辑 }); }); /* if(document.getElementById("camera_frame") == null) { $("body").append("<iframe id='camera_frame' src='"+ v_path +"' style='display:none'/>"); } else { $("#camera_frame").attr("src") = v_path; } */ //window.open(); /* //path + '/work/common/camera_out.jsp?userid='+userid+'&id='+id+'&lx='+lx+'&qzrq='+qzrq+'&hqshow='+hqshow //var dataurl = "#springUrl('/work/common/camera_out.jsp')?userid="+selectManagerDept+"&id="+id+"&lx="+lx+"&qzrq="+qzrq+"&hqshow="+hqshow; var dataurl = 'http://layim.layui.com'; var index = layer.open({ type: 2, content: dataurl, area: ['320px', '195px'], maxmin: true; }); ymPrompt.win({ message: path + '/work/common/camera_out.jsp?userid='+userid+'&id='+id+'&lx='+lx+"&qzrq="+qzrq+"&hqshow="+hqshow, width:200, height:300, title:'人脸识别签名', handler: function(flag) { }, minBtn:true, iframe:true }); */ }
4.选择模式,进入对应签字情况
面部识别(主要展示):
进入camera_out.jsp页面进行图片的比对(同时用到MP3
的播放)

1 <%@page import="java.text.SimpleDateFormat"%> 2 <%@page import="com.cwai.xtag.xTable"%> 3 <%@page import="com.cwai.logic.dao.PageDD"%> 4 <%@page import="com.cwai.ado.PageList"%> 5 <%@page import="com.cwai.logic.task.sql.TaskSQL"%> 6 <%@page import="com.cwai.logic.bean.User"%> 7 <%@page import="com.cwai.dao.DBManager"%> 8 <%@page import="com.cwai.ado.XDataConvert"%> 9 <%@page import="com.cwai.xtag.xtag"%> 10 <%@page import="com.cwai.cfg.Configs"%> 11 <%@page import="org.daisy.daisyframework.mobile.dd.AuthHelper"%> 12 <%@ page language="java" import="java.util.*" contentType="text/html;charset=utf-8"%> 13 <% 14 String path = request.getContextPath(); 15 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 16 String agentId = XDataConvert.TryToString(session.getAttribute("agentId")); 17 if("".equals(agentId)) { 18 agentId = Configs.getAgentid(); 19 } 20 String userid = xtag.getParameter(request, "userid"); 21 String id = xtag.getParameter(request, "id"); 22 String lx = xtag.getParameter(request, "lx"); 23 String qzrq = xtag.getParameter(request, "qzrq"); 24 String hqshow = xtag.getParameter(request, "hqshow"); 25 26 27 System.out.println("------------------------开始拍照---------------------------------"); 28 System.out.println("------------------------开始拍照---------------------------------"); 29 System.out.println("------------------------开始拍照---------------------------------"); 30 31 %> 32 <!DOCTYPE html> 33 <html> 34 <head> 35 <meta charset="utf-8"> 36 <meta http-equiv=Content-Type content="text/html;charset=utf-8"> 37 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 38 <meta content="yes" name="apple-mobile-web-app-capable"/> 39 <meta content="black" name="apple-mobile-web-app-status-bar-style"> 40 <meta content="telephone=no" name="format-detection"/> 41 <meta content="yes" name="apple-touch-fullscreen"/> 42 <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no" /> 43 <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0"> 44 45 <script src="<%=basePath%>js/jqueyweui/lib/jquery-2.1.4.js"></script> 46 47 <title>全流程集成管理平台</title> 48 <script type="text/javascript" src="http://g.alicdn.com/dingding/open-develop/1.9.0/dingtalk.js"></script> 49 <script type="text/javascript" src="<%=path%>/www/ddpt/javascripts/logger.js"></script> 50 51 52 <script type="text/javascript"> 53 window.jQuery || document.write("<script src='<%= path%>/css/ace/js/jquery.js'>"+"<"+"/script>"); 54 </script> 55 <!-- ZUI Javascript组件 --> 56 57 <link rel="stylesheet" href="<%= path%>/css/dialog-skin/simple/ymPrompt.css" /> 58 <script src="<%= path%>/js/ymPrompt.js"></script> 59 60 <!-- jQuery (ZUI中的Javascript组件依赖于jQuery) --> 61 <script src="<%=basePath %>js/jquery-2.2.0.min.js"></script> 62 <!-- ZUI Javascript组件 --> 63 <link href="<%=basePath %>css/zui/css/zui.min.css" rel="stylesheet"> 64 <script src="<%=basePath %>css/zui/js/zui.min.js"></script> 65 <script src="<%= path%>/js/layer/layer.js"></script> 66 67 <script type="text/javascript"> 68 //在此拿到权限验证配置所需要的信息 钉钉平台拍照 69 70 window.onload = function page_init() { 71 //alert("进入camora"); 72 f_success(window.parent.v_result); 73 } 74 75 var id = '<%=id%>'; 76 var userid = '<%=userid%>'; 77 //用于签名时间(FORM_20170117050524000077.jsp) 78 var qzrq = '<%=qzrq%>'; 79 var ny = '<%= new SimpleDateFormat("yyyy-MM-dd").format(new Date())%>'; 80 var hqshow = '<%=hqshow%>'; 81 82 function f_success(result) { 83 var str = result +"~<%= userid%>" ; 84 //var result_message = ajaxGetData("SDKRESULT",str);//getdata.jsp 85 //alert("str______________"+str); 86 $.ajax({ 87 url:"<%= path%>/ajax/getitems.jsp", //请求的url地址 88 dataType: "text", //返回格式为json 89 async: false, 90 data: {"DMZL" : "SDKRESULT_OUT", "queryValue" : str }, 91 type:"post", //请求方式 92 success:function(data){ 93 var re = new Array(); 94 re = data.split("~"); 95 if(null != re[1] && "" != re[1].trim()){ 96 if("OK" == re[0].trim()){ 97 //alert("re[0].trim():"+re[0].trim()); 98 //获取qzxxid 99 $.ajax({ 100 url : '<%= path%>/ajax/getitems.jsp', 101 type : 'POST', 102 dataType : 'text', 103 data : {"DMZL":"GETQZXXID", "queryValue": '<%= userid%>' }, 104 success : function(qzxx){ 105 ///alert("qzxx:"+qzxx); 106 //进行图片签字,显示图片 107 if("0" == qzxx.trim()){ 108 //失败音乐播放 109 var file2 = []; 110 file2['mp3'] = '<%=path%>/sound/fail.mp3';//文件路径 111 audioplayer('audioplane', file2, false); 112 //提示信息 113 new window.parent.$.zui.Messager("没有被应用的签字,请先设置签字!", { 114 type: 'warning' ,// 定义颜色主题 115 icon: 'warning-sign', 116 placement:'center', 117 close: false, //不需要关闭按钮 118 time: 0 , //0 为不自动隐藏 119 actions: [{ 120 name: 'undo', 121 icon: 'undo', 122 text: '关闭', 123 action: function() { // 点击该操作按钮的回调函数 124 //隐藏遮罩层 125 window.parent.document.querySelector(".mask1").style.display = "none"; 126 window.parent.document.querySelector(".mask2").style.display = "none"; 127 //return false; // 通过返回 false 来阻止消息被点击时隐藏 128 } 129 }] 130 }).show(); 131 }else{ 132 //成功音乐播放 133 var file1 = []; 134 file1['mp3'] = '<%=path%>/sound/success.mp3';//文件路径 135 audioplayer('audioplane', file1, false); 136 //提示音乐播放完毕自动关闭 137 //alert("<%=lx%>"); 138 if("QM" == "<%=lx%>"){ 139 var src = "<%=path%>/work/common/view_image2.jsp?tpid=" + qzxx.trim(); 140 window.parent.$("#"+id+"_img").attr("src",src); 141 window.parent.$("#"+id).val(qzxx.trim()); 142 window.parent.$("#"+id+"_btn").hide(); 143 window.parent.$("#"+id+"_img").show(); 144 if("" != qzrq && null != qzrq ){ 145 window.parent.$("#"+qzrq).val(ny); 146 } 147 //隐藏遮罩层 148 window.parent.document.querySelector(".mask1").style.display = "none"; 149 window.parent.document.querySelector(".mask2").style.display = "none"; 150 }else if("HQ" == "<%=lx%>"){ 151 window.parent.app.huiqian.push({ 152 userid: userid, 153 imgid: qzxx.trim() 154 }); 155 if("0" == hqshow){ 156 window.parent.app.hqshow = false; 157 }else { 158 window.parent.$("#"+id+"_btn").hide(); 159 } 160 //隐藏遮罩层 161 window.parent.document.querySelector(".mask1").style.display = "none"; 162 window.parent.document.querySelector(".mask2").style.display = "none"; 163 } 164 165 } 166 } 167 }); 168 }else{ 169 //失败音乐播放 170 var file2 = []; 171 file2['mp3'] = '<%=path%>/sound/fail.mp3';//文件路径 172 audioplayer('audioplane', file2, false); 173 //提示信息 174 new window.parent.$.zui.Messager(re[1].trim(), { 175 type: 'warning' ,// 定义颜色主题 176 icon: 'warning-sign', 177 placement:'center', 178 close: false, //不需要关闭按钮 179 time: 0 , //0 为不自动隐藏 180 actions: [{ 181 name: 'undo', 182 icon: 'undo', 183 text: '关闭', 184 action: function() { // 点击该操作按钮的回调函数 185 //隐藏遮罩层 186 window.parent.document.querySelector(".mask1").style.display = "none"; 187 window.parent.document.querySelector(".mask2").style.display = "none"; 188 //return false; // 通过返回 false 来阻止消息被点击时隐藏 189 } 190 }] 191 }).show(); 192 193 } 194 } 195 } 196 }); 197 } 198 199 function f_error(err) { 200 new $.zui.Messager(re[1], { 201 type: 'warning' ,// 定义颜色主题 202 icon: 'warning-sign', 203 placement:'top-left', 204 close: false, 205 time: 0 //0 为不自动隐藏 206 }).show(); 207 } 208 209 /* 210 用法示例: 211 var file = []; 212 file['mp3'] = '1.mp3'; 213 file['ogg'] = '1.ogg'; 214 // 播放 215 audioplayer('audioplane', file, true); 216 // 停止 217 audioplayer('audioplane'); 218 */ 219 /** 音乐播放器 * @param obj 播放器id * @param file 音频文件 mp3: ogg: * @param loop 是否循环 */ 220 function audioplayer(id, file, loop){ 221 var audioplayer = document.getElementById(id); 222 if(audioplayer!=null) 223 { 224 document.body.removeChild(audioplayer); 225 } 226 if(typeof(file)!='undefined') 227 { 228 if(navigator.userAgent.indexOf("MSIE")>0) 229 { 230 // IE 231 var player = document.createElement('bgsound'); 232 player.id = id; 233 player.src = file['mp3']; 234 player.setAttribute('autostart', 'true'); 235 if(loop){ player.setAttribute('loop', 'infinite'); 236 } 237 document.body.appendChild(player); 238 }else{ 239 // Other FF Chome Safari Opera 240 var player = document.createElement('audio'); 241 player.id = id; 242 player.setAttribute('autoplay', 'autoplay'); 243 if (loop) { 244 player.setAttribute('loop', 'loop'); 245 } 246 document.body.appendChild(player); 247 var mp3 = document.createElement('source'); 248 mp3.src = file['mp3']; 249 mp3.type = 'audio/mpeg'; 250 player.appendChild(mp3); 251 var ogg = document.createElement('source'); 252 ogg.src = file['ogg']; 253 ogg.type = 'audio/ogg'; 254 player.appendChild(ogg); 255 } 256 } 257 } 258 259 260 </script> 261 <style type="text/css"> 262 263 </style> 264 </head> 265 <body> 266 <% 267 System.out.println("------------------------拍照结束---------------------------------"); 268 System.out.println("------------------------拍照结束---------------------------------"); 269 System.out.println("------------------------拍照结束---------------------------------"); 270 %> 271 <div id="outMessage"> 272 </div> 273 </body> 274 </html>

1 <%@page import="com.cwai.util.SDKMatch"%> 2 <%@page import="net.sf.json.JSONObject"%> 3 <%@page import="net.sf.json.JSONArray"%> 4 <%@page import="com.cwai.xtag.xtag"%> 5 <%@page import="com.cwai.logic.task.sql.TaskSQL"%> 6 <%@page import="org.daisy.daisyframework.util.DataConvertor"%> 7 <%@page import="com.cwai.pass.Md5"%> 8 <%@page import="com.cwai.dao.DBManager"%> 9 <%@page import="com.cwai.logic.bean.User"%> 10 <%@ page language="java" import="java.util.*,com.cwai.bean.*,com.cwai.xbean.*,com.cwai.ado.*" pageEncoding="UTF-8"%> 11 <% 12 String path = request.getContextPath(); if(null==session||session.getAttribute("LoginUser")==null){out.println("<script language='javascript'> function reLongin(){top.window.PAGE_FLAG = false;top.location='"+path+"/fail.jsp?ID=001'"+"}</script> ");out.println("<script language='javascript'> reLongin();</script> ");return;} 13 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 14 %> 15 <% 16 //代码种类 17 String dmzl=request.getParameter("DMZL")==null?"":request.getParameter("DMZL").toUpperCase(); 18 //查询代码 19 String v=request.getParameter("queryValue")==null?"":request.getParameter("queryValue"); 20 BaseDAO dao = null; 21 try{ 22 dao = new BaseDAO(); 23 if("GETQZXXID".equals(dmzl)){//根据userid获取签字信息ID 24 System.out.println("获取当前图片的比对结果_GETQZXXID:__________开始___________________"); 25 System.out.println("获取当前图片的比对结果_GETQZXXID:__________开始___________________"); 26 System.out.println("获取当前图片的比对结果_GETQZXXID:__________开始___________________"); 27 String qzxxid = dao.getValue("SELECT QZXX_ID FROM BM_USER_DZQZ T WHERE USERID = '"+v.trim()+"' AND SFYY = 1 AND DQYX = 1", new Object[]{}); 28 System.out.println("获取当前图片的比对结果_GETQZXXID:__________开始___________________"+qzxxid); 29 if("".equals(qzxxid) || null == qzxxid){ 30 out.println("0"); 31 }else{ 32 out.println(qzxxid.trim()); 33 } 34 }else if("SDKRESULT_OUT".equals(dmzl)){//根据用户ID获取线上拍照头像比对结果 35 System.out.println("获取当前图片的比对结果_out:__________开始___________________"); 36 String[] re = v.split("~"); 37 //获取当前图片的比对结果 38 String flag = SDKMatch.faceCompare(re[0], re[1]); 39 System.out.println("获取当前图片的比对结果_out——flag:_____________________________"+flag); 40 String rtn_data = "头像比对未通过!"; 41 if("OK".equals(flag)){ 42 rtn_data = "面部识别通过!"; 43 }else if("LIVE_NO".equals(flag)){ 44 rtn_data = "活体验证失败!"; 45 }else if("NO".equals(flag)){ 46 rtn_data = "面部识别未通过。未通过原因:非本人面部!"; 47 }else if("MAP_NO".equals(flag)){ 48 rtn_data = "未设置主头像,请密码登陆设置后,再次操作!"; 49 }else if("FACE_NO".equals(flag)){ 50 rtn_data = "面部识别未通过。未通过原因:拍摄时未对准面部!"; 51 } 52 System.out.println("获取当前图片的比对结果_out:_____________________结束____________________"); 53 out.print(flag+"~"+rtn_data); 54 } else if("SDKRESULT".equals(dmzl)){//根据用户ID获取线上拍照头像比对结果 55 System.out.println("获取当前图片的比对结果:_____________开始________________"); 56 String[] re = v.split("~"); 57 //获取当前图片的比对结果 58 String flag = SDKMatch.faceCompare(re[0], re[1]); 59 System.out.println("获取当前图片的比对结果:_____________________________"+flag); 60 String rtn_data = "头像比对未通过!"; 61 boolean ff = false; 62 if("OK".equals(flag)){ 63 ff = DBManager.execute(" UPDATE DD_SDKMESSAGE SET FINISH_TIME = SYSDATE ,STATUS = '4' WHERE ID = '" + re[2] + "' ", new String[]{}); 64 rtn_data = "面部识别通过!"; 65 }else if("LIVE_NO".equals(flag)){ 66 ff = DBManager.execute(" UPDATE DD_SDKMESSAGE SET FINISH_TIME = SYSDATE, STATUS = '5' WHERE ID = '" + re[2] + "' ", new String[]{}); 67 rtn_data = "活体验证失败!"; 68 }else if("NO".equals(flag)){ 69 ff = DBManager.execute(" UPDATE DD_SDKMESSAGE SET FINISH_TIME = SYSDATE, STATUS = '1' WHERE ID = '" + re[2] + "' ", new String[]{}); 70 rtn_data = "面部识别未通过。未通过原因:非本人面部!"; 71 }else if("MAP_NO".equals(flag)){ 72 rtn_data = "未设置主头像,请密码登陆设置后,再次操作!"; 73 }else if("FACE_NO".equals(flag)){ 74 rtn_data = "面部识别未通过。未通过原因:拍摄时未对准面部!"; 75 } 76 System.out.println("ff:_________________________________________"+ff); 77 out.print(flag+"~"+rtn_data); 78 }
注:1.getitems.jsp中内容仅作参考,根据项目要求来定
2.本项目使用的是百度AI版本2