AttPushController.java 16.6 KB
package com.sincere.att.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.sincere.att.feign.ScFeign;
import com.sincere.att.feign.XaFeign;
import com.sincere.att.logs.LogName;
import com.sincere.att.logs.LoggerUtils;
import com.sincere.att.vo.AttendanceInfoBean;
import com.sincere.att.vo.FingerOrderVo;
import com.sincere.att.vo.UserOrderVo;
import com.sincere.common.dto.smartCampus.SZ_AttendanceDto;
import com.sincere.common.dto.xiaoan.FingerDto;
import com.sincere.common.util.DateUtils;
import com.sincere.common.util.HttpClientUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 所有的设备请求都会在url参数里携带SN,这是设备序列号(serial number的缩写),每个设备唯一标识
 */
@RestController
@RequestMapping("/iclock")
public class AttPushController {
    private static final Logger Log_orderFail = LoggerUtils.Logger(LogName.orderFail);
    private static final Logger Log_orderSuccess = LoggerUtils.Logger(LogName.orderSuccess);
    private static final Logger Log_kaoInfo = LoggerUtils.Logger(LogName.kaoInfo);

    private static Map<String, List<String>> cmdMap = new HashMap<>();
    private static Map<String, Integer> cmdOrderMap = new HashMap<>();

    private static String pwd = "22222222-6faf-48uh-a5a9-447ec68bfe2f";
    private static String account = "yueqingzhijiao";


    @Autowired
    ScFeign scFeign;

    @Autowired
    XaFeign xaFeign;

    @RequestMapping(value = "sendUser", method = RequestMethod.GET)
    public void sendUser(int roomId) {
        JSONObject object = new JSONObject();
        object.put("pageIndex", 1);
        object.put("roomId", roomId);
        object.put("pageSize", 9999);
        JSONObject result = HttpClientUtils.httpPostJson("http://campus.myjxt.com/api/Room/GetListPageRoom", object.toJSONString());
        JSONArray array = (JSONArray) ((JSONObject) result.get("data")).get("roomList");
        List<String> attendanceList = scFeign.selectRoomAttendance(roomId);
        for (String attendance : attendanceList) {
            List<String> order = new ArrayList<>();
            for (int i = 0; i < array.size(); i++) {
                JSONObject student = (JSONObject) array.get(i);
                UserOrderVo vo = new UserOrderVo();
                vo.setStudentId((Integer) student.get("studentid"));
                vo.setStudentName((String) student.get("name"));
                int number = 1;
                try {
                    number = cmdOrderMap.get(attendance);
                } catch (Exception e) {

                }
                vo.setNumber(number);
                number++;
                cmdOrderMap.put(attendance, number);
                if (vo.getStudentId() != 0) {
//                    if (vo.getStudentId() == 72196){
                    //todo:测试专用
                    if (!order.contains(vo.toString())) {
                        order.add(vo.toString());
                    }
//                    }
                }
            }
                cmdMap.put(attendance, order);
        }
    }

    @RequestMapping(value = "sendFinger", method = RequestMethod.GET)
    public void sendFinger(int roomId) {
        JSONObject object = new JSONObject();
        object.put("PageIndex", 1);
        object.put("roomId", roomId);
        object.put("pageSize", 9999);
        JSONObject result = HttpClientUtils.httpPostJson("http://campus.myjxt.com/api/Room/GetListPageRoom", object.toJSONString());
        JSONArray array = (JSONArray) ((JSONObject) result.get("data")).get("roomList");
        List<String> attendanceList = scFeign.selectRoomAttendance(roomId);
        for (String attendance : attendanceList) {
            List<String> order = new ArrayList<>();
            for (int i = 0; i < array.size(); i++) {
                JSONObject student = (JSONObject) array.get(i);
                FingerOrderVo vo = new FingerOrderVo();
                int number = 1;
                try {
                    number = cmdOrderMap.get(attendance);
                } catch (Exception e) {

                }
                vo.setNumber(number);
                vo.setOrder(xaFeign.selectFinger((Integer) student.get("studentid")));
                number++;
                cmdOrderMap.put(attendance, number);
                if (StringUtils.isNotBlank(vo.getOrder())) {
                    order.add(vo.toString());
                }
            }
            cmdMap.put(attendance, order);
        }
    }

    /**
     * 1,设备通完电以后第一个发送到后台的请求
     * 格式为 /iclock/cdata?options=all&language=xxxx&pushver=xxxx
     */
    @RequestMapping(value = "/cdata", params = {"options", "language", "pushver"}, method = RequestMethod.GET)
    public void init(String SN, String options, String language, String pushver, HttpServletRequest request,
                     @RequestParam(required = false) String PushOptionsFlag, HttpServletResponse response) {
        try {
            if (cmdMap.get(SN) == null) {
                System.out.println("设备上线:" + SN);
                cmdMap.put(SN, new ArrayList<>());
                cmdOrderMap.put(SN, 1);
            }
            if (scFeign.selectAttendaceWithId(SN) == null) {
                SZ_AttendanceDto attendanceDto = new SZ_AttendanceDto();
                attendanceDto.setClint_id(SN);
                attendanceDto.setClint_type("24");
                attendanceDto.setIp(request.getRemoteAddr());
                attendanceDto.setPort(request.getRemotePort());
                attendanceDto.setIntime(DateUtils.date2String(new Date(), DateUtils.format2));
                attendanceDto.setSchool_id("-1");
                attendanceDto.setState(1);
                scFeign.insertAttendance(attendanceDto);
            } else {
                scFeign.updateAttendance(SN);
            }
            String initOptions = initOptions(SN, PushOptionsFlag);
            response.getWriter().write(initOptions);//返回成功以后设备会发送心跳请求
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 2,心跳请求,会从服务器拿到命令返回   给设备
     */
    @RequestMapping("/getrequest")
    public void heartBeat(String SN, HttpServletResponse response) {
        scFeign.updateAttendance(SN);
        StringBuffer sb = new StringBuffer("OK");
        List<String> cmds = cmdMap.get(SN);
//        if (null != cmds && cmds.size() > 10)
//            cmds = cmds.subList(0, 10);
        if (cmds == null) {//等于空说明从来没加载过,如果初始化加载过了,此时应该不为Null 只是size为0
            System.out.println("设备上线:" + SN);
            cmds = new ArrayList<>();
            cmdMap.put(SN, cmds);
            cmdOrderMap.put(SN, 1);
        }
        if (cmds != null && cmds.size() > 0) {
            sb.setLength(0);//如果有命令就不返回OK了
            cmds.stream().forEach(cmd -> sb.append(cmd).append("\r\n\r\n"));
        }
        try {
            response.setCharacterEncoding("gbk");
            response.getWriter().write(sb.toString());
//            System.out.println("返回数据成功:" + SN + "---学生数量:" + cmds.size());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 3,候补心跳请求,正常情况下设备不发此请求,有大量数据上传的时候,不发上面的心跳,发这个请求,
     * 这个请求,服务器只能返回OK,不可以返回命令
     */
    @RequestMapping("/ping")
    public void ping(HttpServletResponse response) {
        System.out.println("考勤机心跳请求大量进来了......ping" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
        try {
            response.getWriter().write("OK");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 4,设备端处理完命令以后会发送该请求,告诉服务器命令的处理结果
     */
    @RequestMapping("/devicecmd")
    public void handleCmd(String SN, @RequestBody String data, HttpServletResponse response) {
        //判断data  清空map
        List<String> cmdList = cmdMap.get(SN);
        String[] returnList = data.split("\n");
        if (returnList != null && returnList.length > 0 && cmdList != null && cmdList.size() > 0) {
            System.out.println("----returnList:" + returnList.length);
            for (String message : returnList) {
                String number = message.substring(message.indexOf("=") + 1, message.indexOf("&"));
                String result = message.substring(message.indexOf("=", message.indexOf("&")) + 1, message.indexOf("&", message.indexOf("&") + 1));
                if (result.equals("0")) {
                    Iterator<String> it = cmdList.iterator();
                    while (((Iterator) it).hasNext()) {
                        String b = it.next();
                        if (b.contains("C:" + number)) {
                            it.remove();
                            System.out.println("----设备接收数据成功:" + SN + "----number:" + number);
                        }
                    }
                }
            }
        }
        try {
            response.getWriter().write("OK");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 5 考勤数据上报
     */
    @RequestMapping(value = "/cdata")
    public void handleRtData(HttpServletRequest request, HttpServletResponse response, String SN, String table) throws UnsupportedEncodingException {
        request.setCharacterEncoding("gbk");
        String data = "";
        ByteArrayOutputStream bos = null;
        byte[] b = new byte[1024];
        try {
            InputStream is = request.getInputStream();
            bos = new ByteArrayOutputStream();
            int len = 0;
            while ((len = is.read(b)) != -1) {
                bos.write(b, 0, len);
            }
            data = new String(bos.toByteArray(), "gbk");
        } catch (IOException e) {
            e.printStackTrace();
        }
        if ("ATTLOG".equals(table)) {
            String[] list = data.split("\t");
            String cardNo = scFeign.selectStudentNumByStudentId(Integer.valueOf(list[0]));
            if (StringUtils.isNotBlank(cardNo)) {
                String cardNo10 = new BigInteger(cardNo, 16).toString();
                //考勤日志
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String info = String.format("<AttendanceInfo submitTime=\"%s\"><Info device=\"%s\" card=\"%s\" operTime=\"%s\" direc=\"%s\"></Info></AttendanceInfo>",
                        simpleDateFormat.format(new Date()), SN, cardNo10, list[1], "-1");
                AttendanceInfoBean attendanceInfoBean = new AttendanceInfoBean();
                attendanceInfoBean.setInfo(info);
                attendanceInfoBean.setIsControl(0);
                attendanceInfoBean.setPwd(pwd);
                attendanceInfoBean.setUsername(account);

                String jsonResult = JSON.toJSONString(attendanceInfoBean);
                String urlHXY = "http://campus.myjxt.com/api/XiaoAnCommon/SendHXY";
                JSONObject jsonObject = HttpClientUtils.httpPostJson(urlHXY, jsonResult);
                if ((int) jsonObject.get("status") == 1) {
                    Log_kaoInfo.info("出入寝签到成功:" + SN + " 卡号:" + cardNo);
                } else {
                    Log_orderFail.info("出入寝签到失败:" + SN + " 卡号:" + cardNo + " result1:" + jsonObject.toJSONString());
                }
            } else {
                System.out.println(cardNo);
            }
        }
        if ("OPERLOG".equals(table)) {
            //操作日志
            if (data.substring(0, 3).contains("FP")) {
                //添加指纹
                String studentId = data.substring(data.indexOf("=") + 1, data.indexOf("\t", data.indexOf("=")));
                String order = data.substring(3);
                FingerDto fingerDto = new FingerDto();
                fingerDto.setOrderMsg(order);
                fingerDto.setStudentId(Integer.valueOf(studentId));
                fingerDto.setCreateTime(new Date());
                xaFeign.insertFinger(fingerDto);
            }
        }
        try {
            response.getWriter().write("OK");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
       /*JSONObject object = new JSONObject();
       object.put("pageIndex",1);
       object.put("roomId","13299");
       object.put("pageSize",9999);
       JSONObject result = HttpClientUtils.httpPostJson("http://campus.myjxt.com/api/Room/GetListPageRoom",object.toJSONString());
       JSONObject data = result.getJSONObject("data");
       JSONArray roomList = data.getJSONArray("roomList");
       for (int i = 0; i < roomList.size(); i++) {
           String name = roomList.getJSONObject(i).getString("name");
           String studentId = roomList.getJSONObject(i).getString("studentid");
           System.out.println(name+","+studentId);
       }*/

        String cardNo = "FF013E0F";
        String SN = "A4JS174260624";
        String cardNo10 = new BigInteger(cardNo, 16).toString();
        //考勤日志
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String info = String.format("<AttendanceInfo submitTime=\"%s\"><Info device=\"%s\" card=\"%s\" operTime=\"%s\" direc=\"%s\"></Info></AttendanceInfo>",
                simpleDateFormat.format(new Date()), SN, cardNo10, DateUtils.date2String(new Date(), DateUtils.format2), "-1");
        AttendanceInfoBean attendanceInfoBean = new AttendanceInfoBean();
        attendanceInfoBean.setInfo(info);
        attendanceInfoBean.setIsControl(0);
        attendanceInfoBean.setPwd(pwd);
        attendanceInfoBean.setUsername(account);

        String jsonResult = JSON.toJSONString(attendanceInfoBean);
        String urlHXY = "http://campus.myjxt.com/api/XiaoAnCommon/SendHXY";
        JSONObject jsonObject = HttpClientUtils.httpPostJson(urlHXY, jsonResult);
        if ((int) jsonObject.get("status") == 1) {
            Log_kaoInfo.info("出入寝签到成功:" + SN + " 卡号:" + cardNo);
        } else {
            Log_orderFail.info("出入寝签到失败:" + SN + " 卡号:" + cardNo + " result1:" + jsonObject.toJSONString());
        }
    }


    /**
     * 设备通电以后连接到服务器,需要返回的初始化参数
     *
     * @param sn
     * @param PushOptionsFlag
     * @return
     */
    private String initOptions(String sn, String PushOptionsFlag) {
        StringBuffer devOptions = new StringBuffer();
        devOptions.append("GET OPTION FROM: " + sn);
        // + "\nStamp=" + devInfo.devInfoJson.getString("Stamp")
        devOptions.append("\nATTLOGStamp=0");
        devOptions.append("\nOPERLOGStamp=0");
        devOptions.append("\nBIODATAStamp=0");
        devOptions.append("\nATTPHOTOStamp=0");
        devOptions.append("\nErrorDelay=10");//断网重连
        devOptions.append("\nDelay=5");//心跳间隔
        devOptions.append("\nTimeZone=8");//时区
        devOptions.append("\nRealtime=1");//实时上传
        devOptions.append("\nServerVer=3.0.1");//这个必须填写
//        1 考勤记录
//        2 操作日志
//        3 考勤照片
//        4 登记新指纹
//        5 登记新用户
//        6 指纹图片
//        7 修改用户信息
//        8 修改指纹
//        9 新登记人脸
//        10 用户照片
//        11 工作号码
//        12 比对照片
        devOptions.append("\nTransFlag=111111111111");//  1-12二进制位 分别代表以上含义
        System.out.println("PushOptionsFlag=============" + PushOptionsFlag);
        if (PushOptionsFlag != null && PushOptionsFlag.equals("1")) {
            // 支持参数单独获取的才要把需要获取的参数回传给设备 modifeid by max 20170926
            devOptions.append("\nPushOptions=RegDeviceType,FingerFunOn,FaceFunOn,FPVersion,FaceVersion,NetworkType,HardwareId3,HardwareId5,HardwareId56,LicenseStatus3,LicenseStatus5,LicenseStatus56");
        }
        devOptions.append("\n");
        return devOptions.toString();
    }
}