欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

扫码登录

程序员文章站 2022-06-14 20:17:55
...
package cc.zenking.classcard.system.controller;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import cc.zenking.classcard.common.Const;
import cc.zenking.classcard.system.model.QrCodeResponse;
import cc.zenking.classcard.system.service.ScanService;
import cc.zenking.classcard.utils.RedisUtil;
import net.sf.json.JSONObject;

/** 
* @ClassName: ScanController 
* @Description: (扫码登录) 
* @date 2019年7月11日 上午10:15:48 
* @version V1.0
*  
*/
@Controller
@RequestMapping("/zhbpappscan")
public class ScanController{

    @Autowired
    private RedisUtil rs;
    @Autowired
    private ScanService scanService;
    /**
     * 二维码 扫码登录 存储三分钟
     */
    @Value("${zhbp.redis.auth.code.three}")
    private long authCodeThree;

    /**
     * @param @return 设定文件
     * @return ResponseEntity<Object>    返回类型
     * @throws
     * @Title: createQRCode
     * @Description: (生成二维码并将uuid存储到redis中)
     */
    @RequestMapping("/qrcode")
    @ResponseBody
    public JSONObject createQRCode() {
        Map<String, Object>map = new HashMap<>();
        map.put("status", 1);
        map.put("reason", "成功");
        map.put("data", 0);
        String uuid = UUID.randomUUID().toString();
        //组装二维码内容 zenking,1,uuid=xxxx
        String text = Const.QRCODE_DOMAIN + "?type=" + Const.QRCODE_TYPE + "&uuid=" + uuid;
        int width = 300;
        int height = 300;
        String format = "png";
        Map<String, Object> uuidMap = new HashMap<>();
        uuidMap.put("userId", "0");
        //是否扫码 0未扫码,1扫码
        uuidMap.put("isAppScan", "0");
        try {
            Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
            // hints.put(EncodeHintType.MARGIN, 1);
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 容错率
            BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, hints);
            ByteArrayOutputStream bao = new ByteArrayOutputStream();
            MatrixToImageWriter.writeToStream(bitMatrix, format, bao);
            bao.toByteArray();
            Base64 encoder = new Base64();
            String img = encoder.encodeAsString(bao.toByteArray());
            QrCodeResponse qrCodeResponse = new QrCodeResponse();
            qrCodeResponse.setUuid(uuid);
            qrCodeResponse.setImg(img);
            rs.addMap(Const.QECODE + uuid, uuidMap);
            rs.expire(Const.QECODE + uuid, authCodeThree);
            map.put("data", qrCodeResponse);
        } catch (WriterException e) {
            map.put("status", -1000);
            map.put("reason", "参数有误");
            e.printStackTrace();
        } catch (IOException e) {
            map.put("status", -1000);
            map.put("reason", "参数有误");
            e.printStackTrace();
        }
        return JSONObject.fromObject(map);
    }

    /**
     * @param @param  uuid
     * @param @return 设定文件
     * @return ResponseEntity<Object>    返回类型
     * @throws
     * @Title: cleanRedisQrcode
     * @Description: (扫码后未确认返回二维码登录时重置)
     */
    @RequestMapping("/resetQrcode")
    @ResponseBody
    public JSONObject resetQrcode(String uuid) {
        Map<String, Object>map = new HashMap<>();
        map.put("status", 1);
        map.put("reason", "成功");
        map.put("data", 0);
        try {
            Object uuidExist = rs.getMapField(Const.QECODE + uuid, "userId", Object.class);
            if (null == uuidExist) {
                map.put("status", -6371);
                map.put("reason", "redis中uuid不存在");
            } else {
                //扫描成功标识,用该标识展示“请在手机上确认登录”界面
                rs.addMap(Const.QECODE + uuid, "isAppScan", "0");
            }
        } catch (Exception e) {
            e.printStackTrace();
            map.put("status", -6379);
            map.put("reason", "uuid保存到redis中异常");
        }
        return JSONObject.fromObject(map);
    }

    /**
     * @param @param  uuid
     * @param @param  status  无值 或者 0的时候 返回扫过的状态  1的时候 不返回
     * @param @return 设定文件
     * @return ResponseEntity<Object>    返回类型
     * @throws
     * @Title: pool
     * @Description: (检查二维码是否被扫描)
     */
    @RequestMapping("/pool")
    @ResponseBody
    public JSONObject pool(String uuid, Integer status) {
        Map<String, Object>map = new HashMap<>();
        Map<String, Object>userInfoMap = new HashMap<>();
        map.put("status", 1);
        map.put("reason", "成功");
        map.put("data", 0);
        userInfoMap.put("userId", "");
        userInfoMap.put("userName", "");
        userInfoMap.put("portrait", "");
        map.put("userInfo",userInfoMap);
        //计时
        int time = 0;
        while (true) {
            time++;
            Map<String, Object> ad = rs.mget(Const.QECODE + uuid, Object.class);
            if (ad == null || ad.size() == 0) {
                //点击刷新  3代表超时,页面点击刷新
                map.put("data", 3);
                return JSONObject.fromObject(map);
            }
            if (ad != null && !("0".equals(ad.get("userId")))) {
                //app扫过 并且登录  使用userId 生成token
                int n = scanService.getUserInfo(Integer.parseInt(ad.get("userId").toString()));
                if (n == 1) {
                    //登录后信息
                    map.put("userInfo", scanService.getLoginInfo(Integer.parseInt(ad.get("userId").toString())));
                    //2 代表成功登录状态
                    map.put("data", 2);
                    return JSONObject.fromObject(map);
                } else {
                    //3代表 刷新
                    map.put("data", 3);
                    return JSONObject.fromObject(map);
                }
            }
            if (ad != null && "1".equals(ad.get("isAppScan"))) {
                //app扫过
                if (status == null || status.intValue() == 0) {
                    //1 是 app扫过,弹出选择登录 还是 取消
                    map.put("data", 1);
                    return JSONObject.fromObject(map);
                }
            }
            if (time >= 10) {
                //保持10秒
                map.put("data", 0);
                return JSONObject.fromObject(map);
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    /**
     * @param @param  uuid
     * @param @param  userId
     * @param @return 设定文件
     * @return ResponseEntity<Object>    返回类型
     * @throws
     * @Title: login
     * @Description: (app按钮 : 允许登录)
     */
    @RequestMapping("/appScanLogin")
    @ResponseBody
    public JSONObject appScanLogin(String uuid, String userId) {
        Map<String, Object>map = new HashMap<>();
        map.put("status", 1);
        map.put("reason", "成功");
        map.put("data", 0);
        Map<String, Object> ad = rs.mget(Const.QECODE + uuid, Object.class);
        if (null == ad||ad.isEmpty()) {
            map.put("status", -1021);
            map.put("reason", "请重新扫码");
        } else {
            //如果isAppScan状态是1才可以登录
            if (ad.get("isAppScan") != null && "1".equals(ad.get("isAppScan"))) {
                rs.addMap(Const.QECODE + uuid, "userId", userId);
            }
        }
        return JSONObject.fromObject(map);
    }
    
    /**
     * 功能描述:退出
     *
     * @param uuid
     * @param userId
     * @return: org.springframework.http.ResponseEntity<java.lang.Object>
     */
    @RequestMapping(value = "/appScanCancel")
    @ResponseBody
    public JSONObject appScanCancel(String uuid, String userId) {
        Map<String, Object>map = new HashMap<>();
        map.put("status", 1);
        map.put("reason", "成功");
        try {
            Map<String, Object> ad = rs.mget(Const.QECODE + uuid, Object.class);
            if (null == ad || ad.isEmpty()) {
                map.put("status", -1021);
                map.put("reason", "请重新扫码");
            }
            //如果 isAppScan=1 则移除
            if (ad.get("isAppScan") != null && "1".equals(ad.get("isAppScan"))) {
                rs.del(Const.QECODE + uuid);
            }
        } catch (Exception e) {
            e.printStackTrace();
            map.put("status", -1021);
            map.put("reason", "请重新扫码");
        }
        return JSONObject.fromObject(map);
    }
    
    /**
     * @param uuid
     * @param userId
     * @return ResponseEntity<Object>    返回类型
     * @Title: appScanEnd
     * @Description: (app扫描二维码后)
     */
    @RequestMapping("/appScanPrevious")
    @ResponseBody
    public JSONObject appScanPrevious(@RequestParam(value = "uuid", required = true) String uuid,
                                                  @RequestParam(value = "userId", required = true) String userId) {
        Map<String, Object>map = new HashMap<>();
        map.put("status", 1);
        map.put("reason", "成功");
        map.put("data", 0);
        try {
            Object uuidExist = rs.getMapField(Const.QECODE + uuid, "userId", Object.class);
            if (null == uuidExist) {
                map.put("status", -6371);
                map.put("reason", "redis中uuid不存在");
            } else {
                //扫描成功标识,用该标识展示“请在手机上确认登录”界面
                rs.addMap(Const.QECODE + uuid, "isAppScan", "1");
            }
        } catch (Exception e) {
            e.printStackTrace();
            map.put("status", -6379);
            map.put("reason", "uuid保存到redis中异常");
        }
        return JSONObject.fromObject(map);
    }
}
layui.extend({
    common: '../lib/common'
}).define(['common', 'form', 'layer', 'element'], function (exports) {
    var form = layui.form
        , layer = layui.layer
        , element = layui.element
        , common = layui.common
        , layerIndex = -1
        , getQrCode = function (n) {//n=1是初始化
            $.ajax({
                type: "get",
                url: common.prefix + "appscan/qrcode",
                data: [],
                cache: false,
                dataType: 'json',
                success: function (response) {
                    if (response) {
                        if (response.status == 1) {
                            $("#qrcode").attr("src", "data:image/png;base64," + response.data.img);
                            if (n == 1) {
                                keepPool(response.data.uuid, 0);
                                $("#redisUUID").val(response.data.uuid);
                            }
                        }
                    }
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    if (textStatus == null || textStatus == "") {
                    } else {
                    }
                }
            });
        }
        , keepPool = function (uuid, status) {//status=1 已经扫描 等待登录
            if (!status) {
                status = 0;
            }
            $.ajax(
                {
                    type: "get",
                    url: common.prefix + "appscan/pool",
                    data: {uuid: uuid, status: status},
                    cache: false,
                    dataType: 'json',
                    success: function (data) {
                        if (data && data.status == '1') {
                            if (data.data == '1') {
                                //扫码成功
                                $('.scan-box').addClass('layui-hide');
                                $('.scanned-box').removeClass('layui-hide');
                                $('.lapse-box').addClass('layui-hide');
                                keepPool(uuid, 1);
                            } else if (data.data == '2') {
                                //如果有返回地址 则重定向回
                                var redirectUri = "";
                                redirectUri = common.getRequest().redirectUri;
                                if (redirectUri) {
                                    var token = "?token=" + common.getCookie("token");
                                    if (!token) {
                                        token = "";
                                    }
                                    top.location.replace(redirectUri + token);
                                }
                                else {
                                    window.location.replace(common.prefix + "view/index.html");
                                }
                            } else if (data.data == '3') {
                                //点击刷新
                                $('.scan-box').addClass('layui-hide');
                                $('.scanned-box').addClass('layui-hide');
                                $('.lapse-box').removeClass('layui-hide');
                            } else {
                                keepPool(uuid, 0);
                            }
                        }
                        else {
                            keepPool(uuid, 0);
                        }
                    },
                    error: function (XMLHttpRequest, textStatus, errorThrown) {
                        if (textStatus == "timeout") {
                            keepPool(uuid, 0);
                        } else {
                            keepPool(uuid, 0);
                        }
                    }
                }
            );
        }
        // 检测是否需要强制修改密码
        , checkUpdatePwd = function () {
            $.ajax({
                type: "post",
                url: common.prefix + "user/constraintUpdatePwd",
                async: false,
                dataType: 'json',
                success: function (result) {
                    if (result.status != 1) {
                        form.val("formPwd",{
                            'pwd':'',
                            'pwdSure':''
                        });
                        layer.open({
                            type: 1,
                            title: false,
                            closeBtn: 0,
                            content: $('#updatePwd'),
                            area: ['680px','440px'],
                            resize: false,
                            scrollbar: false,
                            success: function(layero, index){
                                layerIndex = index;
                                $('#updatePwd').removeClass('layui-hide');
                            },
                            end: function(){
                                $('#updatePwd').addClass('layui-hide');
                                form.val("formPwd",{
                                    'pwd':'',
                                    'pwdSure':''
                                });
                            }
                        });
                    } else {                    
                        logIn();
                    }
                }
            });
        }
        // 登入系统
        , logIn = function () {
            //如果有返回地址 则重定向回
            var redirectUri = "";
            redirectUri = common.getRequest().redirectUri;
            if (redirectUri) {
                //带上token
                var token = "?token=" + common.getCookie("token");
                if (!token) {
                    token = "";
                }
                top.location.replace(redirectUri + token);
            }
            else {
                window.location.replace(common.prefix + "view/index.html");
            }
        }
        , initListeners = function () {
            //二维码
            getQrCode(1);
            // 扫码
            $("body").on("click", "[data-scan]", function () {
                var type = $(this).attr("data-scan");
                var $parent = $(this).parents(".scan");
                $parent.addClass("layui-hide");
                $(".scan-box").removeClass("layui-hide");
                if (type == 'back') {
                    // '返回'
                    //调用接口 重置 redis中的uuid  ajax成功后 调用 getQrCode(1);
                    var redisUUID = $("#redisUUID").val();
                    $.ajax({
                        type: "get",
                        url: common.prefix + "appscan/resetQrcode",
                        data: {uuid: redisUUID},
                        cache: false,
                        dataType: 'json',
                        success: function (response) {
                            if (response) {
                                if (response.status == 1) {
                                    //window.location.reload();
                                    //getQrCode(0);
                                } else {
                                    lay.msg(response.reason);
                                }
                            }
                        },
                        error: function (XMLHttpRequest, textStatus, errorThrown) {
                            if (textStatus == null || textStatus == "") {
                            } else {
                            }
                        }
                    });
                } else if (type == 'refresh') {
                    // '刷新'
                    getQrCode(1);
                }
            });

            // 帐号登录
            $("body").on("click", "[data-logintype]", function () {
                var type = $(this).attr("data-logintype");
                var $tabTitle = $("[data-account]");
                var newTab = '', newPlaceholder = '', newType = '', newBtntxt = '';
                if (type == 'student') {
                    // 切换为学生
                    newTab = "学生登录";
                    newPlaceholder = '帐号';
                    newType = 'zksc';
                    newBtntxt = '<i class="layui-icon layui-icon-return"></i>返回';
                    $("[data-zksc]").addClass("layui-hide");
                    $("[data-student]").removeClass("layui-hide");
                } else if (type == 'zksc') {
                    // 帐号
                    newTab = "帐号登录";
                    newPlaceholder = '手机号';
                    newType = 'student';
                    newBtntxt = '学生登录';
                    $("[data-student]").addClass("layui-hide");
                    $("[data-zksc]").removeClass("layui-hide");
                }
                $tabTitle.text(newTab);
                $(this).attr("data-logintype", newType).html(newBtntxt);
                $("[name='username']").attr("placeholder", newPlaceholder);
				$('[name="username"]').val("");
				$('[name="password"]').val("");
				$('[name="authcode"]').val("");
            });

            //监听提交
            form.on('submit(loginform)', function (data) {
                type = gettype();
                $.ajax({
                    type: "post",
                    url: common.prefix + "user/login",
                    data: {
                        type: type,
                        username: $.trim($("[name='username']").val()),
                        password: $.trim($("[name='password']").val()),
                        code: $.trim($("[name='authcode']").val()),
                        loginType: 1
                    },
                    async: false,
                    dataType: 'json',
                    success: function (result) {
                        if (result.status != 1) {
                            if(result.data){
                                // 被锁定
                                if(result.data.loginErrorStatus==4){
                                    layer.open({'title':'您的帐号已被禁用,暂时无法登录', 'content':'<div><i class="icon-danger"></i></div>'+result.reason, closeBtn:0, skin: 'login-layer'});
                                } else {
                                    layer.open({'title':'温馨提示', 'content':result.reason, closeBtn:0, skin: 'login-layer',
                                        yes: function(index, layero){                                        
                                            if(result.data.loginErrorStatus==2){
                                                // 账号或密码错误时,刷新验证码
                                                $('#imgCode').attr('src', 'user/validateCode?'+Math.random());
                                            }
                                            layer.close(index);
                                        }
                                    });
                                }
                            } else {
                                layer.open({'title':'温馨提示', 'content':result.reason, closeBtn:0, skin: 'login-layer'});
                            }                          
                            return;
                        }
                        
                        //检测是否需要强制修改密码
                        checkUpdatePwd();
                    },
                    error: function (XMLHttpRequest, textStatus, errorThrown) {
                        if (textStatus == null || textStatus == "") {
                            layer.msg(errorThrown);
                        } else {
                            layer.msg(textStatus);
                        }
                    }
                });
                return false;
            });

            // 提交,强制修改密码
            form.on('submit(updatePwd)', function (data) {
                var phone=$(".account input[name='username']").val();
                var field=data.field;
                $.ajax({
                    type:'POST',
                    url:common.prefix+'forgetPwd/setNewPwd',
                    data:{phoneNo:phone, pwd:field.pwd, pwdSure:field.pwdSure},
                    cache:false,
                    dataType:'json',
                    success:function(result) {
                        layer.close(layerIndex);
                        layerIndex = -1; // 重置
                        if(result.status==1){
                            layer.open({'title':'温馨提示', 'content':'修改成功,请重新登录!'});
                            $(".account input[name='password']").val("");
                        } else {
                            layer.msg(result.reason,{title:false,icon:5,closeBtn:0,shade:0,time:3000});
                        }
                    }
                });
                return false;
            });

            form.verify({
                password: function(value){
                    if(value.trim().length<8){
                        return '密码不能少于8位';
                    } else if(value.trim().length>24){
                        return '密码不能超过24位';
                    } else if( !(/^(?=.*[A-Z])(?=.*\d)[A-Za-z\d]{8,24}$/.test(value)) && !(/^(?=.*[a-z])(?=.*\d)[A-Za-z\d]{8,24}$/.test(value)) ){
                        return '密码要字母加数字进行组合';
                    }
                }
                ,equalPwd: function(value){
                    var pwd1=$("[name='pwd']").val().trim(),
                        pwd2=$("[name='pwdSure']").val().trim();
                    if(pwd1!=pwd2){
                        return '两次密码不一致';
                    }
                }
            });

            // 禁止输入空格
            $("form").on("keypress", "input[name='username'],input[name='password']", function (event) {
                var evt = arguments.callee.caller.arguments[0];
                var key = evt.charCode;
                if (key == 32) {
                    event.preventDefault();
                }
            });

            // 回车登录
            $("body").bind("keyup",function(event){
                var showFlag = $(".account").hasClass("layui-show");
                if(!showFlag){
                    return;
                }
                var evt=arguments.callee.caller.arguments[0];
                var key = evt.keyCode;
                if(key == 13){
                    var $layer = $("body>.layui-layer");
                    if($layer.length==0){
                        // 登录
                        $("[lay-filter='loginform']").click();
                    }
                }
            });

            // 发送验证码
            $("[name='btnCode']").bind("click", function () {
                if ($("body").find(".error").length > 0) {
                    return false;
                }
                var flag = validRequired('username');
                if (!flag) {
                    layer.msg("请填写手机号!");
                    return false;
                }
                flag = validRequired('password');
                if (!flag) {
                    layer.msg("请填写密码!");
                    return false;
                }
                sendcode(common.prefix, $(this));
            });

            // 用户协议
            form.on('checkbox(agreement)', function(data){
                var $parent = $(data.elem).parents(".form-btn");
                    $btn = $parent.find('[lay-filter="loginform"]');
                if(data.elem.checked){
                    // 勾选
                    $btn.removeClass("layui-btn-disabled").removeAttr("disabled");
                } else {
                    $btn.addClass("layui-btn-disabled").attr("disabled",true);
                }
            });

            // 强制重置密码,监听密码输入框,改变‘确定’按钮状态
            $("#updatePwd").on("input porpertychange","input[required]",function(){
                var pwd1 = $("#updatePwd [name='pwd']").val().trim();
                var pwd2 = $("#updatePwd [name='pwdSure']").val().trim();
                if(pwd1!=""&&pwd2!=""){
                    $("#updatePwd .layui-btn").removeClass("layui-btn-disabled").removeAttr("disabled");
                } else {
                    $("#updatePwd .layui-btn").addClass("layui-btn-disabled").attr("disabled","disabled");
                }
            });
        };

    var type = 0;
    var sTime; //发送间隔时间    

    initListeners();
    exports('login', {});
});

/**
 * 获取登录名称类型
 */
function gettype() {
    if ($("body").find(".error").length > 0) {
        return false;
    }
    var flag = validRequired('username');
    if (!flag) {
        return false;
    }
    flag = validRequired('password');
    if (!flag) {
        return false;
    }

    if (/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-][email protected][a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test($.trim($("[name='username']").val()))) {
        type = 2;

    } else if (/^1[0-9]{10}$/.test($.trim($("[name='username']").val()))) {
        type = 1;
    } else {
        type = 0;
    }
    return type;
}

/**
 * 发送验证码
 * @param wrap
 */
function sendcode(commonUrl, wrap) {
    gettype();
    wrap.attr("disabled","disabled").addClass("layui-btn-disabled");
    $.ajax({
        type: "post",
        url: commonUrl + "user/sendLoginRandomNo",
        data: {
            type: type,
            phoneNo: $.trim($("[name='username']").val()),
            password: $.trim($("[name='password']").val()),
            loginType: 0
        },
        async: false,
        dataType: 'json',
        success: function (data) {
            if (data.status != 1) {
                layer.msg(data.reason);
                wrap.removeAttr("disabled").removeClass("layui-btn-disabled");
            } else {
                layer.msg("验证码发送成功,请注意查收");                
                if (wrap) {
                    sTime = 60;
                    resendtime(wrap);
                }                
            }
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            if (textStatus == null || textStatus == "") {
                layer.msg(errorThrown);
            } else {
                layer.msg(textStatus);
            }
        }
    });
}

//设置定时,1分钟后才能重新发送
function resendtime(wrap) {
    if (sTime != 0) {
        wrap.val("获取验证码("+sTime+")");
        sTime--;
        setTimeout(function () {
            resendtime(wrap)
        }, 1000)
    } else {
        wrap.removeAttr("disabled").val("获取验证码").removeClass("layui-btn-disabled");
    }
}

function validRequired(name) {
    var flag = true;
    var that = $("[name='" + name + "']");
    var value = that.val();
    if (value == "") {
        flag = false;
    }
    return flag;
}

function replaceNull(obj) {
    var exp = obj;
    if (typeof(exp) == "undefined" || exp == null) {
        return "";
    }
    return obj;
}

 

相关标签: java扫码登录