xinyb_
2022-02-18 9eb57fa535820b880703f9b543c78cad61c3e3cf
调整PC端扫码登录功能
5个文件已添加
8个文件已修改
743 ■■■■ 已修改文件
WebRoot/WEB-INF/lib/expiringmap-0.5.10.jar 补丁 | 查看 | 原始文档 | blame | 历史
WebRoot/js/index/WebSocketqrLogin.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WebRoot/js/loginValidate.js 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/phoneQRLogin/action/LoginQRCode.java 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/phoneQRLogin/action/LoginQRCodeWS.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/phoneQRLogin/action/WebSocketqrCode.java 290 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/phoneQRLogin/action/verification.java 45 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/phoneQRLogin/entity/QrCodeToken.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/phoneQRLogin/listener/LoginQRCodeListener.java 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/phoneQRLogin/listener/WebSocketqrCodeInvalidListener.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/phoneQRLogin/listener/WebSocketqrCodeListener.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/com/yc/phoneQRLogin/utils/BackMsg.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/spring-redis.xml 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
WebRoot/WEB-INF/lib/expiringmap-0.5.10.jar
Binary files differ
WebRoot/js/index/WebSocketqrLogin.js
@@ -24,9 +24,9 @@
                break;
            case "2":
                // 登录
                setTimeout(function(){
                // setTimeout(function(){
                    window.location.href= $("#hostUrl").val() + "/home.jsp";
                }, 1000);
                // }, 1000);
                break;
            case "3":
                console.log(a.msg);
WebRoot/js/loginValidate.js
@@ -335,12 +335,12 @@
        //生成二维码图片
        this.createqrCode=function(){
            $(".qrcode-error").hide(); 
            $.post("/ws/qrCode.do?appId="+select.value,function(data){
                if(data!=null && data.qrcode!=null){
                    $(".qrcode-logins").find("img").attr("src",data.url);
                    initWebSocket(hostUrl+"/ws/qrLogin/"+select.value+"/"+data.qrcode+"/0");
            $.post("/ws/qrCode.do?appId="+select.value,function(res){
                if(res!=null && res.code==0){
                    $(".qrcode-logins").find("img").attr("src",res.data.url);
                    initWebSocket(hostUrl+"/ws/qrLogin/"+select.value+"/"+res.data.qrcode+"/0");
                }else{
                    alert(data.msg);
                    alert(res.msg);
                    webSocket=-1;
                }                
            },"json").error(function(e){
src/com/yc/phoneQRLogin/action/LoginQRCode.java
New file
@@ -0,0 +1,100 @@
package com.yc.phoneQRLogin.action;
import com.yc.action.grid.GridUtils;;
import com.yc.action.login.TokenInfo;
import com.yc.factory.FactoryBean;
import com.yc.im.service.RedisDAO;
import com.yc.multiData.SpObserver;
import com.yc.phoneQRLogin.entity.QrCodeToken;
import com.yc.phoneQRLogin.utils.BackMsg;
import com.yc.sdk.shopping.action.api.GenerationQrCodeForApp;
import com.yc.sdk.shopping.action.api.InvitationCode;
import com.yc.sdk.shopping.entity.QrCodeForAppEntity;
import com.yc.sdk.shopping.service.imagedata.ShoppingImageDataIfc;
import com.yc.utils.AESUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
 * @USER: xinyb_
 * @DATE: 2022-01-15 10:49
 */
@RestController
public class LoginQRCode {
    @Autowired
    ShoppingImageDataIfc imgData;
    @Autowired
    RedisDAO redisDAO;
    public static Map<String, HttpSession> sessionMapMap = new HashMap<>();
    public static Map<String,HttpServletResponse> responseMap=new HashMap<>();
    /**
     * 生成系统登录用的二维码 xin 2022-1-15 10:58:37
     *
     * @param appId
     * @param request
     * @return
     */
    @RequestMapping("/ws/qrCode.do")
    public BackMsg getLoginQRCode(String appId, HttpServletRequest request,HttpServletResponse response) {
        BackMsg msg = new BackMsg();
        try {
            SpObserver.setDBtoInstance("_" + appId);
            QrCodeForAppEntity qrCodeForAppEntity = new QrCodeForAppEntity();
            qrCodeForAppEntity.setAction(QrCodeForAppEntity.Login); // 设置行为 Action
            qrCodeForAppEntity.setAuthorCode("SYSTEM");
            qrCodeForAppEntity.setAuthorName("系统管理员");
            qrCodeForAppEntity = GenerationQrCodeForApp.saveQrCodeForApp(qrCodeForAppEntity, false);
            String url = imgData.getImageUrl(qrCodeForAppEntity.getQrCodeUnid(), 250, 250, true, false, request);
            Map<String, String> map = new HashMap<>();
            map.put("qrcode", qrCodeForAppEntity.getQrCode());
            map.put("url", url);
            msg.setOk(map);
            sessionMapMap.put(qrCodeForAppEntity.getQrCode(), request.getSession());//当前登录的session对象
        } catch (Exception e) {
            msg.setFail(e.getCause() != null ? e.getCause().getMessage() : e.getMessage());
        } finally {
            SpObserver.setDBtoInstance();
        }
        return msg;
    }
    @RequestMapping("/ws/qrLoginToken.do")
    public void getLoginToken(@RequestBody QrCodeToken token, HttpServletResponse response) throws InterruptedException {
        responseMap.put(token.getQrCode(),response);
//        token.setToken(genToken("666666","15918137189",82));
        redisDAO.publishMessage("Onbus_Qrcode", GridUtils.toJsonNotNull(token));
        Thread.sleep(1000);//沉睡1秒
    }
    //测试模拟值
    public String genToken(String pwd,String usercode,int dbid) {
        TokenInfo tokenInfo=new TokenInfo();
        tokenInfo.setUsercode(usercode);
        tokenInfo.setDbid(dbid);
        double rand=new Random().nextDouble();
        tokenInfo.setRand(rand);//增加随机数,以便用于生成不同的token
        try {
            //格式dbid:usercode
            String key = InvitationCode.TOKEN_STR+tokenInfo.getDbid() + ":" + tokenInfo.getUsercode();
            RedisTemplate redisTemplate = (RedisTemplate) FactoryBean.getBean("redisTemplate");
            final int OVERTIME = 12;//12小时过期,时间限制
            redisTemplate.opsForValue().set(key, pwd+"#"+rand,OVERTIME, TimeUnit.HOURS);
            String token= AESUtils.encrypt(GridUtils.toJson(tokenInfo));//dbid+usercode加密返回给APP客户端保存
            return  token;
        }catch(Exception ex){
            ex.printStackTrace();
            return "";
        }
    }
}
src/com/yc/phoneQRLogin/action/LoginQRCodeWS.java
New file
@@ -0,0 +1,73 @@
package com.yc.phoneQRLogin.action;
import com.yc.action.grid.GridUtils;
import com.yc.factory.FactoryBean;
import com.yc.im.service.RedisDAO;
import com.yc.phoneQRLogin.entity.QrCodeToken;
import net.jodah.expiringmap.ExpirationPolicy;
import net.jodah.expiringmap.ExpiringMap;
import org.springframework.web.bind.annotation.RestController;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
 * @USER: xinyb_
 * @DATE: 2022-01-15 11:03
 */
@RestController
@ServerEndpoint("/ws/qrLogin/{dbId}/{qrCode}/{state}")
public class LoginQRCodeWS {
    public static ExpiringMap<String, String> exMap = null;
    private static RedisDAO redisDao = null;
    public static Map<String,Map<String,Object>> pullMap=new HashMap<>();
    static {
        redisDao = (RedisDAO) FactoryBean.getBean("redisDAO");
        //创建ExpiringMap,最大容量:100,有效时间:60秒。
        exMap = ExpiringMap.builder().maxSize(100).expiration(60, TimeUnit.SECONDS)
                .variableExpiration().expirationListener((key, value) -> {
                    //监听过期处理
                    beOverdue((String) key,(String) value);
                }).expirationPolicy(ExpirationPolicy.CREATED).build();
    }
    /***
     * 打开连接
     */
    @OnOpen
    public void onOpen(@PathParam("dbId") String dbId, @PathParam("qrCode") String qrCode,
                       @PathParam("state") int state, Session session) {
        Map<String, Object> map = new HashMap<>();
        map.put("session", session);
        map.put("dbId", dbId);
        pullMap.put(qrCode, map);
        exMap.put(qrCode,dbId);
    }
    /**
     * 断开连接
     */
    @OnClose
    public void onClose(@PathParam("dbId") String dbId,@PathParam("qrCode") String qrCode, Session session) {
        beOverdue(qrCode,dbId);
    }
    /**
     * 过期处理
     * @param qrCode
     */
    private static void beOverdue(String qrCode,String dbId) {
        QrCodeToken token = new QrCodeToken();
        token.setType(-1);
        token.setQrCode(qrCode);
        token.setDbId(dbId);
        redisDao.publishMessage("Onbus_Qrcode", GridUtils.toJson(token));
    }
}
src/com/yc/phoneQRLogin/action/WebSocketqrCode.java
@@ -25,154 +25,154 @@
import com.yc.phoneQRLogin.entity.QrCodeToken;
import com.yc.phoneQRLogin.entity.WebSession;
import net.sf.json.JSONObject;
@RestController
@ServerEndpoint(value = "/ws/qrLogin/{dbId}/{qrCode}/{state}", configurator = HttpSessionConfigurator.class)
//
//@RestController
//@ServerEndpoint(value = "/ws/qrLogin/{dbId}/{qrCode}/{state}", configurator = HttpSessionConfigurator.class)
public class WebSocketqrCode {
    private static Map<String, List<WebSession>> clients = new ConcurrentHashMap<String, List<WebSession>>();
    protected static String WS_ONBUS_QRCODE = "Onbus_Qrcode";// 二维码频道名称
    /***
     * 打开连接
     *
     * @throws Exception
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    @OnOpen
    public void onOpen(@PathParam("dbId") String dbId, @PathParam("qrCode") String qrCode,
            @PathParam("state") int state, Session session, EndpointConfig config) {
        RedisTemplate redis = (RedisTemplate) FactoryBean.getBean("redisTemplate");
        CallBackMessage callBackMessage = new CallBackMessage();
        try {
            // 不存在则过期
            if (!redis.hasKey(qrCode)) {
                session.getAsyncRemote().sendText(new CallBackMessage().sendErrorMessage("二维码已失效!"));
                return;
            }
            if (!Objects.equals(redis.opsForValue().get("DBID" + qrCode), dbId)) {
                session.getAsyncRemote().sendText(new CallBackMessage().sendErrorMessage("不是本系统的登录二维码!"));
                return;
            }
            if (Objects.equals(redis.opsForValue().get("STATE" + qrCode), 1)) {
                session.getAsyncRemote().sendText(new CallBackMessage().sendErrorMessage("二维码已失效!"));
                return;
            }
            HttpSession httpSession = null;
            if (state == 0) {// 网页端进入
                httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
            }
            WebSession webSession = new WebSession(session, httpSession, dbId, qrCode);
            List<WebSession> list = clients.get(qrCode);
            if (list == null) {
                list = new ArrayList<WebSession>();
            }
            list.add(webSession);
            clients.put(qrCode, list);
            if (state == 0) {
                callBackMessage.setData("3");
                session.getAsyncRemote().sendText(callBackMessage.sendSuccessMessage("二维码已生成"));
                return;
            }
            if (state == 1) {
                redis.opsForValue().set("STATE" + qrCode, 1);// 二维码当前扫码
                redis.expire(qrCode, 60, TimeUnit.SECONDS);
                qrCodeRedis(new QrCodeToken(state, qrCode));
            }
        } catch (Exception e) {
            session.getAsyncRemote().sendText(new CallBackMessage()
                    .sendErrorMessage(e.getCause() != null ? e.getCause().getMessage() : e.getMessage()));
        }
    }
    /**
     * 断开连接
     *
     * @param dbid
     * @param userCode
     */
    @OnClose
    public void onClose(@PathParam("qrCode") String qrCode, Session session) {
        // 断开连接后删除此连接clients的key
        if (clients.get(qrCode) == null || clients.get(qrCode).size() == 0) {
            return;
        }
        for(WebSession s : clients.get(qrCode)) {
            if(s.getSession().getId().equals(session.getId())) {
                qrCodeRedis(new QrCodeToken(-1, qrCode));
                break;
            }
        }
    }
    /**
     * 接收APP端信息
     *
     * @param message
     * @param session
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    @OnMessage
    public void onMessage(Session session, String message) {
        try {
            JSONObject json = JSONObject.fromObject(message.replace(" ",""));
            String qrCode = json.getString("qrCode");
            String token = json.getString("token");
            // 查看写入redis的key,不存在则表示二维码已失效。
            @SuppressWarnings("rawtypes")
            RedisTemplate redis = (RedisTemplate) FactoryBean.getBean("redisTemplate");
            if (!redis.hasKey(qrCode)) {
                if (session.isOpen()) {
                    session.getAsyncRemote().sendText(new CallBackMessage().sendErrorMessage("二维码已失效!"));
                }
                return;
            }
            // 处理接收到token信息。
//            handleMessage(qrCode, token,session);
            qrCodeRedis(new QrCodeToken(2, qrCode, token));
        } catch (Exception e) {
            session.getAsyncRemote().sendText((e.getCause() != null ? e.getCause().getMessage() : e.getMessage()));
        }
    }
    /**
     * 发生错误的信息
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }
    /**
     * 获取指定的qrCode集合
     *
     * @param qrCode
     * @return
     */
//    private static Map<String, List<WebSession>> clients = new ConcurrentHashMap<String, List<WebSession>>();
//    protected static String WS_ONBUS_QRCODE = "Onbus_Qrcode";// 二维码频道名称
//
//    /***
//     * 打开连接
//     *
//     * @throws Exception
//     */
//    @SuppressWarnings({ "unchecked", "rawtypes" })
//    @OnOpen
//    public void onOpen(@PathParam("dbId") String dbId, @PathParam("qrCode") String qrCode,
//            @PathParam("state") int state, Session session, EndpointConfig config) {
//        RedisTemplate redis = (RedisTemplate) FactoryBean.getBean("redisTemplate");
//        CallBackMessage callBackMessage = new CallBackMessage();
//        try {
//            // 不存在则过期
//            if (!redis.hasKey(qrCode)) {
//                session.getAsyncRemote().sendText(new CallBackMessage().sendErrorMessage("二维码已失效!"));
//                return;
//            }
//            if (!Objects.equals(redis.opsForValue().get("DBID" + qrCode), dbId)) {
//                session.getAsyncRemote().sendText(new CallBackMessage().sendErrorMessage("不是本系统的登录二维码!"));
//                return;
//            }
//            if (Objects.equals(redis.opsForValue().get("STATE" + qrCode), 1)) {
//                session.getAsyncRemote().sendText(new CallBackMessage().sendErrorMessage("二维码已失效!"));
//                return;
//            }
//            HttpSession httpSession = null;
//            if (state == 0) {// 网页端进入
//                httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
//            }
//            WebSession webSession = new WebSession(session, httpSession, dbId, qrCode);
//            List<WebSession> list = clients.get(qrCode);
//            if (list == null) {
//                list = new ArrayList<WebSession>();
//            }
//            list.add(webSession);
//            clients.put(qrCode, list);
//            if (state == 0) {
//                callBackMessage.setData("3");
//                session.getAsyncRemote().sendText(callBackMessage.sendSuccessMessage("二维码已生成"));
//                return;
//            }
//            if (state == 1) {
//                redis.opsForValue().set("STATE" + qrCode, 1);// 二维码当前扫码
//                redis.expire(qrCode, 60, TimeUnit.SECONDS);
//                qrCodeRedis(new QrCodeToken(state, qrCode));
//            }
//        } catch (Exception e) {
//            session.getAsyncRemote().sendText(new CallBackMessage()
//                    .sendErrorMessage(e.getCause() != null ? e.getCause().getMessage() : e.getMessage()));
//        }
//    }
//
//    /**
//     * 断开连接
//     *
//     * @param dbid
//     * @param userCode
//     */
//    @OnClose
//    public void onClose(@PathParam("qrCode") String qrCode, Session session) {
//        // 断开连接后删除此连接clients的key
//        if (clients.get(qrCode) == null || clients.get(qrCode).size() == 0) {
//            return;
//        }
//        for(WebSession s : clients.get(qrCode)) {
//            if(s.getSession().getId().equals(session.getId())) {
//                qrCodeRedis(new QrCodeToken(-1, qrCode));
//                break;
//            }
//        }
//    }
//
//    /**
//     * 接收APP端信息
//     *
//     * @param message
//     * @param session
//     * @throws Exception
//     */
//    @SuppressWarnings("unchecked")
//    @OnMessage
//    public void onMessage(Session session, String message) {
//        try {
//            JSONObject json = JSONObject.fromObject(message.replace(" ",""));
//            String qrCode = json.getString("qrCode");
//            String token = json.getString("token");
//            // 查看写入redis的key,不存在则表示二维码已失效。
//            @SuppressWarnings("rawtypes")
//            RedisTemplate redis = (RedisTemplate) FactoryBean.getBean("redisTemplate");
//            if (!redis.hasKey(qrCode)) {
//                if (session.isOpen()) {
//                    session.getAsyncRemote().sendText(new CallBackMessage().sendErrorMessage("二维码已失效!"));
//                }
//                return;
//            }
//            // 处理接收到token信息。
////            handleMessage(qrCode, token,session);
//            qrCodeRedis(new QrCodeToken(2, qrCode, token));
//        } catch (Exception e) {
//            session.getAsyncRemote().sendText((e.getCause() != null ? e.getCause().getMessage() : e.getMessage()));
//        }
//    }
//
//    /**
//     * 发生错误的信息
//     *
//     * @param session
//     * @param error
//     */
//    @OnError
//    public void onError(Session session, Throwable error) {
//        error.printStackTrace();
//    }
//
//    /**
//     * 获取指定的qrCode集合
//     *
//     * @param qrCode
//     * @return
//     */
    public static List<WebSession> getListWebSession(String qrCode) {
        return clients.get(qrCode);
        return null;//clients.get(qrCode);
    }
    /**
     * 删除clients
     *
     * @param qrCode
     */
//
//    /**
//     * 删除clients
//     *
//     * @param qrCode
//     */
    public static void deletListWebSession(String qrCode) {
        clients.remove(qrCode);
//        clients.remove(qrCode);
    }
    /**
     * 发布订阅消息
     *
     * @param session
     */
    public static void qrCodeRedis(QrCodeToken token) {
        // 发送消息
        RedisDAO redisDAO = (RedisDAO) FactoryBean.getBean("redisDAO");
        redisDAO.publishMessage(WebSocketqrCode.WS_ONBUS_QRCODE, GridUtils.toJsonNotNull(token));
    }
//
//    /**
//     * 发布订阅消息
//     *
//     * @param session
//     */
//    public static void qrCodeRedis(QrCodeToken token) {
//        // 发送消息
//        RedisDAO redisDAO = (RedisDAO) FactoryBean.getBean("redisDAO");
//        redisDAO.publishMessage(WebSocketqrCode.WS_ONBUS_QRCODE, GridUtils.toJsonNotNull(token));
//    }
}
src/com/yc/phoneQRLogin/action/verification.java
@@ -176,29 +176,28 @@
    // 生成二维码图片
    @SuppressWarnings("unchecked")
    @RequestMapping("/ws/qrCode.do")
    public void getQeCode(String appId, HttpServletRequest request, HttpServletResponse response) throws Exception {
        try {
            SpObserver.setDBtoInstance("_" + appId);
            QrCodeForAppEntity qrCodeForAppEntity = new QrCodeForAppEntity();
            qrCodeForAppEntity.setAction(QrCodeForAppEntity.Login); // 设置行为 Action
            qrCodeForAppEntity.setAuthorCode("SYSTEM");
            qrCodeForAppEntity.setAuthorName("系统管理员");
            qrCodeForAppEntity = GenerationQrCodeForApp.saveQrCodeForApp(qrCodeForAppEntity, false);
            String url = imgData.getImageUrl(qrCodeForAppEntity.getQrCodeUnid(), 250, 250, true, false, request);
            // 写入一个key到redis,并且设置过期时间为60s
            redisTemplate.opsForValue().set(qrCodeForAppEntity.getQrCode(), qrCodeForAppEntity.getQrCode(), 60,
                    TimeUnit.SECONDS);
            redisTemplate.opsForValue().set("STATE" + qrCodeForAppEntity.getQrCode(), 0);// 二维码当前状态
            redisTemplate.opsForValue().set("DBID" + qrCodeForAppEntity.getQrCode(), appId);// 二维码当前数据源ID
            this.print(response, "{\"qrcode\":\"" + qrCodeForAppEntity.getQrCode() + "\",\"url\":\"" + url + "\"}");
        } catch (Exception e) {
            this.print(response, e.getCause() != null ? (e.getCause().getMessage()).trim() : e.getMessage());
        } finally {
            SpObserver.setDBtoInstance();
        }
    }
//    @RequestMapping("/ws/qrCode.do")
//    public void getQeCode(String appId, HttpServletRequest request, HttpServletResponse response) throws Exception {
//        try {
//            SpObserver.setDBtoInstance("_" + appId);
//            QrCodeForAppEntity qrCodeForAppEntity = new QrCodeForAppEntity();
//            qrCodeForAppEntity.setAction(QrCodeForAppEntity.Login); // 设置行为 Action
//            qrCodeForAppEntity.setAuthorCode("SYSTEM");
//            qrCodeForAppEntity.setAuthorName("系统管理员");
//            qrCodeForAppEntity = GenerationQrCodeForApp.saveQrCodeForApp(qrCodeForAppEntity, false);
//            String url = imgData.getImageUrl(qrCodeForAppEntity.getQrCodeUnid(), 250, 250, true, false, request);
//            // 写入一个key到redis,并且设置过期时间为60s
//            redisTemplate.opsForValue().set(qrCodeForAppEntity.getQrCode(), qrCodeForAppEntity.getQrCode(), 10,
//                    TimeUnit.SECONDS);
//            redisTemplate.opsForValue().set("STATE" + qrCodeForAppEntity.getQrCode(), 0);// 二维码当前状态
//            redisTemplate.opsForValue().set("DBID" + qrCodeForAppEntity.getQrCode(), appId);// 二维码当前数据源ID
//            this.print(response, "{\"qrcode\":\"" + qrCodeForAppEntity.getQrCode() + "\",\"url\":\"" + url + "\"}");
//        } catch (Exception e) {
//            this.print(response, e.getCause() != null ? (e.getCause().getMessage()).trim() : e.getMessage());
//        } finally {
//            SpObserver.setDBtoInstance();
//        }
//    }
    /**
     * 生成随机6位数
src/com/yc/phoneQRLogin/entity/QrCodeToken.java
@@ -4,21 +4,32 @@
    private int type;
    private String qrCode;
    private String token;
    private String dbId;
    public QrCodeToken() {
    }
    public QrCodeToken(int type, String qrCode) {
    public QrCodeToken(int type, String qrCode,String dbId) {
        super();
        this.type = type;
        this.qrCode = qrCode;
        this.dbId=dbId;
    }
    
    public QrCodeToken(int type, String qrCode, String token) {
    public QrCodeToken(int type, String qrCode, String token,String dbId) {
        super();
        this.type = type;
        this.qrCode = qrCode;
        this.token=token;
        this.dbId=dbId;
    }
    public String getDbId() {
        return dbId;
    }
    public void setDbId(String dbId) {
        this.dbId = dbId;
    }
    public int getType() {
src/com/yc/phoneQRLogin/listener/LoginQRCodeListener.java
New file
@@ -0,0 +1,155 @@
package com.yc.phoneQRLogin.listener;
import com.google.gson.Gson;
import com.yc.action.login.LoginAction;
import com.yc.action.login.TokenInfo;
import com.yc.entity.UserAccountEntity;
import com.yc.exception.CallBackMessage;
import com.yc.factory.FactoryBean;
import com.yc.multiData.SpObserver;
import com.yc.phoneQRLogin.action.LoginQRCode;
import com.yc.phoneQRLogin.action.LoginQRCodeWS;
import com.yc.phoneQRLogin.entity.QrCodeToken;
import com.yc.phoneQRLogin.service.WebSocketqrCodeIfc;
import com.yc.sdk.password.action.ChangePassword;
import com.yc.service.user.UserAccountServiceIfc;
import com.yc.utils.AESUtils;
import com.yc.utils.EncodeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.websocket.Session;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
/**
 * @USER: xinyb_
 * @DATE: 2022-01-15 11:27
 */
public class LoginQRCodeListener implements MessageListener {
    @Autowired
    WebSocketqrCodeIfc webSocketqrCodeIfc;
    @Autowired
    UserAccountServiceIfc userAccountService;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    public RedisTemplate<String, String> getRedisTemplate() {
        return redisTemplate;
    }
    public void setRedisTemplate(RedisTemplate<String, String> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }
    @Override
    public void onMessage(Message message, byte[] bytes) {
        try {
            RedisSerializer<?> serializer = redisTemplate.getValueSerializer();
            Object body = serializer.deserialize(message.getBody());
            QrCodeToken token = new Gson().fromJson(String.valueOf(body),
                    new com.google.gson.reflect.TypeToken<QrCodeToken>() {
                    }.getType());
            if (token != null) {
                CallBackMessage callBackMessage = new CallBackMessage();
                Map<String, Object> map = LoginQRCodeWS.pullMap.get(token.getQrCode());
                if (map == null) {
                    getRespone(token.getQrCode(), callBackMessage.sendErrorMessage("二维码已失效!"));
                    return;
                }
                Session session = (Session) map.get("session");//ws的session
                String dbId = (String) map.get("dbId");//PC登录的dbId;
                if (!dbId.equals(token.getDbId())) {//不是同一个系统dbId
                    getRespone(token.getQrCode(), callBackMessage.sendErrorMessage("不是本系统的登录二维码!"));
                    return;
                }
                switch (token.getType()) {
                    case 1://扫码通过
                        //返回信息给APP
                        getRespone(token.getQrCode(), callBackMessage.sendSuccessMessage("扫码成功"));
                        if (session != null && session.isOpen()) {
                            callBackMessage.setData("1");//PC端登录时候需要到
                            //返回信息给PC端
                            session.getAsyncRemote().sendText(callBackMessage.sendSuccessMessage("扫码成功!"));
                            //重置过期时间
                            LoginQRCodeWS.exMap.resetExpiration(token.getQrCode());
                        }
                        break;
                    case 2://认证保存
                        getToken(token, session);
                        break;
                    default://失效删除
                        webSocketqrCodeIfc.delExpireQrCode(token.getQrCode());
                        if (session != null && session.isOpen()) {
                            session.getAsyncRemote().sendText(callBackMessage.sendErrorMessage("二维码已失效"));
                        }
                        //返回信息给APP
                        getRespone(token.getQrCode(), callBackMessage.sendErrorMessage("二维码已失效"));
                        LoginQRCodeWS.pullMap.remove(token.getQrCode());
                        LoginQRCode.sessionMapMap.remove(token.getQrCode());
                        LoginQRCodeWS.exMap.remove(token.getQrCode());
                        break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private void getToken(QrCodeToken token, Session session) {
        try {
            HttpSession session1 = LoginQRCode.sessionMapMap.get(token.getQrCode());
            String value = AESUtils.decrypt(EncodeUtil.replaceUrlChar(token.getToken()));// 解密
            TokenInfo info = new Gson().fromJson(value, new com.google.gson.reflect.TypeToken<TokenInfo>() {
            }.getType());
            if (info.getUsercode() != null && info.getUsercode().length() > 30) {// 解密为明文
                info.setUsercode(ChangePassword.getDecryptPassword(EncodeUtil.replaceUrlChar(info.getUsercode())));
            }
            SpObserver.setDBtoInstance("_" + info.getDbid());
            UserAccountEntity userAccount = userAccountService.getUserInfoByTelephone(info.getUsercode());
            if (userAccount != null) {
                // 保存会话 session信息
                LoginAction loginAction = (LoginAction) FactoryBean.getBean("loginAction");
                boolean bol = loginAction.processLoginUserToSession("", info.getDbid() + "", session1,
                        userAccount);
                if (bol) {
                    CallBackMessage callBackMessage = new CallBackMessage();
                    //返回信息给APP
                    getRespone(token.getQrCode(), callBackMessage.sendSuccessMessage("登录成功!"));
                    if (session.isOpen()) {
                        callBackMessage.setData("2");//PC端登录时候需要到
                        session.getAsyncRemote().sendText(callBackMessage.sendSuccessMessage("登录成功!"));
                    }
                    LoginQRCodeWS.pullMap.remove(token.getQrCode());
                    LoginQRCode.sessionMapMap.remove(token.getQrCode());
                    LoginQRCodeWS.exMap.remove(token.getQrCode());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            SpObserver.setDBtoInstance();
        }
    }
    private void getRespone(String qrCode, String msg) throws IOException {
        HttpServletResponse response = LoginQRCode.responseMap.get(qrCode);
        if (response != null) {
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            PrintWriter out = response.getWriter();
            out.print(msg);
            out.close();
        }
        LoginQRCode.responseMap.remove(qrCode);
    }
}
src/com/yc/phoneQRLogin/listener/WebSocketqrCodeInvalidListener.java
@@ -10,7 +10,6 @@
public class WebSocketqrCodeInvalidListener implements MessageListener {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    public RedisTemplate<String, String> getRedisTemplate() {
        return redisTemplate;
    }
@@ -23,7 +22,7 @@
    public void onMessage(Message msg, byte[] arg1) {
        try {
            String qrCode = new String(msg.getBody());// 获取过期的qrCode
            WebSocketqrCode.qrCodeRedis(new QrCodeToken(-1, qrCode));
//            WebSocketqrCode.qrCodeRedis(new QrCodeToken(-1, qrCode));
        } catch (Exception e) {
            e.printStackTrace();
        }
src/com/yc/phoneQRLogin/listener/WebSocketqrCodeListener.java
@@ -103,12 +103,12 @@
                        if (s.getHttpSession() != null) {
                            // 保存会话 session信息
                            LoginAction loginAction = (LoginAction) FactoryBean.getBean("loginAction");
                            loginAction.processLoginUserToSession("", info.getDbid() + "", s.getHttpSession(),
                            boolean bol=loginAction.processLoginUserToSession("", info.getDbid() + "", s.getHttpSession(),
                                    userAccount);
                        }
                        if (s.getSession().isOpen()) {
                            callBackMessage.setData("2");
                            s.getSession().getAsyncRemote().sendText(callBackMessage.sendSuccessMessage("登录成功!"));
                            if (s.getSession().isOpen() && bol) {
                                callBackMessage.setData("2");
                                s.getSession().getAsyncRemote().sendText(callBackMessage.sendSuccessMessage("登录成功!"));
                            }
                        }
                    }
                }
@@ -123,7 +123,7 @@
    /**
     * 删除
     * 
     * @param session
     * @param token
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
src/com/yc/phoneQRLogin/utils/BackMsg.java
New file
@@ -0,0 +1,26 @@
package com.yc.phoneQRLogin.utils;
import lombok.Data;
/**
 * @USER: xinyb_
 * @DATE: 2022-01-15 10:50
 */
@Data
public class BackMsg {
    private Integer code;
    private String msg;
    private Object data;
    public void setOk(Object data){
        this.code=0;
        this.msg="操作成功!";
        this.data=data;
    }
    public void setFail(Object data){
        this.code=-1;
        this.msg="操作失败!";
        this.data=data;
    }
}
src/spring-redis.xml
@@ -90,13 +90,13 @@
        <property name="redisTemplate" ref="redisTemplate"/>
    </bean>
     <!-- 监听二维码订阅,并触发事件-->
    <bean id="listenerForQrCodeSession" class="com.yc.phoneQRLogin.listener.WebSocketqrCodeListener">
    <bean id="listenerForQrCodeSession" class="com.yc.phoneQRLogin.listener.LoginQRCodeListener">
        <property name="redisTemplate" ref="redisTemplate"/>
    </bean>
    <!-- 监听二维码过期,并触发事件 -->
    <bean id="listenerForQrCodeInvalid" class="com.yc.phoneQRLogin.listener.WebSocketqrCodeInvalidListener">
        <property name="redisTemplate" ref="redisTemplate"/>
    </bean>
<!--    <bean id="listenerForQrCodeInvalid" class="com.yc.phoneQRLogin.listener.WebSocketqrCodeInvalidListener">-->
<!--        <property name="redisTemplate" ref="redisTemplate"/>-->
<!--    </bean>-->
    <!--监听维护费支付-->
    <bean id="listenerForMaintainPay" class="com.yc.MaintenanceFee.listener.MaintainPayListener">
        <property name="redisTemplate" ref="redisTemplate"/>
@@ -112,7 +112,7 @@
        <redis:listener  ref="listenerForImageCache" serializer="jdkSerializer" topic="Onbus_ClearImageCache" />
        <redis:listener  ref="listenerForMessages" serializer="jdkSerializer" topic="Onbus_Messages" />
        <redis:listener  ref="listenerForQrCodeSession" serializer="jdkSerializer" topic="Onbus_Qrcode" />
        <redis:listener  ref="listenerForQrCodeInvalid" serializer="jdkSerializer" topic="__keyevent@*__:expired"/>
<!--        <redis:listener  ref="listenerForQrCodeInvalid" serializer="jdkSerializer" topic="__keyevent@*__:expired"/>-->
        <redis:listener  ref="listenerForMaintainPay" serializer="jdkSerializer" topic="Onbus_Maintain"/>
    </redis:listener-container>