fs-danaus
2023-06-26 2e5389660d216dabf6ebee15e7a3fa6eab73d01d
会话失效时websocket发送通知
11个文件已修改
168 ■■■■■ 已修改文件
WebRoot/general/loginOut.jsp 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WebRoot/js/index/WebSocketMessage.js 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WebRoot/js/loginSession.js 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WebRoot/js/selectedGrid/js/selectGrid.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WebRoot/sessionFail.jsp 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/action/grid/TreeGrid.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/action/login/LoginAction.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/listener/SessionListener.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/sdk/WebSocketMessage/api/messagelistener/WebSocketMessageListener.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/sdk/WebSocketMessage/entity/MessageType.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/sdk/shopping/action/Maintaince.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WebRoot/general/loginOut.jsp
@@ -2,6 +2,7 @@
<%
    //com.yc.listener.OnLineUser ou=new com.yc.listener.OnLineUser();
    //ou.deleteUser(session);
    session.setAttribute("isClose",true);//表示手动关闭会话,不需要websocket发送6017通知,避免出现重登录页面
    session.invalidate() ;
    response.sendRedirect("/default.jsp");
%>
WebRoot/js/index/WebSocketMessage.js
@@ -1,6 +1,7 @@
var wsOnTimers=null;
var layerMaintenanceIndex=null;
function initWebsocket(hostUrl,userCode,dbId,sessionId,userType) {
var reloginIndex=null;
function initWebsocket(hostUrl,userCode,dbId,sessionId,userType,isColseLayer) {
//  初始化weosocket
    var userFromType=1;
    if(userType!=undefined) userFromType=userType;
@@ -8,6 +9,7 @@
    var localUserCode = userCode ;
    var localDbId = dbId;
    var localSessionId = sessionId ;
    var colseLayer=isColseLayer;
    if(localUserCode==null||localUserCode==""||localUserCode=="null") localUserCode="temp_userCode_"+Math.random();
    if(localDbId==null||localDbId==""||localDbId=="null") localDbId=Math.floor(Math.random() * (10000 - 2000)) + 2000;
    if(localUserCode==null||localUserCode==""||localUserCode=="null") localUserCode="temp_session_"+Math.random();
@@ -22,6 +24,10 @@
            //console.log("onOpen-wsOnTimers:"+wsOnTimers);
            clearInterval(wsOnTimers);
            wsOnTimers=null;
        }
        if(colseLayer==true){
            var index = parent.layer.getFrameIndex(window.name); //先得到当前iframe层的索引
            parent.layer.close(index); //再执行关闭
        }
      }
@@ -72,6 +78,23 @@
                    }
                });
            }else if(json.info.msgType==6017){
                if(reloginIndex==null) {
                    reloginIndex = layui.layer.open({
                        type: 2,
                        area: ['400px', '200px'],
                        closeBtn: 0,
                        isOutAnim: false,
                        title: [json.info.msg, 'font-size:18px;text-align:center;padding:0px'],
                        resize: false,
                        fixed: false,
                        content: '/sessionFail.jsp?userCode=' + userCode,
                        move: false,
                        success: function (layero, index) {
                        }
                    });
                }
            }else if(json.info.msgType==6002){
                //右下角弹窗
                //console.log('接收消息', json);
@@ -99,7 +122,7 @@
                    layerMaintenanceIndex=null;
                }
            }
         // console.log('接收消息', json);
          //console.log('接收消息', json);
      }
}
var popflag=false;
WebRoot/js/loginSession.js
@@ -1,15 +1,16 @@
$(function() {
          $("#usercode").focus();
        $("#login").click(function(e){
jQuery(function() {
          jQuery("#usercode").focus();
        jQuery("#login").click(function(e){
            jQuery(this).linkbutton('disable');
            login();
        });
        $("#usercode").keydown(function(e){
        jQuery("#usercode").keydown(function(e){
            var e=e||window.event;
            if(e.keyCode==13){//回车键
                $("#password").focus();
                jQuery("#password").focus();
            }    
        });
        $("#password").keydown(function(e){
        jQuery("#password").keydown(function(e){
            var e=e||window.event;
            if(e.keyCode==13){//回车键
                login();
@@ -19,18 +20,18 @@
function login(){
    var temp="";
    if($("#usercode").val()=="") temp+="请输入账号\n";
    if($("#password").val()=="") temp+="请输入账号密码\n";
    if(jQuery("#usercode").val()=="") temp+="请输入账号\n";
    if(jQuery("#password").val()=="") temp+="请输入账号密码\n";
    
    if($("#usercode").val()!=""&&$("#password").val()!=""){
        $("#dbid").val($.cookie("dbid"));
        $("#dbstr").val($.cookie("dbstr"));
        //$("#loginForm").submit();
    if(jQuery("#usercode").val()!=""&&jQuery("#password").val()!=""){
        jQuery("#dbid").val(jQuery.cookie("dbid"));
        jQuery("#dbstr").val(jQuery.cookie("dbstr"));
        var encrypt = new JSEncrypt();
        encrypt.setPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkRupiYcKVGGUtDBDoR1t/1zm3ZtZgnte39iTJW6hlqjdY0UagKjpNiIv7J6XjtgfX7SgsR4AWnivqQHAICIvdPKfGZZzIs62OQ19MqrDTMoB/LvK5teNWhClv23WMUfRbP+EHgprT6hTw8U5apw1IB6i/y57NkLav792wiYBYRU4X45NoTaT+aiTSLFEflbfm94EXnhSS3vFkBmrZGy5BRNI8gmzafroslGx2Hk90CqlNdeKYxgZQ6xtvj+u33yrszWvPT6F9fsJT8aMjtvH050iYKRVct+x6Q7VRJgCI4MgvAexnTKdxW54YzvXCuO5bDiy5la7CgerWkTAq9dzXwIDAQAB");
        var encryptPwd = encrypt.encrypt($("#password").val());
        var encryptUser = encrypt.encrypt($("#usercode").val());
        $.ajax({
        var encryptPwd = encrypt.encrypt(jQuery("#password").val());
        var encryptUser = encrypt.encrypt(jQuery("#usercode").val());
        jQuery.ajax({
            type:"POST",
            url: "/againLogin.do",
            //contentType: "application/json", //如果提交的是json数据类型,则必须有此参数,表示提交的数据类型
@@ -38,27 +39,20 @@
            data:{
                "usercode":encryptUser,
                'password': encryptPwd,
                'dbid': $("#dbid").val(),
                'dbstr': $("#dbstr").val(),
                'domain': $("#domain").val()
                'dbid': jQuery("#dbid").val(),
                'dbstr': jQuery("#dbstr").val(),
                'domain': jQuery("#domain").val()
            },
            success: function (jsonResult) {
                if(jsonResult!=undefined &&jsonResult!=null){
                    var redirect="";
                    if(jsonResult.data!=undefined &&jsonResult.data!=""){
                        var json=JSON.parse(jsonResult.data);
                        redirect=json.redirect;
                    }
                    if(jsonResult.state==-1){//出错
                        alert(jsonResult.msg);
                    }else{
                        parent.deskTopHidden();
                        // var url=$("#hostUrl").val()+"/home.jsp";
                        // if(redirect!=""){
                        //     url+="?redirect="+redirect;
                        // }
                        // window.location.replace(url);
                        try {
                            parent.jQuery("#layui-layer-shade"+parent.reloginIndex).hide();
                            parent.jQuery("#layui-layer"+parent.reloginIndex).hide();
                            parent.reloginIndex=null;
                        }catch (e) {}
                    }
                }
            },
@@ -66,5 +60,5 @@
                alert(data);
            }
        });
    }else{alert(temp);}
    }else{alert(temp);jQuery("#login").linkbutton('enable');}
}
WebRoot/js/selectedGrid/js/selectGrid.js
@@ -128,10 +128,11 @@
           var parm=selectGridRowsDom.selectFields.split(";");
           var tempTile={};
           var num=selectGridRowsDom.getFieldsLength(parm);
           if(num<4){
            num=8;
           var width=(num+1)*100;
           if(width<800){
            width=800;
           }
           var htmlTitle='<ul class="selected-list-th flex-row"  style="width:'+num*100+'px;"><li class="selected-list-tr">操作</li>';
           var htmlTitle='<ul class="selected-list-th flex-row"  style="width:'+width+'px;"><li class="selected-list-tr">操作</li>';
           for(var i=0;i<parm.length;i++){
            if(grid.Cols[parm[i]]!=undefined&&grid.Cols[parm[i]].Visible!=undefined&&grid.Cols[parm[i]].Visible==0) continue;
            if(tempTile[parm[i]]!=undefined) continue;
@@ -147,8 +148,9 @@
         var html = '';
         var parm=selectGridRowsDom.selectFields.split(";");
         var num=selectGridRowsDom.getFieldsLength(parm);
         if(num<4){
            num=8;
         var width=(num+1)*100;
           if(width<800){
            width=800;
           }
         var gt=selectGridRowsDom.refGrid;
         var pkey=gt.primeKey.split(";");//表格的主键
@@ -165,7 +167,7 @@
               }
           }
             html += '<li class="selected-list-tr selected-list-data-item">' +
                 '<ul class="selected-list-ul flex-row" style="width:'+num*100+'px;margin:0;">' +
                 '<ul class="selected-list-ul flex-row" style="width:'+width+'px;margin:0;">' +
                 '<li class="selected-list-tr pointer smark deleteTableRow" data-index="' +
                 pkObj + '">[取消]</li>'
                 var tempTile={};
WebRoot/sessionFail.jsp
@@ -1,6 +1,5 @@
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@page import="com.yc.utils.SessionKey"%>
<%@page import="com.yc.multiData.MultiDataSource"%>
<%@page import="com.yc.entity.DataSourceEntity"%>
<%@page import="java.util.List"%>
@@ -23,17 +22,14 @@
<link rel="stylesheet" type="text/css" href="<%=hostUrl%>/style/commons.css?v=<%=com.yc.utils.FileUtil.getVerstion(request,"/style/commons.css")%>">
<link rel="stylesheet" type="text/css" href="<%=hostUrl%>/style/icon.css?v=<%=com.yc.utils.FileUtil.getVerstion(request,"/style/icon.css")%>">
<link rel="stylesheet" type="text/css" href="<%=hostUrl%>/style/default/easyui.css?v=<%=com.yc.utils.FileUtil.getVerstion(request,"/style/default/easyui.css")%>">
<script type="text/javascript" src="<%=hostUrl%>/js/jquery-1.4.4.min.js?v=<%=com.yc.utils.FileUtil.getVerstion(request,"/js/jquery-1.4.4.min.js")%>"></script>
<script type="text/javascript" src="<%=hostUrl%>/js/index/jquery.easyui.min.js?v=<%=com.yc.utils.FileUtil.getVerstion(request,"/js/index/jquery.easyui.min.js")%>"></script>
   <script type="text/javascript" src="/shopping/view/javascript/gotop/js/jquery-1.10.2.min.js?v=<%=com.yc.utils.FileUtil.getVerstion(request,"/shopping/view/javascript/gotop/js/jquery-1.10.2.min.js")%>"></script>
    <script type="text/javascript" src="<%=hostUrl%>/js/index/jquery.easyui.min.js?v=<%=com.yc.utils.FileUtil.getVerstion(request,"/js/index/jquery.easyui.min.js")%>"></script>
<script type="text/javascript" src="<%=hostUrl%>/js/jquery.cookie.min.js?v=<%=com.yc.utils.FileUtil.getVerstion(request,"/js/jquery.cookie.min.js")%>"></script>
<script type="text/javascript" src="<%=hostUrl%>/js/loginSession.js?v=<%=com.yc.utils.FileUtil.getVerstion(request,"/js/loginSession.js")%>"></script>
<script src="<%=hostUrl%>/js/jsencrypt.min.js?v=<%=com.yc.utils.FileUtil.getVerstion(request,"/js/jsencrypt.min.js")%>" type="text/javascript" ></script>
    <script type="text/javascript" src="<%=hostUrl%>/js/loginSession.js?v=<%=com.yc.utils.FileUtil.getVerstion(request,"/js/loginSession.js")%>"></script>
</head>
<body>
    <div class="easyui-layout" fit="true">
         <div region="north" border="false" style="padding-top:15px;padding-bottom:15px;text-align:center;background:#fff;">
              <span>您有太长时间没有操作了,请重新登录!</span>
         </div>
        <div region="center" border="false" style="overflow:hidden;text-align:center;padding-top:25px;background:#fff;border:1px solid #ccc;">
       
<%--        <form id="loginForm" method="post" action="/againLogin.do">--%>
src/com/yc/action/grid/TreeGrid.java
@@ -325,7 +325,7 @@
        } finally {
            SpObserver.setDBtoInstance();
        }
        if(keys!=null) {
        if(keys!=null&&keys.size()>0) {
            for (String str : keys) {
                if ("".equals(dto.field))
                    dto.field += str;
@@ -333,6 +333,9 @@
                    dto.field += ";" + str;
            }
        }
        /*else {
            throw new ApplicationException("由于表名称是函数或视图获取不到主键,请到9807设置表关键字");
        }*/
        dto.primeKey = dto.field;
    }
src/com/yc/action/login/LoginAction.java
@@ -17,6 +17,7 @@
import com.yc.exception.CallBackMessage;
import com.yc.factory.FactoryBean;
import com.yc.factory.InitSystem;
import com.yc.im.util.RedisSocket;
import com.yc.jpush.JpushAction;
import com.yc.listener.SessionListener;
import com.yc.multiData.MultiDataSource;
@@ -25,6 +26,7 @@
import com.yc.sdk.WebSocketMessage.action.WebSocketMessageServer;
import com.yc.sdk.WebSocketMessage.entity.MessageInfo;
import com.yc.sdk.WebSocketMessage.entity.MessageType;
import com.yc.sdk.WebSocketMessage.entity.WsMessageUserEntity;
import com.yc.sdk.gaodemap.action.GdMapServiceInit;
import com.yc.sdk.gaodemap.api.GdMapService;
import com.yc.sdk.gaodemap.entity.GdErrorException;
@@ -1431,8 +1433,36 @@
            } catch (Exception ex) {
                this.print2(response, ex.getMessage(), request.getParameter("redirect"), isApp);
            }
            if (isApp) {
                session.setAttribute(SessionKey.USER_LOGIN_TYPE, SessionKey.USER_LOGIN_TYPE_APP);//app 类型
                //判断当前登录设备是否与最新一次登录设备是一样,不一样需要返回给前端,输出短信进行验证登录
            } else {
                session.setAttribute(SessionKey.USER_LOGIN_TYPE, SessionKey.USER_LOGIN_TYPE_WEB);//web 类型
            }
            final DataSourceEntity dataSourceMap = MultiDataSource.getDataSourceMap(dbid);
            //---------------------------------
            if(dataSourceMap.isLoginOnceForOneUserCode()) {
                //限制多设备登录
                this.singleAccount(isApp ? "2" : "1", dbid, userAccount, request);
            }
            // 设置权限
            processLoginUserToSessionV2(ip, dbid, request, userAccount);
            //把新会话id替换websocket中对应用户的会话id,
            //--同一用户重新连接,如果存在已有会话是打开状态,则删除这个会话,启用新会话
            if(WebSocketMessageServer.getOnlineUserList()!=null&&WebSocketMessageServer.getOnlineUserList().size()>0) {
                String key = RedisSocket.CHANEL_WS_MESSAGES + ":" + dbid + ":1:" + usercode + ":";
                for (Map.Entry<String, WsMessageUserEntity> entry : WebSocketMessageServer.getOnlineUserList().entrySet()) {
                    if (entry.getKey().contains(key)) {
                        if (entry.getValue().getSession().isOpen()) {
                            WsMessageUserEntity wsMessageUser= entry.getValue();
                            wsMessageUser.setSessionId(session.getId());
                            WebSocketMessageServer.getOnlineUserList().put(key+session.getId(),wsMessageUser);
                            break;
                        }
                    }
                }
            }
            callBackMessage.sendSuccessMessage("登录成功");
            this.printJson(response, callBackMessage.toString());
            return null;
src/com/yc/listener/SessionListener.java
@@ -20,6 +20,10 @@
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import com.alibaba.fastjson.JSON;
import com.yc.sdk.WebSocketMessage.action.WebSocketMessageServer;
import com.yc.sdk.WebSocketMessage.entity.MessageInfo;
import com.yc.sdk.WebSocketMessage.entity.MessageType;
import com.yc.sdk.shopping.action.api.InvitationCode;
import org.apache.catalina.Manager;
import org.apache.catalina.Session;
@@ -674,13 +678,21 @@
            InitLicense.getInstance().pusSessionCount();//给加密狗用,作为单个客户计数使用
            HttpSession session = event.getSession();
            String sessionId = session.getId();
            String dbId = getDatabaseId(session) ;
            if(dbId!=null&&!"".equals(dbId)){
            if(dbId!=null&&!"".equals(dbId)&&session.getAttribute("isClose")==null){//session.getAttribute("isClose")表示手动退出系统
                try{
                    SpObserver.setDBtoInstance("_"+dbId);
                    UserAccountServiceIfc userAccountServiceIfc = (UserAccountServiceIfc)FactoryBean.getBean("UserAccountServiceImpl");
                    userAccountServiceIfc.doQuitLog(sessionId);   //更新 _sysloginlog 日志表
                    //发送会话失效通知
                    MessageInfo messageInfo = new MessageInfo();
                    messageInfo.setDbId(Integer.parseInt(dbId));
                    messageInfo.setMsgType(MessageType.RELOGIN_PAGE);
                    messageInfo.setUserFromType(session.getAttribute(SessionKey.USER_LOGIN_TYPE)+"");
                    messageInfo.setUserCode(session.getAttribute(SessionKey.USERCODE)+"");
                    messageInfo.setSessionId(sessionId);
                    messageInfo.setMsg("您已太长时间没有操作,请重新登录");
                    WebSocketMessageServer.publishMessageToRedis(messageInfo);
                }catch (Exception e) {
                    e.printStackTrace();
                }finally {
src/com/yc/sdk/WebSocketMessage/api/messagelistener/WebSocketMessageListener.java
@@ -135,6 +135,7 @@
                    messageIfc = versionMessageIfc;
                    break;
                case 6016:   //关闭同一账号在其他设备登录
                case 6017:   //关闭同一账号在其他设备登录
                    messageIfc = singleAccountMessageIfc;
                    break;
                default:
src/com/yc/sdk/WebSocketMessage/entity/MessageType.java
@@ -17,6 +17,7 @@
    public final static Integer NOTICE_SYSTEM_STOP =6014;   //通知web端和APP端关闭系统,返回登录界面
    public final static Integer NOTICE_SYSTEM_START =6015;   //通知web端和APP端启用系统,刷新登录界面
    public final static Integer RETURN_LOGIN_PAGE =6016;   //通知web端,APP端退出系统,返回登录界面
    public final static Integer RELOGIN_PAGE =6017;   //通知web端,APP端会话已失效,在当前页面弹出登录界面
    public final static Integer MAINTENANCE_SYSTEM =6999;   //表示当前连接的应用是在维护系统,需要弹出显示维护页面告之客户
    public final static Integer NORMAL_SYSTEM =6998;   //表示当前连接的应用是正常使用的系统,需要关闭之前弹出的显示维护页面
src/com/yc/sdk/shopping/action/Maintaince.java
@@ -190,6 +190,7 @@
            Map<String,DataSourceEntity> dataSourceMap = MultiDataSource.getDataSourceMapsByHostAndPort() ;
            for (Map.Entry<String, DataSourceEntity> entry : dataSourceMap.entrySet()) {
                DataSourceEntity dataSourceEntity = entry.getValue();
                if(dataSourceEntity.isExpiredDate()) continue;//过期跳过处理 by danaus 2023-06-19 15:37
                if (dataSourceEntity.getDbId() == 148) continue ;   //如果是苏州科勒,则跳过
                
                Map<String,DatabaseEntity> dbDataSizeList = null ;  
@@ -254,9 +255,9 @@
            }
            DataSourceEntity dataSourceEntity = MultiDataSource.getDataSourceMap( request) ;
            try {
                //AsynchronousExecution.doRefreshUri(hostUrl,"/SyncDataSource.do", "");  //doRefreshDataSource();
                InvGet.refreshDataSource(dataSourceEntity.getDbId()+"",DataSourceActionEntity.ActionEnum.REFRESH);  //直接刷新本机
            if(!dataSourceEntity.isExpiredDate()) {//没过期才需要执行 by danaus 2023-06-19 15:38
                InvGet.refreshDataSource(dataSourceEntity.getDbId() + "", DataSourceActionEntity.ActionEnum.REFRESH);  //直接刷新本机
            }
            }catch(Exception e) {
                e.printStackTrace();
                json.addProperty("error", e.getCause()!= null?e.getCause().getMessage(): e.getMessage());