package com.jpsoft.shinestar.modules.business.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.jpsoft.shinestar.config.OSSConfig;
import com.jpsoft.shinestar.modules.base.entity.*;
import com.jpsoft.shinestar.modules.base.service.*;
import com.jpsoft.shinestar.modules.business.dto.PersonInfoDayWSADTO;
import com.jpsoft.shinestar.modules.business.dto.PersonInfoMonthWSADTO;
import com.jpsoft.shinestar.modules.business.entity.SupplementWork;
import com.jpsoft.shinestar.modules.business.entity.SupplementWorkPerson;
import com.jpsoft.shinestar.modules.business.entity.WorkScheduleAttendance;
import com.jpsoft.shinestar.modules.business.service.*;
import com.jpsoft.shinestar.modules.common.dto.MessageResult;
import com.jpsoft.shinestar.modules.common.utils.OSSUtil;
import com.jpsoft.shinestar.modules.sys.service.DataDictionaryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.joda.time.DateTime;
import org.joda.time.Months;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import com.jpsoft.shinestar.modules.common.dto.Sort;

@Slf4j
@RestController
@RequestMapping("/business/workScheduleAttendance")
@Api(description = "workScheduleAttendance")
public class WorkScheduleAttendanceController {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private WorkScheduleAttendanceService workScheduleAttendanceService;
    @Autowired
    private PersonInfoService personInfoService;
    @Autowired
    private CompanyInfoService companyInfoService;
    @Autowired
    private WorkPersonSchedulingService workPersonSchedulingService;
    @Autowired
    private WorkShiftInfoService workShiftInfoService;
    @Autowired
    private ValueOperations<String, Object> valueOperations;
    @Autowired
    private DataDictionaryService dataDictionaryService;
    @Autowired
    private WorkOverService workOverService;
    @Autowired
    private WorkOverPersonService workOverPersonService;
    @Autowired
    private BusinessOutService businessOutService;
    @Autowired
    private RequestForLeaveInfoService requestForLeaveInfoService;
    @Autowired
    private HolidayInfoService holidayInfoService;
    @Autowired
    private SupplementWorkService supplementWorkService;
    @Autowired
    private SupplementWorkPersonService supplementWorkPersonService;

    @Autowired
    private YearRequestForLeaveInfoService yearRequestForLeaveInfoService;

    @Autowired
    private OSSConfig ossConfig;

    @ApiOperation(value = "删除重复考勤记录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startDate", value = "起始时间", required = true, paramType = "form"),
            @ApiImplicitParam(name = "limit", value = "查询记录数", required = true, paramType = "form")
    })
    @GetMapping("removeDuplicateRecord")
    public MessageResult<Integer> removeDuplicateRecord(
            @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,int limit){
        MessageResult<Integer> messageResult = new MessageResult<>();
    
        try {
            int affectCount = 0;

            List<Map> mapList = workScheduleAttendanceService.queryDuplicateRecord(startDate,limit);

            for (Map map : mapList) {
                String personScheduleId = String.valueOf(map.get("personScheduleId"));
                String workShiftId = String.valueOf(map.get("workShiftId"));
                String classify = String.valueOf(map.get("classify"));

                List<WorkScheduleAttendance> attendanceList = workScheduleAttendanceService.findByPersonScheduleIdAndClassify(personScheduleId,workShiftId,classify);

                int index = 0;

                //recordTime desc排序
                if ("1".equals(classify)){
                    //上班保留最早记录
                    index = attendanceList.size()-1;
                }
                else if("2".equals(classify)){
                    //下班保留最迟记录
                    index = 0;
                }

                for (int i = 0; i < attendanceList.size(); i++) {
                    if(i!=index){
                        WorkScheduleAttendance wsa = attendanceList.get(i);
                        wsa.setDelFlag(true);
                        wsa.setUpdateTime(new Date());

                        affectCount += workScheduleAttendanceService.update(wsa);
                    }
                }
            }

            //todo 填写具体代码
            messageResult.setData(affectCount);
            messageResult.setResult(true);
        }
        catch (Exception ex){
            log.error(ex.getMessage(),ex);
    
            messageResult.setResult(false);
            messageResult.setMessage(ex.getMessage());
        }
    
        return messageResult;
    }

    @ApiOperation(value = "添加考勤记录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deviceNo", value = "设备编号", required = true, paramType = "form"),
            @ApiImplicitParam(name = "personId", value = "人员编号", required = true, paramType = "form"),
            @ApiImplicitParam(name = "temperature", value = "温度", required = true, paramType = "form"),
            @ApiImplicitParam(name = "recordTime", value = "考勤时间", required = true, paramType = "form")
    })
    @RequestMapping(value = "add", method = RequestMethod.POST)
    public MessageResult<String> add(
            String deviceNo,
            Long personId, BigDecimal temperature,
            @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date recordTime) {
        MessageResult<String> messageResult = new MessageResult<>();

        try {
            boolean result = workScheduleAttendanceService.punchIn(deviceNo, personId, temperature, recordTime);

            messageResult.setResult(result);

            messageResult.setMessage(result ? "添加考勤记录成功!" : "添加考勤记录失败!");
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
            messageResult.setResult(false);
            messageResult.setMessage(ex.getMessage());
        }

        return messageResult;
    }

    @PostMapping("batchUpdate")
    @ApiOperation(value = "批量更新考勤记录")
    public MessageResult<String> batchUpdate(String companyId, String personIds,
                                             String personName,
                                             String workShiftId,
                                             @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
                                             @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate) {
        MessageResult<String> messageResult = new MessageResult<>();

        try {
            if (startDate == null) {
                startDate = DateTime.now().dayOfMonth().withMinimumValue().toDate();
            }

            if (endDate == null) {
                endDate = DateTime.now().plusMonths(1).dayOfMonth().withMinimumValue().toDate();
            } else {
                endDate = new DateTime(endDate).plusDays(1).toDate();
            }

            //todo 起始时间与结束时间间隔最大1个月
            DateTime startTime = new DateTime(startDate);
            DateTime endTime = new DateTime(endDate);

            int months = Months.monthsBetween(startTime, endTime).getMonths();

            if (months > 1) {
                throw new Exception("最多只能更新一个月内的考勤记录!");
            }

            long start = System.currentTimeMillis();
            int affectCount = 0;

            if (StringUtils.isNotEmpty(personIds)) {
                String[] arr = personIds.split(",");

                for (String str : arr) {
                    Long personId = Long.valueOf(str);

                    PersonInfo personInfo = personInfoService.get(personId);

                    if (personInfo != null) {
                        companyId = personInfo.getCompanyId();
                    }

                    affectCount += workScheduleAttendanceService.batchUpdate(companyId, workShiftId, personId,
                            personName, startDate, endDate, true);
                }
            } else if (StringUtils.isNotEmpty(personName)) {
                CompanyInfo companyInfo = companyInfoService.get(companyId);

                Map<String, Object> searchParams = new HashMap<>();

                searchParams.put("code", companyInfo.getCode() + "%");
                searchParams.put("name", personName);

                List<Sort> sortList = new ArrayList<>();
                sortList.add(new Sort("create_time", "desc"));

                List<PersonInfo> personList = personInfoService.findByCompanyCode(searchParams, sortList);

                if (personList.size() > 0) {
                    PersonInfo personInfo = personList.get(0);

                    //只更新第一个
                    affectCount += workScheduleAttendanceService.batchUpdate(personInfo.getCompanyId(), workShiftId, personInfo.getId(),
                            personInfo.getName(), startDate, endDate, true);
                }
            } else {
                affectCount += workScheduleAttendanceService.batchUpdate(companyId, workShiftId, null,
                        personName, startDate, endDate, true);
            }

            long end = System.currentTimeMillis();

            //todo 填写具体代码
            messageResult.setData(String.format("共添加:%d条记录,耗时：%s秒", affectCount, (end - start) / 1000));
            messageResult.setMessage(DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
            messageResult.setResult(true);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);

            messageResult.setResult(false);
            messageResult.setMessage(ex.getMessage());
        }

        return messageResult;
    }

    @ApiOperation(value = "考勤按月统计")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "companyId", value = "单位编号", required = true, paramType = "form"),
            @ApiImplicitParam(name = "subordinate", value = "是否查询下级单位", required = false, paramType = "form", dataType = "String"),
            @ApiImplicitParam(name = "name", value = "用户姓名", required = true, paramType = "form"),
            @ApiImplicitParam(name = "startDate", value = "开始时间", required = true, paramType = "form"),
            @ApiImplicitParam(name = "endDate", value = "截止时间", required = true, paramType = "form"),
            @ApiImplicitParam(name = "subject", value = "subject", required = false, paramType = "form")
    })
    @RequestMapping(value = "attendanceMonth", method = RequestMethod.POST)
    public MessageResult<Map> attendanceMonth(
            @RequestParam(value = "companyId", defaultValue = "") String companyId,
            @RequestParam(value = "subordinate", defaultValue = "false") Boolean subordinate,
            @RequestParam(value = "name", defaultValue = "") String name,
            @RequestParam(value = "jobNumber", defaultValue = "") String jobNumber,
            @RequestParam(value = "popedomRemark", defaultValue = "") String popedomRemark,
            @DateTimeFormat(pattern = "") String startMonth,
            @DateTimeFormat(pattern = "") String endMonth,
            @RequestParam(value = "pageIndex", defaultValue = "1") int pageIndex,
            @RequestParam(value = "pageSize", defaultValue = "10") int pageSize,
            @RequestAttribute String subject) {
        //当前用户ID
        System.out.println(subject);

        MessageResult<Map> msgResult = new MessageResult<>();

        try {
            Map<String, Object> searchParams = new HashMap<>();
            Map<String, Object> msgMap = new HashMap<>();

            List<Sort> sortList = new ArrayList<>();
            sortList.add(new Sort("a.id_", "asc"));

            if (StringUtils.isNotEmpty(name)) {
                String[] names = name.split(",");
                List nameList = new ArrayList();
                for (String n : names) {
                    nameList.add("%" + n + "%");
                }
                searchParams.put("nameList", nameList);
            }

            if (StringUtils.isNotEmpty(companyId)) {
                CompanyInfo parentCompanyInfo = companyInfoService.get(companyId);
                String parentCode = parentCompanyInfo.getCode();
                if (subordinate) {
                    searchParams.put("companyCode", parentCode + "%");
                } else {
                    searchParams.put("companyCode", parentCode);
                }
            }

            if (StringUtils.isNotEmpty(jobNumber)) {
                searchParams.put("jobNumber", jobNumber);
            }

            if (StringUtils.isNotEmpty(popedomRemark)) {
                List<String> popedomRemarkList = Arrays.asList(popedomRemark.split(","));
                searchParams.put("popedomRemarkList", popedomRemarkList);
            }

            Page<PersonInfo> page = personInfoService.pageSearch(searchParams, pageIndex, pageSize, true, sortList);
            List<PersonInfoMonthWSADTO> wsaList = new ArrayList<>();

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

            Date startDate = sdf.parse(startMonth + " 00:00:00");
            Date endDate = sdf.parse(endMonth + " 23:59:59");
//            //头部是月份
//            Boolean isDateEq = false;
//
//            //获取开始查询的年月
//            Map<String, Object> startMap = getDayByMonth(startDate);
//            int sYear = Integer.parseInt(startMap.get("year").toString());
//            int sMonth = Integer.parseInt(startMap.get("month").toString());
//            List<Integer> months = new ArrayList<>();
//
//
//            months.add(sMonth);
//            if(startDate.equals(endDate)){
//                //如果日期相同 查的同年月
//                isDateEq = true;
//            }else {
//                //获取结束查询的年月
//                Map<String, Object> endMap = getDayByMonth(endDate);
//                int eMonth = Integer.parseInt(endMap.get("month").toString());
//                months.add(eMonth);
//            }
//
//            List<String> dateLst = new ArrayList<>();
//            dateLst.add(startMonth + "%");
//            dateLst.add(endMonth + "%");
            Map<String,CompanyInfo> companyInfoMap = new HashMap<>();

            for (PersonInfo pi : page.getResult()) {
                PersonInfoMonthWSADTO wsaDTO = new PersonInfoMonthWSADTO();
                wsaDTO.setPersonInfo(pi);

                CompanyInfo ci = null;

                if(!companyInfoMap.containsKey(pi.getCompanyId())){
                    ci = companyInfoService.get(pi.getCompanyId());
                    companyInfoMap.put(pi.getCompanyId(), ci);
                }
                else{
                    ci = companyInfoMap.get(pi.getCompanyId());
                }

                if(ci!=null) {
                    if (StringUtils.isNotEmpty(ci.getFullName())) {
                        wsaDTO.setCompanyName(ci.getFullName());
                    } else {
                        wsaDTO.setCompanyName(ci.getName());
                    }
                }

                //出差次数businessTripNum
                //Map<String,Object> searchParams11 = new HashMap<>();
                //searchParams11.put("workStatus","3");
                BigDecimal businessTripNum = businessOutService.sumDaysByPersonIdAndTimeRange(pi.getId(), startDate, endDate);
                //BigDecimal businessTripNum = workScheduleAttendanceService.findBusinessTripNum(pi.getId(),startDate,endDate,searchParams11);
                wsaDTO.setBusinessTripNum(businessTripNum);

                //请年假天数yearLeaveNum
                BigDecimal yearLeaveNum = yearRequestForLeaveInfoService.sumDaysByPersonIdAndTimeRange(pi.getId(), startDate, endDate);
                wsaDTO.setYearLeaveNum(yearLeaveNum);

                //先查总班次 确认正常上班和休息
//                List<WorkPersonScheduling> startWorkPersonScheduling
//                        = workPersonSchedulingService.findByPersonIdSDateAndEDate(pi.getId(),startDate,endDate,false);
                BigDecimal attendanceDays
                        = workPersonSchedulingService.findAttendanceDaysByPersonIdSDateAndEDate(pi.getId(), startDate, endDate, false);

                //应出勤天数attendanceDays
                wsaDTO.setAttendanceDays(attendanceDays);
                //全勤天数totalAttendanceDays
                BigDecimal totalAttendanceDays = workScheduleAttendanceService.findTotalAttendance(pi.getId(), startDate, endDate, "1");
                //加上出差天数
                BigDecimal days = totalAttendanceDays.add(businessTripNum);

                //加上年假天数
                days = days.add(yearLeaveNum);

                wsaDTO.setTotalAttendanceDays(days);
                //迟到分钟lateMinutes
                Map<String, Object> searchParams3 = new HashMap<>();
                searchParams3.put("result", "2");
                Double lateMinutes = workScheduleAttendanceService.findSumLMinuteByParams(pi.getId(), startDate, endDate, searchParams3);
                wsaDTO.setLateMinutes(lateMinutes);
                //迟到次数lateNum
                Map<String, Object> searchParams4 = new HashMap<>();
                searchParams4.put("result", "2");
                searchParams4.put("classify", "1");//上班
                int lateNum = workScheduleAttendanceService.findCountByParams(pi.getId(), startDate, endDate, searchParams4);
                wsaDTO.setLateNum(lateNum);
                //早退分钟leaveEarlyMinutes
                Map<String, Object> searchParams5 = new HashMap<>();
                searchParams5.put("result", "3");
                Double leaveEarlyMinutes = workScheduleAttendanceService.findSumLMinuteByParams(pi.getId(), startDate, endDate, searchParams5);
                wsaDTO.setLeaveEarlyMinutes(leaveEarlyMinutes);
                //早退次数leaveEarlyNum
                Map<String, Object> searchParams6 = new HashMap<>();
                searchParams6.put("result", "3");
                searchParams6.put("classify", "2");//下班
                int leaveEarlyNum = workScheduleAttendanceService.findCountByParams(pi.getId(), startDate, endDate, searchParams6);
                wsaDTO.setLeaveEarlyNum(leaveEarlyNum);
                //加班小时overtime
                Map<String, Object> searchParams7 = new HashMap<>();
                searchParams7.put("result", "3");
                searchParams7.put("classify", "2");//下班
                List<WorkOverPerson> overLists = workOverPersonService.findByPersonIdAndSEDate(pi.getId(), startDate, endDate);
                Integer minute = 0;

                for (WorkOverPerson wop : overLists) {
                    if (wop.getDuration() == null) {
                        minute = minute + (wop.getHours() * 60);
                    } else {
                        minute = minute + wop.getDuration();
                    }
                }

                wsaDTO.setOvertime(formatTime(minute));
                //旷工天数absenteeismDays
                BigDecimal absenteeismCount = workScheduleAttendanceService.findAbsenteeism(pi.getId(), startDate, endDate, "0");
                wsaDTO.setAbsenteeismDays(absenteeismCount);
                //未刷次数notSwipingNum = 旷工次数
                Map<String, Object> searchParams9 = new HashMap<>();
                searchParams9.put("result", "0");
                searchParams9.put("noWorkStatus", "3");//出差未打卡不算
                searchParams9.put("noWorkStatus7", "7");//年假未打卡不算
                int notSwipingNum = workScheduleAttendanceService.findCountByParams(pi.getId(), startDate, endDate, searchParams9);
                wsaDTO.setNotSwipingNum(notSwipingNum);
                //签到次数signNum
                Map<String, Object> searchParams10 = new HashMap<>();
                //0为未打卡 不等于0的为签到
                searchParams10.put("noResult", "0");
                searchParams9.put("noWorkStatus", "3");//出差未打卡不算
                int signNum = workScheduleAttendanceService.findCountByParams(pi.getId(), startDate, endDate, searchParams10);
                wsaDTO.setSignNum(signNum);

                //请假天数leaveNum
//                Map<String,Object> searchParams12 = new HashMap<>();
//                searchParams12.put("workStatus","4");
//                BigDecimal leaveNum = workScheduleAttendanceService.findLeaveNum(pi.getId(),startDate,endDate,searchParams12);
                BigDecimal leaveNum = requestForLeaveInfoService.sumDaysByPersonIdAndTimeRange(pi.getId(), startDate, endDate);
                wsaDTO.setLeaveNum(leaveNum);

                //String remark = queryRemark(String.valueOf(pi.getId()),startMonth,endMonth);
                String remark = statScheduleAttendanceByDate(pi.getId(), startDate, endDate);
                wsaDTO.setRemark(remark);

                //工作时长
                Map<String, Object> workMinuteParams = new HashMap<>();
                workMinuteParams.put("classify", "2");

                BigDecimal workMinutes = workScheduleAttendanceService.findSumWorkMinuteByParams(pi.getId(), startDate, endDate, workMinuteParams);

                wsaDTO.setWorkTimes(formatTime(workMinutes.intValue()));
                wsaList.add(wsaDTO);
            }

            msgMap.put("wsaList", wsaList);
            msgMap.put("recordsTotal", page.getTotal());
            msgMap.put("recordsFiltered", page.getTotal());
            msgMap.put("totalPage", page.getPages());
            msgMap.put("pageNumber", page.getPageNum());
            msgMap.put("pageSize", page.getPageSize());
            msgResult.setResult(true);
            msgResult.setData(msgMap);
        } catch (Exception ex) {
            ex.printStackTrace();
            logger.error(ex.getMessage(), ex);
            msgResult.setResult(false);
            msgResult.setMessage("查询失败");
        }

        return msgResult;
    }

    /**
     * 查询人员班次按天考勤次数
     *
     * @param personId
     * @param startDate
     * @param endDate
     * @return
     */
    private String statScheduleAttendanceByDate(Long personId, Date startDate, Date endDate) {
        List<Map> mapList = workScheduleAttendanceService.statScheduleAttendanceByDate(personId, startDate, endDate);

        StringBuilder sb = new StringBuilder();

        for (Map map : mapList) {
            if (sb.length() > 0) {
                sb.append(",");
            }

            String shiftId = map.get("workShiftId").toString();
            WorkShiftInfo workShiftInfo = workShiftInfoService.get(shiftId);
            Long dayCount = Long.valueOf(map.get("dayCount").toString());

            if (workShiftInfo != null) {
                sb.append(workShiftInfo.getName() + ":" + dayCount + "次");
            }
        }

        return sb.toString();
    }


    public String queryRemark(String personId, String startMonth, String endMonth) {

        String workShiftDayNotes = "";

        try {
            Map<String, Object> searchParams = new HashMap<>();

            if (StringUtils.isNotEmpty(personId)) {
                searchParams.put("personId", personId);
            } else {
                return "";
            }

            List<String> months = new ArrayList<>();

            if (StringUtils.isNotEmpty(startMonth) && StringUtils.isNotEmpty(endMonth)) {
                searchParams.put("startMonth", startMonth + "%");
                searchParams.put("endMonth", endMonth + "%");

                months.add(startMonth + "%");
                months.add(endMonth + "%");
            }

            PersonInfo pi = personInfoService.get(Long.valueOf(personId));

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            //获取需要统计的日期
            List<Date> schedulingDayList = workPersonSchedulingService.findSchedulingDayByPersonIdSDateAndEDate(pi.getId(), sdf.parse(startMonth), sdf.parse(endMonth), true);

            //统计班次次数
            Map<String, Object> workShiftDayMap = new HashMap<>();

            for (Date attendanceDate : schedulingDayList) {
                WorkPersonScheduling wps = workPersonSchedulingService.findByPersonIdSchedulingDay(pi.getId(), attendanceDate);
                PersonInfoDayWSADTO wsaDayDTO = new PersonInfoDayWSADTO();
                if (wps != null) {
                    String shifts = wps.getShiftIds();

                    if (shifts != null) {
                        String[] shiftIds = shifts.split(",");
                        for (int i = 0; i < shiftIds.length; i++) {
                            String shiftId = shiftIds[i];

                            WorkShiftInfo workShiftInfo = workShiftInfoService.get(shiftId);

                            int workShiftNum = 0;
                            if (workShiftDayMap.get(workShiftInfo.getName()) != null) {
                                workShiftNum = Integer.parseInt(workShiftDayMap.get(workShiftInfo.getName()).toString());
                            }
                            if (workShiftNum > 0) {
                                workShiftDayMap.replace(workShiftInfo.getName(), workShiftNum + 1);
                            } else {
                                workShiftDayMap.put(workShiftInfo.getName(), workShiftNum + 1);
                            }
                        }
                    }
                }
            }

            Set<Map.Entry<String, Object>> entryseSet = workShiftDayMap.entrySet();

            for (Map.Entry<String, Object> entry : entryseSet) {
                workShiftDayNotes = workShiftDayNotes + "" + entry.getKey() + ":" + entry.getValue() + "次;";
            }

        } catch (Exception ex) {
            ex.printStackTrace();
            logger.error(ex.getMessage(), ex);
        }

        return workShiftDayNotes;
    }

    @ApiOperation(value = "后勤-考勤按月统计")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "companyId", value = "单位编号", required = true, paramType = "form"),
            @ApiImplicitParam(name = "subordinate", value = "是否查询下级单位", required = false, paramType = "form", dataType = "String"),
            @ApiImplicitParam(name = "name", value = "用户姓名", required = true, paramType = "form"),
            @ApiImplicitParam(name = "startDate", value = "开始时间", required = true, paramType = "form"),
            @ApiImplicitParam(name = "endDate", value = "截止时间", required = true, paramType = "form"),
            @ApiImplicitParam(name = "subject", value = "subject", required = false, paramType = "form")
    })
    @RequestMapping(value = "hqAttendanceMonth", method = RequestMethod.POST)
    public MessageResult<Map> hqAttendanceMonth(
            @RequestParam(value = "companyId", defaultValue = "") String companyId,
            @RequestParam(value = "subordinate", defaultValue = "false") Boolean subordinate,
            @RequestParam(value = "name", defaultValue = "") String name,
            @RequestParam(value = "jobNumber", defaultValue = "") String jobNumber,
            @RequestParam(value = "popedomRemark", defaultValue = "") String popedomRemark,
            @DateTimeFormat(pattern = "") String startMonth,
            @DateTimeFormat(pattern = "") String endMonth,
            @RequestParam(value = "pageIndex", defaultValue = "1") int pageIndex,
            @RequestParam(value = "pageSize", defaultValue = "10") int pageSize,
            @RequestAttribute String subject) {

        //当前用户ID
        System.out.println(subject);

        MessageResult<Map> msgResult = new MessageResult<>();
        try {


            Map<String, Object> searchParams = new HashMap<>();
            Map<String, Object> msgMap = new HashMap<>();

            List<Sort> sortList = new ArrayList<>();
            sortList.add(new Sort("a.hq_sort_no", "asc"));

            if (StringUtils.isNotEmpty(name)) {
                String[] names = name.split(",");
                List nameList = new ArrayList();
                for (String n : names) {
                    nameList.add("%" + n + "%");
                }
                searchParams.put("nameList", nameList);
            }

            if (StringUtils.isNotEmpty(companyId)) {
                if ("hq1".equals(companyId)) {
                    //外勤1
//                    List<CompanyInfo> list1 = companyInfoService.findByClassify("1");
//                    searchParams.put("companyInfos", list1);
                    searchParams.put("hqStatus", "1");
                } else if ("hq2".equals(companyId)) {
                    //外勤2
//                    List<CompanyInfo> list2 = companyInfoService.findByClassify("2");
//                    searchParams.put("companyInfos", list2);
                    searchParams.put("hqStatus", "2");
                } else {
                    CompanyInfo parentCompanyInfo = companyInfoService.get(companyId);
                    String parentCode = parentCompanyInfo.getCode();
                    if (subordinate) {
                        searchParams.put("attendanceCompanyCode", parentCode + "%");
                    } else {
                        searchParams.put("attendanceCompanyCode", parentCode);
                    }

                    searchParams.put("hqStatus", parentCompanyInfo.getClassify());
                }
            } else {
                searchParams.put("querHq", "yes");
            }

            if (StringUtils.isNotEmpty(jobNumber)) {
                searchParams.put("jobNumber", jobNumber);
            }

            if (StringUtils.isNotEmpty(popedomRemark)) {
                List<String> popedomRemarkList = Arrays.asList(popedomRemark.split(","));
                searchParams.put("popedomRemarkList", popedomRemarkList);
            }

            Page<PersonInfo> page = personInfoService.pageSearch(searchParams, pageIndex, pageSize, true, sortList);
            List<PersonInfoMonthWSADTO> wsaList = new ArrayList<>();

            //头部是月份
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date startDate = sdf.parse(startMonth + " 00:00:00");
            Date endDate = sdf.parse(endMonth + " 23:59:59");
//            Boolean isDateEq = false;
//
//            //获取开始查询的年月
//            Map<String, Object> startMap = getDayByMonth(startDate);
//            int sYear = Integer.parseInt(startMap.get("year").toString());
//            int sMonth = Integer.parseInt(startMap.get("month").toString());
//            List<Integer> months = new ArrayList<>();
//
//
//            months.add(sMonth);
//            if(startDate.equals(endDate)){
//                //如果日期相同 查的同年月
//                isDateEq = true;
//            }else {
//                //获取结束查询的年月
//                Map<String, Object> endMap = getDayByMonth(endDate);
//                int eMonth = Integer.parseInt(endMap.get("month").toString());
//                months.add(eMonth);
//            }
//
//            List<String> dateLst = new ArrayList<>();
//            dateLst.add(startMonth + "%");
//            dateLst.add(endMonth + "%");

            //应出勤天数attendanceDays
            //按照要求 直接统计天数
            //直接统计开始日期到结束日期的天数 - 周日 = 应出勤天数
            Date queryDateStart = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(startMonth + " 00:00:00");
            Date queryDateEnd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(endMonth + " 23:59:59");
            int attendanceDays = calculateNotSunDays(queryDateStart, queryDateEnd);

            for (PersonInfo pi : page.getResult()) {
                PersonInfoMonthWSADTO wsaDTO = new PersonInfoMonthWSADTO();
                wsaDTO.setPersonInfo(pi);
                CompanyInfo ci = companyInfoService.get(pi.getCompanyId());
                if (StringUtils.isNotEmpty(ci.getFullName())) {
                    wsaDTO.setCompanyName(ci.getFullName());
                } else {
                    wsaDTO.setCompanyName(ci.getName());
                }
                //出差次数businessTripNum
//                Map<String,Object> searchParams11 = new HashMap<>();
//                searchParams11.put("workStatus","3");
//                BigDecimal businessTripNum = workScheduleAttendanceService.findBusinessTripNum(pi.getId(),startDate,endDate,searchParams11);
                BigDecimal businessTripNum = businessOutService.sumDaysByPersonIdAndTimeRange(pi.getId(), startDate, endDate);
                wsaDTO.setBusinessTripNum(businessTripNum);

                //请年假天数yearLeaveNum
                BigDecimal yearLeaveNum = yearRequestForLeaveInfoService.sumDaysByPersonIdAndTimeRange(pi.getId(), startDate, endDate);
                wsaDTO.setYearLeaveNum(yearLeaveNum);

                //先查总班次 确认正常上班和休息
//                List<WorkPersonScheduling> startWorkPersonScheduling
//                        = workPersonSchedulingService.findByPersonIdSDateAndEDate(pi.getId(),startDate,endDate,false);

                //应出勤天数attendanceDays
                wsaDTO.setAttendanceDays(new BigDecimal(attendanceDays));
                //先查总班次 确认正常上班和休息
//                List<WorkPersonScheduling> startWorkPersonScheduling
//                        = workPersonSchedulingService.findByPersonIdSDateAndEDate(pi.getId(),startDate,endDate,false);

                //全勤天数totalAttendanceDays
                BigDecimal totalAttendanceDays = workScheduleAttendanceService.findTotalAttendance(pi.getId(), startDate, endDate, "1");
                totalAttendanceDays = totalAttendanceDays.add(businessTripNum);

                //加上年假天数
                totalAttendanceDays = totalAttendanceDays.add(yearLeaveNum);

                wsaDTO.setTotalAttendanceDays(totalAttendanceDays);
                //迟到分钟lateMinutes
                Map<String, Object> searchParams3 = new HashMap<>();
                searchParams3.put("result", "2");
                Double lateMinutes = workScheduleAttendanceService.findSumLMinuteByParams(pi.getId(), startDate, endDate, searchParams3);
                wsaDTO.setLateMinutes(lateMinutes);
                //迟到次数lateNum
                Map<String, Object> searchParams4 = new HashMap<>();
                searchParams4.put("result", "2");
                searchParams4.put("classify", "1");//上班
                int lateNum = workScheduleAttendanceService.findCountByParams(pi.getId(), startDate, endDate, searchParams4);
                wsaDTO.setLateNum(lateNum);
                //早退分钟leaveEarlyMinutes
                Map<String, Object> searchParams5 = new HashMap<>();
                searchParams5.put("result", "3");
                Double leaveEarlyMinutes = workScheduleAttendanceService.findSumLMinuteByParams(pi.getId(), startDate, endDate, searchParams5);
                wsaDTO.setLeaveEarlyMinutes(leaveEarlyMinutes);
                //早退次数leaveEarlyNum
                Map<String, Object> searchParams6 = new HashMap<>();
                searchParams6.put("result", "3");
                searchParams6.put("classify", "2");//下班
                int leaveEarlyNum = workScheduleAttendanceService.findCountByParams(pi.getId(), startDate, endDate, searchParams6);
                wsaDTO.setLeaveEarlyNum(leaveEarlyNum);
                //加班小时overtime
                int overtime = workScheduleAttendanceService.findHqOvertimeByPersonIdAndSEDate(pi.getId(), startDate, endDate);
                wsaDTO.setOvertime(formatTime(overtime));
                //未刷次数notSwipingNum = 旷工次数
                Map<String, Object> searchParams9 = new HashMap<>();
                searchParams9.put("result", "0");
                searchParams9.put("noWorkStatus7", "7");//年假未打卡不算
                int notSwipingNum = workScheduleAttendanceService.findCountByParams(pi.getId(), startDate, endDate, searchParams9);
                wsaDTO.setNotSwipingNum(notSwipingNum);
                //签到次数signNum
                Map<String, Object> searchParams10 = new HashMap<>();
                //0为未打卡 不等于0的为签到
                searchParams10.put("noResult", "0");
                int signNum = workScheduleAttendanceService.findCountByParams(pi.getId(), startDate, endDate, searchParams10);
                wsaDTO.setSignNum(signNum);

                //旷工天数absenteeismDays====>加班天数
                //实际出勤天数totalAttendanceDays - attendanceDays应出勤天数
                BigDecimal absenteeismCount = BigDecimal.ZERO;
                absenteeismCount = totalAttendanceDays.subtract(new BigDecimal(attendanceDays));
                if (absenteeismCount.compareTo(BigDecimal.ZERO) > 0) {
                    wsaDTO.setAbsenteeismDays(absenteeismCount);
                } else {
                    wsaDTO.setAbsenteeismDays(BigDecimal.ZERO);
                }
                //请假天数leaveNum
//                BigDecimal leaveNum = BigDecimal.ZERO;
//                //attendanceDays应出勤天数-实际出勤天数totalAttendanceDays
//                leaveNum = new BigDecimal(attendanceDays).subtract(totalAttendanceDays);
//                if(leaveNum.compareTo(BigDecimal.ZERO) > 0){
//                    wsaDTO.setLeaveNum(leaveNum);
//                }else {
//                    wsaDTO.setLeaveNum(BigDecimal.ZERO);
//                }
                //请假天数leaveNum
                BigDecimal leaveNum = requestForLeaveInfoService.sumDaysByPersonIdAndTimeRange(pi.getId(), startDate, endDate);
                wsaDTO.setLeaveNum(leaveNum);

                //休息天数
                //查询的总天数-实际出勤天数
                //实际出勤天数totalAttendanceDays
                BigDecimal restDays = BigDecimal.ZERO;
                int daysBetween = daysBetween(startMonth, endMonth) + 1;
                restDays = new BigDecimal(daysBetween).subtract(totalAttendanceDays);
                if (restDays.compareTo(BigDecimal.ZERO) > 0) {
                    wsaDTO.setRestDays(restDays);
                } else {
                    wsaDTO.setRestDays(BigDecimal.ZERO);
                }
                wsaList.add(wsaDTO);

            }

            msgMap.put("wsaList", wsaList);
            msgMap.put("recordsTotal", page.getTotal());
            msgMap.put("recordsFiltered", page.getTotal());
            msgMap.put("totalPage", page.getPages());
            msgMap.put("pageNumber", page.getPageNum());
            msgMap.put("pageSize", page.getPageSize());
            msgResult.setResult(true);
            msgResult.setData(msgMap);
        } catch (Exception ex) {
            ex.printStackTrace();
            logger.error(ex.getMessage(), ex);
            msgResult.setResult(false);
            msgResult.setMessage("查询失败");
        }

        return msgResult;
    }

    @ApiOperation(value = "考勤按月统计详细")
    @RequestMapping(value = "attendanceMonthDetail", method = RequestMethod.POST)
    public MessageResult<Map> attendanceMonthDetail(
            @RequestParam(value = "personId", defaultValue = "") String personId,
            @DateTimeFormat(pattern = "") String startMonth,
            @DateTimeFormat(pattern = "") String endMonth,
            @RequestAttribute String subject) {

        //当前用户ID
        System.out.println(subject);

        MessageResult<Map> msgResult = new MessageResult<>();
        Map<String, Object> resultMap = new HashMap<>();

        try {
            Map<String, Object> searchParams = new HashMap<>();

            if (StringUtils.isNotEmpty(personId)) {
                searchParams.put("personId", personId);
            }

            List<String> months = new ArrayList<>();

            if (StringUtils.isNotEmpty(startMonth) && StringUtils.isNotEmpty(endMonth)) {
                searchParams.put("startMonth", startMonth + "%");
                searchParams.put("endMonth", endMonth + "%");

                months.add(startMonth + "%");
                months.add(endMonth + "%");
            }

            PersonInfo pi = personInfoService.get(Long.valueOf(personId));
            List<PersonInfoDayWSADTO> wsaDTOList = new ArrayList<>();

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            //获取需要统计的日期
            //List<Date> attendanceList = workScheduleAttendanceService.findAttendanceDateByPersonAndMonths(Long.valueOf(personId),months);
            List<Date> schedulingDayList = workPersonSchedulingService.findSchedulingDayByPersonIdSDateAndEDate(pi.getId(), sdf.parse(startMonth), sdf.parse(endMonth), true);

            //统计班次次数
            Map<String, Object> workShiftDayMap = new HashMap<>();

            for (Date attendanceDate : schedulingDayList) {
                //wsaDTO.setPersonInfo(pi);
                WorkPersonScheduling wps = workPersonSchedulingService.findByPersonIdSchedulingDay(pi.getId(), attendanceDate);
                boolean exist = false;
                PersonInfoDayWSADTO wsaDayDTO = new PersonInfoDayWSADTO();
                if (wps != null) {
                    String shifts = wps.getShiftIds();

                    wsaDayDTO.setPersonInfo(pi);
                    wsaDayDTO.setShiftIds(shifts);
                    List<String> shiftNumbers = new ArrayList<>();

                    if (shifts != null) {
                        String[] shiftIds = shifts.split(",");
                        //未刷次数
                        int notSwipingNum = 0;
                        for (int i = 0; i < shiftIds.length; i++) {
                            String shiftId = shiftIds[i];

                            WorkShiftInfo workShiftInfo = workShiftInfoService.get(shiftId);
                            String shiftNumber = workShiftInfo.getNumber();

                            int workShiftNum = 0;
                            if (workShiftDayMap.get(workShiftInfo.getName()) != null) {
                                workShiftNum = Integer.parseInt(workShiftDayMap.get(workShiftInfo.getName()).toString());
                            }
                            if (workShiftNum > 0) {
                                workShiftDayMap.replace(workShiftInfo.getName(), workShiftNum + 1);
                            } else {
                                workShiftDayMap.put(workShiftInfo.getName(), workShiftNum + 1);
                            }


                            shiftNumbers.add(workShiftInfo.getNumber());

                            List<WorkScheduleAttendance> wsaList = workScheduleAttendanceService.findByPersonIdAndShiftIdAndAttendanceDate(pi.getId(), shiftId, sdf.format(attendanceDate));
                            //单排班只有2条记录 1条上班1条下班

                            wsaDayDTO.setPersonInfo(pi);
                            wsaDayDTO.setAttendanceDate(attendanceDate);

                            String onWorkResult = "50";
                            String onWorkStatus = "";
                            String onWorkStatusN = "";
                            Date onWorkRecordTime = null;
                            BigDecimal onLateLeaveMinute = BigDecimal.ZERO;
                            String onLateLeaveMinuteN = "";
                            String onSupplementWork = "";

                            String offWorkResult = "50";
                            String offWorkStatus = "";
                            String offWorkStatusN = "";
                            Date offWorkRecordTime = null;
                            BigDecimal offLateLeaveMinute = BigDecimal.ZERO;
                            String offLateLeaveMinuteN = "";
                            String offSupplementWork = "";

                            if ("0".equals(shiftNumber)) {
                                //休息
                                onWorkResult = "10";
                                offWorkResult = "10";
                            } else {
                                if (wsaList.size() < 1) {
                                    //没有考勤记录
                                    notSwipingNum = notSwipingNum + 2;
                                    onWorkResult = "50";
                                    offWorkResult = "50";
                                }
                            }


                            for (WorkScheduleAttendance wsa : wsaList) {
                                String workStatusN = dataDictionaryService.findNameByCatalogNameAndValue("工作状态", wsa.getWorkStatus());
                                //旷工天数absenteeismDays
                                List<String> days = new ArrayList<>();
                                days.add(wsa.getAttendanceDate());
                                BigDecimal absenteeismCount = workScheduleAttendanceService.findAbsenteeism(pi.getId(), sdf.parse(wsa.getAttendanceDate()), sdf.parse(wsa.getAttendanceDate()), "0");
                                wsaDayDTO.setAbsenteeismDays(absenteeismCount);

                                if ("1".equals(wsa.getClassify())) {
                                    //上班
                                    if ("补卡".equals(wsa.getRemark())) {
                                        //补卡为11
                                        onWorkResult = "11";

                                        //"补卡原因";
                                        if (StringUtils.isNotEmpty(wsa.getSupplementWorkPersonId())) {
                                            SupplementWorkPerson supplementWorkPerson = supplementWorkPersonService.get(wsa.getSupplementWorkPersonId());
                                            if(supplementWorkPerson != null){
                                                SupplementWork supplementWork = supplementWorkService.get(supplementWorkPerson.getSupplementWorkId());
                                                if(supplementWork != null){
                                                    onSupplementWork = supplementWork.getReason();
                                                }
                                            }
                                        }
                                    } else if ("3".equals(wsa.getWorkStatus())) {
                                        //出差
                                        onWorkResult = "9";
                                    } else if ("4".equals(wsa.getWorkStatus())) {
                                        //请假
                                        onWorkResult = "13";
                                    }
                                    else if ("7".equals(wsa.getWorkStatus())) {
                                        //年假
                                        onWorkResult = "14";
                                    }
                                    else if (StringUtils.isEmpty(wsa.getWorkStatus())) {
                                        onWorkResult = "";
                                    } else {
                                        onWorkResult = wsa.getResult();
                                    }
                                    onWorkStatus = wsa.getWorkStatus();
                                    onWorkStatusN = workStatusN;
                                    onWorkRecordTime = wsa.getRecordTime();
                                    if (wsa.getLateLeaveMinute() != null) {
                                        onLateLeaveMinuteN = formatTime(wsa.getLateLeaveMinute().intValue());
                                    }
                                    onLateLeaveMinute = onLateLeaveMinute;
                                    if ("0".equals(wsa.getResult()) && !"3".equals(wsa.getWorkStatus())&& !"7".equals(wsa.getWorkStatus())) {
                                        notSwipingNum++;
                                    }
                                } else if ("2".equals(wsa.getClassify())) {
                                    //下班
                                    if ("补卡".equals(wsa.getRemark())) {
                                        //补卡为11
                                        offWorkResult = "11";

                                        //"补卡原因";
                                        if (StringUtils.isNotEmpty(wsa.getSupplementWorkPersonId())) {
                                            SupplementWorkPerson supplementWorkPerson = supplementWorkPersonService.get(wsa.getSupplementWorkPersonId());
                                            if(supplementWorkPerson != null){
                                                SupplementWork supplementWork = supplementWorkService.get(supplementWorkPerson.getSupplementWorkId());
                                                if(supplementWork != null){
                                                    offSupplementWork = supplementWork.getReason();
                                                }
                                            }
                                        }
                                    } else if ("3".equals(wsa.getWorkStatus())) {
                                        //出差
                                        offWorkResult = "9";
                                    } else if (StringUtils.isEmpty(wsa.getWorkStatus())) {
                                        offWorkResult = "";
                                    } else if ("4".equals(wsa.getWorkStatus())) {
                                        //请假
                                        offWorkResult = "13";
                                    }
                                    else if ("7".equals(wsa.getWorkStatus())) {
                                        //请假
                                        offWorkResult = "14";
                                    }
                                    else if (StringUtils.isNotEmpty(wsa.getWorkOverPersonId())) {
                                        //为加班 只有下班存在 加班字段不为空代表加班
                                        offWorkResult = "12";
                                    } else {
                                        offWorkResult = wsa.getResult();
                                    }
                                    offWorkStatus = wsa.getWorkStatus();
                                    offWorkStatusN = workStatusN;
                                    offWorkRecordTime = wsa.getRecordTime();
                                    if (wsa.getLateLeaveMinute() != null) {
                                        offLateLeaveMinuteN = formatTime(wsa.getLateLeaveMinute().intValue());
                                    }
                                    offLateLeaveMinute = offLateLeaveMinute;
                                    if ("0".equals(wsa.getResult()) && !"3".equals(wsa.getWorkStatus())&& !"7".equals(wsa.getWorkStatus())) {
                                        notSwipingNum++;
                                    }
                                }
                            }

                            if (i == 0) {
                                wsaDayDTO.setOnWorkResult1(onWorkResult);
                                wsaDayDTO.setOnWorkStatus1(onWorkStatus);
                                wsaDayDTO.setOnWorkStatus1N(onWorkStatusN);
                                wsaDayDTO.setOnWorkRecordTime1(onWorkRecordTime);
                                wsaDayDTO.setOnLateLeaveMinute1(onLateLeaveMinute);
                                wsaDayDTO.setOnLateLeaveMinute1N(onLateLeaveMinuteN);
                                wsaDayDTO.setOnSupplementWork1(onSupplementWork);

                                wsaDayDTO.setOffWorkResult1(offWorkResult);
                                wsaDayDTO.setOffWorkStatus1(offWorkStatus);
                                wsaDayDTO.setOffWorkStatus1N(offWorkStatusN);
                                wsaDayDTO.setOffWorkRecordTime1(offWorkRecordTime);
                                wsaDayDTO.setOffLateLeaveMinute1(offLateLeaveMinute);
                                wsaDayDTO.setOffLateLeaveMinute1N(offLateLeaveMinuteN);
                                wsaDayDTO.setOffSupplementWork1(offSupplementWork);
                            } else if (i == 1) {
                                wsaDayDTO.setOnWorkResult2(onWorkResult);
                                wsaDayDTO.setOnWorkStatus2(onWorkStatus);
                                wsaDayDTO.setOnWorkStatus2N(onWorkStatusN);
                                wsaDayDTO.setOnWorkRecordTime2(onWorkRecordTime);
                                wsaDayDTO.setOnLateLeaveMinute2(onLateLeaveMinute);
                                wsaDayDTO.setOnLateLeaveMinute2N(onLateLeaveMinuteN);
                                wsaDayDTO.setOnSupplementWork2(onSupplementWork);

                                wsaDayDTO.setOffWorkResult2(offWorkResult);
                                wsaDayDTO.setOffWorkStatus2(offWorkStatus);
                                wsaDayDTO.setOffWorkStatus2N(offWorkStatusN);
                                wsaDayDTO.setOffWorkRecordTime2(offWorkRecordTime);
                                wsaDayDTO.setOffLateLeaveMinute2(offLateLeaveMinute);
                                wsaDayDTO.setOffLateLeaveMinute2N(offLateLeaveMinuteN);
                                wsaDayDTO.setOffSupplementWork2(offSupplementWork);
                            } else if (i == 2) {
                                wsaDayDTO.setOnWorkResult3(onWorkResult);
                                wsaDayDTO.setOnWorkStatus3(onWorkStatus);
                                wsaDayDTO.setOnWorkStatus3N(onWorkStatusN);
                                wsaDayDTO.setOnWorkRecordTime3(onWorkRecordTime);
                                wsaDayDTO.setOnLateLeaveMinute3(onLateLeaveMinute);
                                wsaDayDTO.setOnLateLeaveMinute3N(onLateLeaveMinuteN);
                                wsaDayDTO.setOnSupplementWork3(onSupplementWork);

                                wsaDayDTO.setOffWorkResult3(offWorkResult);
                                wsaDayDTO.setOffWorkStatus3(offWorkStatus);
                                wsaDayDTO.setOffWorkStatus3N(offWorkStatusN);
                                wsaDayDTO.setOffWorkRecordTime3(offWorkRecordTime);
                                wsaDayDTO.setOffLateLeaveMinute3(offLateLeaveMinute);
                                wsaDayDTO.setOffLateLeaveMinute3N(offLateLeaveMinuteN);
                                wsaDayDTO.setOffSupplementWork3(offSupplementWork);
                            }
                        }

                        wsaDayDTO.setNotSwipingNum(notSwipingNum);
                        String shiftNumberStrs = shiftNumbers.stream()
                                .map((shiftNumber) -> shiftNumber)
                                .collect(Collectors.joining(","));
                        wsaDayDTO.setShiftNumbers(shiftNumberStrs);
                        wsaDTOList.add(wsaDayDTO);

                        exist = true;
                    }
                }

                if (!exist) {
                    wsaDayDTO.setPersonInfo(pi);
                    wsaDayDTO.setAttendanceDate(attendanceDate);
                    //                    //上班
                    //                    wsaDayDTO.setOnWorkResult(wsa.getResult());
                    //                    wsaDayDTO.setOnWorkStatus(wsa.getWorkStatus());
                    //                    wsaDayDTO.setOnWorkStatusN(workStatusN);
                    //                    wsaDayDTO.setOnWorkRecordTime(wsa.getRecordTime());
                    //                    //下班
                    //                    wsaDayDTO.setOffWorkResult(wsa.getResult());
                    //                    wsaDayDTO.setOffWorkStatus(wsa.getWorkStatus());
                    //                    wsaDayDTO.setOffWorkStatusN(workStatusN);
                    //                    wsaDayDTO.setOffWorkRecordTime(wsa.getRecordTime());
                    wsaDTOList.add(wsaDayDTO);
                }
            }


            Set<Map.Entry<String, Object>> entryseSet = workShiftDayMap.entrySet();
            String workShiftDayNotes = "";
            for (Map.Entry<String, Object> entry : entryseSet) {
                workShiftDayNotes = workShiftDayNotes + "" + entry.getKey() + ":" + entry.getValue() + "次;";
            }

            resultMap.put("wsaList", wsaDTOList);
            resultMap.put("personInfo", pi);
            resultMap.put("workShiftDayNotes", workShiftDayNotes);

            msgResult.setResult(true);
            msgResult.setData(resultMap);
        } catch (Exception ex) {
            ex.printStackTrace();
            logger.error(ex.getMessage(), ex);
            msgResult.setResult(false);
            msgResult.setMessage("查询失败");
        }

        return msgResult;
    }

    @ApiOperation(value = "考勤按日统计")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "companyId", value = "单位编号", required = true, paramType = "form"),
            @ApiImplicitParam(name = "subordinate", value = "是否查询下级单位", required = false, paramType = "form", dataType = "String"),
            @ApiImplicitParam(name = "name", value = "用户姓名", required = true, paramType = "form"),
            @ApiImplicitParam(name = "queryDate", value = "查询日期", required = true, paramType = "form"),
            @ApiImplicitParam(name = "subject", value = "subject", required = false, paramType = "form")
    })
    @RequestMapping(value = "attendanceDay", method = RequestMethod.POST)
    public MessageResult<Map> attendanceDay(
            @RequestParam(value = "companyId", defaultValue = "") String companyId,
            @RequestParam(value = "subordinate", defaultValue = "false") Boolean subordinate,
            @RequestParam(value = "name", defaultValue = "") String name,
            @RequestParam(value = "jobNumber", defaultValue = "") String jobNumber,
            @RequestParam(value = "popedomRemark", defaultValue = "") String popedomRemark,
            @RequestParam(value = "queryDate", defaultValue = "") String queryDate,
            @RequestParam(value = "pageIndex", defaultValue = "0") int pageIndex,
            @RequestParam(value = "pageSize", defaultValue = "100000") int pageSize,
            @RequestAttribute String subject) {

        //当前用户ID
        System.out.println(subject);

        MessageResult<Map> msgResult = new MessageResult<>();
        try {


            Map<String, Object> searchParams = new HashMap<>();
            Map<String, Object> msgMap = new HashMap<>();

            List<Sort> sortList = new ArrayList<>();
            sortList.add(new Sort("a.id_", "asc"));

            if (StringUtils.isNotEmpty(name)) {
                String[] names = name.split(",");
                List nameList = new ArrayList();
                for (String n : names) {
                    nameList.add("%" + n + "%");
                }
                searchParams.put("nameList", nameList);
            }

            if (StringUtils.isNotEmpty(companyId)) {
                CompanyInfo parentCompanyInfo = companyInfoService.get(companyId);
                String parentCode = parentCompanyInfo.getCode();
                if (subordinate) {
                    searchParams.put("companyCode", parentCode + "%");
                } else {
                    searchParams.put("companyCode", parentCode);
                }
            }

            if (StringUtils.isNotEmpty(jobNumber)) {
                searchParams.put("jobNumber", jobNumber);
            }

            if (StringUtils.isNotEmpty(popedomRemark)) {
                List<String> popedomRemarkList = Arrays.asList(popedomRemark.split(","));
                searchParams.put("popedomRemarkList", popedomRemarkList);
            }

            Page<PersonInfo> page = personInfoService.pageSearch(searchParams, pageIndex, pageSize, false, sortList);
            List<PersonInfoDayWSADTO> perWsaList = new ArrayList<>();

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            for (PersonInfo pi : page.getResult()) {
                //查询用户当日排班
                WorkPersonScheduling wps = workPersonSchedulingService.findByPersonIdSchedulingDay(pi.getId(), sdf.parse(queryDate));

                boolean exist = false;

                PersonInfoDayWSADTO wsaDayDTO = new PersonInfoDayWSADTO();

                if (wps != null) {
                    String shifts = wps.getShiftIds();

                    wsaDayDTO.setPersonInfo(pi);
                    wsaDayDTO.setShiftIds(shifts);
                    List<String> shiftNumbers = new ArrayList<>();

                    if (shifts != null) {
                        //List<String> shiftList = workScheduleAttendanceService.findShiftByPersonAndAttendanceDate(pi.getId(), queryDate);
                        String[] shiftIds = shifts.split(",");
                        //未刷次数
                        int notSwipingNum = 0;
                        for (int i = 0; i < shiftIds.length; i++) {
                            String shiftId = shiftIds[i];
                            String shiftNumber = workShiftInfoService.findNumberById(shiftId);
                            shiftNumbers.add(shiftNumber);

                            List<WorkScheduleAttendance> wsaList = workScheduleAttendanceService.findByPersonIdAndShiftIdAndAttendanceDate(pi.getId(), shiftId, queryDate);
                            //单排班只有2条记录 1条上班1条下班

                            wsaDayDTO.setPersonInfo(pi);
                            wsaDayDTO.setAttendanceDate(sdf.parse(queryDate));

                            String onWorkResult = "50";
                            String onWorkStatus = "";
                            String onWorkStatusN = "";
                            Date onWorkRecordTime = null;
                            BigDecimal onLateLeaveMinute = BigDecimal.ZERO;
                            String onLateLeaveMinuteN = "";
                            String onSupplementWork = "";

                            String offWorkResult = "50";
                            String offWorkStatus = "";
                            String offWorkStatusN = "";
                            Date offWorkRecordTime = null;
                            BigDecimal offLateLeaveMinute = BigDecimal.ZERO;
                            String offLateLeaveMinuteN = "";
                            String offSupplementWork = "";

                            if ("0".equals(shiftNumber)) {
                                //休息
                                onWorkResult = "10";
                                offWorkResult = "10";
                            } else {
                                if (wsaList.size() < 1) {
                                    //没有考勤记录
                                    notSwipingNum = notSwipingNum + 2;
                                    onWorkResult = "50";
                                    offWorkResult = "50";
                                }
                            }


                            for (WorkScheduleAttendance wsa : wsaList) {
                                String workStatusN = dataDictionaryService.findNameByCatalogNameAndValue("工作状态", wsa.getWorkStatus());
                                //旷工天数absenteeismDays
                                List<String> days = new ArrayList<>();
                                days.add(wsa.getAttendanceDate());
                                BigDecimal absenteeismCount = workScheduleAttendanceService.findAbsenteeism(pi.getId(), sdf.parse(wsa.getAttendanceDate()), sdf.parse(wsa.getAttendanceDate()), "0");
                                wsaDayDTO.setAbsenteeismDays(absenteeismCount);

                                if ("1".equals(wsa.getClassify())) {
                                    //上班
                                    if ("补卡".equals(wsa.getRemark())) {
                                        //补卡为11
                                        onWorkResult = "11";
                                        //"补卡原因";
                                        if (StringUtils.isNotEmpty(wsa.getSupplementWorkPersonId())) {
                                            SupplementWorkPerson supplementWorkPerson = supplementWorkPersonService.get(wsa.getSupplementWorkPersonId());
                                            if(supplementWorkPerson != null){
                                                SupplementWork supplementWork = supplementWorkService.get(supplementWorkPerson.getSupplementWorkId());
                                                if(supplementWork != null){
                                                    onSupplementWork = supplementWork.getReason();
                                                }
                                            }
                                        }
                                    } else if ("3".equals(wsa.getWorkStatus())) {
                                        //出差
                                        onWorkResult = "9";
                                    } else if ("4".equals(wsa.getWorkStatus())) {
                                        //请假
                                        onWorkResult = "13";
                                    }
                                    else if ("7".equals(wsa.getWorkStatus())) {
                                        //请假
                                        onWorkResult = "14";
                                    }
                                    else if (StringUtils.isEmpty(wsa.getWorkStatus())) {
                                        onWorkResult = "";
                                    } else {
                                        onWorkResult = wsa.getResult();
                                    }


                                    onWorkStatus = wsa.getWorkStatus();
                                    onWorkStatusN = workStatusN;
                                    onWorkRecordTime = wsa.getRecordTime();
                                    if (wsa.getLateLeaveMinute() != null) {
                                        onLateLeaveMinuteN = formatTime(wsa.getLateLeaveMinute().intValue());
                                    }
                                    onLateLeaveMinute = onLateLeaveMinute;
                                    if ("0".equals(wsa.getResult())) {
                                        notSwipingNum++;
                                    }
                                } else if ("2".equals(wsa.getClassify())) {
                                    //下班
                                    if ("补卡".equals(wsa.getRemark())) {
                                        //补卡为11
                                        offWorkResult = "11";

                                        //"补卡原因";
                                        if (StringUtils.isNotEmpty(wsa.getSupplementWorkPersonId())) {
                                            SupplementWorkPerson supplementWorkPerson = supplementWorkPersonService.get(wsa.getSupplementWorkPersonId());
                                            if(supplementWorkPerson != null){
                                                SupplementWork supplementWork = supplementWorkService.get(supplementWorkPerson.getSupplementWorkId());
                                                if(supplementWork != null){
                                                    offSupplementWork = supplementWork.getReason();
                                                }
                                            }
                                        }
                                    } else if ("3".equals(wsa.getWorkStatus())) {
                                        //出差
                                        offWorkResult = "9";
                                    } else if ("4".equals(wsa.getWorkStatus())) {
                                        //请假
                                        offWorkResult = "13";
                                    }
                                    else if ("7".equals(wsa.getWorkStatus())) {
                                        //年假
                                        offWorkResult = "14";
                                    }
                                    else if (StringUtils.isEmpty(wsa.getWorkStatus())) {
                                        offWorkResult = "";
                                    } else if (StringUtils.isNotEmpty(wsa.getWorkOverPersonId())) {
                                        //为加班 只有下班存在 加班字段不为空代表加班
                                        offWorkResult = "12";
                                    } else {
                                        offWorkResult = wsa.getResult();
                                    }
                                    offWorkStatus = wsa.getWorkStatus();
                                    offWorkStatusN = workStatusN;
                                    offWorkRecordTime = wsa.getRecordTime();
                                    if (wsa.getLateLeaveMinute() != null) {
                                        offLateLeaveMinuteN = formatTime(wsa.getLateLeaveMinute().intValue());
                                    }
                                    offLateLeaveMinute = offLateLeaveMinute;
                                    if ("0".equals(wsa.getResult())) {
                                        notSwipingNum++;
                                    }
                                }
                            }

                            if (i == 0) {
                                wsaDayDTO.setOnWorkResult1(onWorkResult);
                                wsaDayDTO.setOnWorkStatus1(onWorkStatus);
                                wsaDayDTO.setOnWorkStatus1N(onWorkStatusN);
                                wsaDayDTO.setOnWorkRecordTime1(onWorkRecordTime);
                                wsaDayDTO.setOnLateLeaveMinute1(onLateLeaveMinute);
                                wsaDayDTO.setOnLateLeaveMinute1N(onLateLeaveMinuteN);
                                wsaDayDTO.setOnSupplementWork1(onSupplementWork);

                                wsaDayDTO.setOffWorkResult1(offWorkResult);
                                wsaDayDTO.setOffWorkStatus1(offWorkStatus);
                                wsaDayDTO.setOffWorkStatus1N(offWorkStatusN);
                                wsaDayDTO.setOffWorkRecordTime1(offWorkRecordTime);
                                wsaDayDTO.setOffLateLeaveMinute1(offLateLeaveMinute);
                                wsaDayDTO.setOffLateLeaveMinute1N(offLateLeaveMinuteN);
                                wsaDayDTO.setOffSupplementWork1(offSupplementWork);
                            } else if (i == 1) {
                                wsaDayDTO.setOnWorkResult2(onWorkResult);
                                wsaDayDTO.setOnWorkStatus2(onWorkStatus);
                                wsaDayDTO.setOnWorkStatus2N(onWorkStatusN);
                                wsaDayDTO.setOnWorkRecordTime2(onWorkRecordTime);
                                wsaDayDTO.setOnLateLeaveMinute2(onLateLeaveMinute);
                                wsaDayDTO.setOnLateLeaveMinute2N(onLateLeaveMinuteN);
                                wsaDayDTO.setOnSupplementWork2(onSupplementWork);

                                wsaDayDTO.setOffWorkResult2(offWorkResult);
                                wsaDayDTO.setOffWorkStatus2(offWorkStatus);
                                wsaDayDTO.setOffWorkStatus2N(offWorkStatusN);
                                wsaDayDTO.setOffWorkRecordTime2(offWorkRecordTime);
                                wsaDayDTO.setOffLateLeaveMinute2(offLateLeaveMinute);
                                wsaDayDTO.setOffLateLeaveMinute2N(offLateLeaveMinuteN);
                                wsaDayDTO.setOffSupplementWork2(offSupplementWork);
                            } else if (i == 2) {
                                wsaDayDTO.setOnWorkResult3(onWorkResult);
                                wsaDayDTO.setOnWorkStatus3(onWorkStatus);
                                wsaDayDTO.setOnWorkStatus3N(onWorkStatusN);
                                wsaDayDTO.setOnWorkRecordTime3(onWorkRecordTime);
                                wsaDayDTO.setOnLateLeaveMinute3(onLateLeaveMinute);
                                wsaDayDTO.setOnLateLeaveMinute3N(onLateLeaveMinuteN);
                                wsaDayDTO.setOnSupplementWork3(onSupplementWork);

                                wsaDayDTO.setOffWorkResult3(offWorkResult);
                                wsaDayDTO.setOffWorkStatus3(offWorkStatus);
                                wsaDayDTO.setOffWorkStatus3N(offWorkStatusN);
                                wsaDayDTO.setOffWorkRecordTime3(offWorkRecordTime);
                                wsaDayDTO.setOffLateLeaveMinute3(offLateLeaveMinute);
                                wsaDayDTO.setOffLateLeaveMinute3N(offLateLeaveMinuteN);
                                wsaDayDTO.setOffSupplementWork3(offSupplementWork);
                            }
                        }

                        wsaDayDTO.setNotSwipingNum(notSwipingNum);

                        String shiftNumberStrs = shiftNumbers.stream().collect(Collectors.joining(","));
                        wsaDayDTO.setShiftNumbers(shiftNumberStrs);

                        //工作时长
                        Map<String, Object> workMinuteParams = new HashMap<>();
                        workMinuteParams.put("classify", "2");

                        BigDecimal workMinutes = workScheduleAttendanceService.findSumWorkMinuteByParams(pi.getId(), sdf.parse(queryDate), sdf.parse(queryDate), workMinuteParams);

                        wsaDayDTO.setWorkTimes(formatTime(workMinutes.intValue()));

                        perWsaList.add(wsaDayDTO);

                        exist = true;
                    }
                }

                if (!exist) {
                    wsaDayDTO.setPersonInfo(pi);
                    wsaDayDTO.setAttendanceDate(sdf.parse(queryDate));
                    wsaDayDTO.setWorkTimes("");
//                    //上班
//                    wsaDayDTO.setOnWorkResult(wsa.getResult());
//                    wsaDayDTO.setOnWorkStatus(wsa.getWorkStatus());
//                    wsaDayDTO.setOnWorkStatusN(workStatusN);
//                    wsaDayDTO.setOnWorkRecordTime(wsa.getRecordTime());
//                    //下班
//                    wsaDayDTO.setOffWorkResult(wsa.getResult());
//                    wsaDayDTO.setOffWorkStatus(wsa.getWorkStatus());
//                    wsaDayDTO.setOffWorkStatusN(workStatusN);
//                    wsaDayDTO.setOffWorkRecordTime(wsa.getRecordTime());
                    perWsaList.add(wsaDayDTO);
                }

            }
            msgMap.put("wsaList", perWsaList);
//            msgMap.put("recordsTotal", page.getTotal());
//            msgMap.put("recordsFiltered", page.getTotal());
//            msgMap.put("totalPage", page.getPages());
//            msgMap.put("pageNumber", page.getPageNum());
//            msgMap.put("pageSize", page.getPageSize());
            msgResult.setResult(true);
            msgResult.setData(msgMap);

        } catch (Exception ex) {
            ex.printStackTrace();
            logger.error(ex.getMessage(), ex);
            msgResult.setResult(false);
            msgResult.setMessage("查询失败");
        }

        return msgResult;
    }

    @ApiOperation(value = "后勤统计考勤-按日统计")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "companyId", value = "单位编号", required = true, paramType = "form"),
            @ApiImplicitParam(name = "subordinate", value = "是否查询下级单位", required = false, paramType = "form", dataType = "String"),
            @ApiImplicitParam(name = "name", value = "用户姓名", required = true, paramType = "form"),
            @ApiImplicitParam(name = "queryDate", value = "查询日期", required = true, paramType = "form"),
            @ApiImplicitParam(name = "subject", value = "subject", required = false, paramType = "form")
    })
    @RequestMapping(value = "hqAttendanceDay", method = RequestMethod.POST)
    public MessageResult<Map> hqAttendanceDay(
            @RequestParam(value = "companyId", defaultValue = "") String companyId,
            @RequestParam(value = "subordinate", defaultValue = "false") Boolean subordinate,
            @RequestParam(value = "name", defaultValue = "") String name,
            @RequestParam(value = "jobNumber", defaultValue = "") String jobNumber,
            @RequestParam(value = "popedomRemark", defaultValue = "") String popedomRemark,
            @RequestParam(value = "queryDate", defaultValue = "") String queryDate,
            @RequestParam(value = "pageIndex", defaultValue = "0") int pageIndex,
            @RequestParam(value = "pageSize", defaultValue = "100000") int pageSize,
            @RequestAttribute String subject) {

        //当前用户ID
        System.out.println(subject);

        MessageResult<Map> msgResult = new MessageResult<>();
        try {


            Map<String, Object> searchParams = new HashMap<>();
            Map<String, Object> msgMap = new HashMap<>();

            List<Sort> sortList = new ArrayList<>();
            sortList.add(new Sort("a.hq_sort_no", "asc"));

            if (StringUtils.isNotEmpty(name)) {
                String[] names = name.split(",");
                List nameList = new ArrayList();
                for (String n : names) {
                    nameList.add("%" + n + "%");
                }
                searchParams.put("nameList", nameList);
            }

            if (StringUtils.isNotEmpty(companyId)) {
                if ("hq1".equals(companyId)) {
                    //外勤1
//                    List<CompanyInfo> list1 = companyInfoService.findByClassify("1");
//                    searchParams.put("companyInfos", list1);

                    searchParams.put("hqStatus", "1");
                } else if ("hq2".equals(companyId)) {
                    //外勤2
//                    List<CompanyInfo> list2 = companyInfoService.findByClassify("2");
//                    searchParams.put("companyInfos", list2);

                    searchParams.put("hqStatus", "2");
                } else {
                    CompanyInfo parentCompanyInfo = companyInfoService.get(companyId);
                    String parentCode = parentCompanyInfo.getCode();
                    if (subordinate) {
                        searchParams.put("attendanceCompanyCode", parentCode + "%");
                    } else {
                        searchParams.put("attendanceCompanyCode", parentCode);
                    }

                    searchParams.put("hqStatus", parentCompanyInfo.getClassify());
                }
            } else {
                searchParams.put("querHq", "yes");
            }

            if (StringUtils.isNotEmpty(jobNumber)) {
                searchParams.put("jobNumber", jobNumber);
            }

            if (StringUtils.isNotEmpty(popedomRemark)) {
                List<String> popedomRemarkList = Arrays.asList(popedomRemark.split(","));
                searchParams.put("popedomRemarkList", popedomRemarkList);
            }

            Page<PersonInfo> page = personInfoService.pageSearch(searchParams, pageIndex, pageSize, false, sortList);
            List<PersonInfoDayWSADTO> perWsaList = new ArrayList<>();

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            for (PersonInfo pi : page.getResult()) {
                //查询用户当日排班
                WorkPersonScheduling wps = workPersonSchedulingService.findByPersonIdSchedulingDay(pi.getId(), sdf.parse(queryDate));

                boolean exist = false;

                PersonInfoDayWSADTO wsaDayDTO = new PersonInfoDayWSADTO();

                if (wps != null) {
                    String shifts = wps.getShiftIds();

                    wsaDayDTO.setPersonInfo(pi);
                    wsaDayDTO.setShiftIds(shifts);
                    List<String> shiftNumbers = new ArrayList<>();

                    if (shifts != null) {
                        //List<String> shiftList = workScheduleAttendanceService.findShiftByPersonAndAttendanceDate(pi.getId(), queryDate);
                        String[] shiftIds = shifts.split(",");
                        //未刷次数
                        int notSwipingNum = 0;
                        for (int i = 0; i < shiftIds.length; i++) {
                            String shiftId = shiftIds[i];
                            String shiftNumber = workShiftInfoService.findNumberById(shiftId);
                            shiftNumbers.add(shiftNumber);

                            List<WorkScheduleAttendance> wsaList = workScheduleAttendanceService.findByPersonIdAndShiftIdAndAttendanceDate(pi.getId(), shiftId, queryDate);
                            //单排班只有2条记录 1条上班1条下班
                            wsaDayDTO.setPersonInfo(pi);
                            wsaDayDTO.setAttendanceDate(sdf.parse(queryDate));

                            String onWorkResult = "50";
                            String onWorkStatus = "";
                            String onWorkStatusN = "";
                            Date onWorkRecordTime = null;
                            BigDecimal onLateLeaveMinute = BigDecimal.ZERO;
                            String onLateLeaveMinuteN = "";
                            String onSupplementWork = "";


                            String offWorkResult = "50";
                            String offWorkStatus = "";
                            String offWorkStatusN = "";
                            Date offWorkRecordTime = null;
                            BigDecimal offLateLeaveMinute = BigDecimal.ZERO;
                            String offLateLeaveMinuteN = "";
                            String offSupplementWork = "";

                            if ("0".equals(shiftNumber)) {
                                //休息
                                onWorkResult = "10";
                                offWorkResult = "10";
                            } else {
                                if (wsaList.size() < 1) {
                                    //没有考勤记录
                                    notSwipingNum = notSwipingNum + 2;
                                    onWorkResult = "50";
                                    offWorkResult = "50";
                                }
                            }


                            for (WorkScheduleAttendance wsa : wsaList) {
                                String workStatusN = dataDictionaryService.findNameByCatalogNameAndValue("工作状态", wsa.getWorkStatus());
                                //旷工天数absenteeismDays
                                List<String> days = new ArrayList<>();
                                days.add(wsa.getAttendanceDate());
                                BigDecimal absenteeismCount = workScheduleAttendanceService.findAbsenteeism(pi.getId(), sdf.parse(wsa.getAttendanceDate()), sdf.parse(wsa.getAttendanceDate()), "0");
                                wsaDayDTO.setAbsenteeismDays(absenteeismCount);

                                if ("1".equals(wsa.getClassify())) {
                                    //上班
                                    if ("补卡".equals(wsa.getRemark())) {
                                        //补卡为11
                                        onWorkResult = "11";

                                        //"补卡原因";
                                        if (StringUtils.isNotEmpty(wsa.getSupplementWorkPersonId())) {
                                            SupplementWorkPerson supplementWorkPerson = supplementWorkPersonService.get(wsa.getSupplementWorkPersonId());
                                            if(supplementWorkPerson != null){
                                                SupplementWork supplementWork = supplementWorkService.get(supplementWorkPerson.getSupplementWorkId());
                                                if(supplementWork != null){
                                                    onSupplementWork = supplementWork.getReason();
                                                }
                                            }
                                        }

                                    } else if ("3".equals(wsa.getWorkStatus())) {
                                        //出差
                                        onWorkResult = "9";
                                    } else if ("4".equals(wsa.getWorkStatus())) {
                                        //请假
                                        onWorkResult = "13";
                                    }
                                    else if ("7".equals(wsa.getWorkStatus())) {
                                        //年假
                                        onWorkResult = "14";
                                    }
                                    else if (StringUtils.isEmpty(wsa.getWorkStatus())) {
                                        onWorkResult = "";
                                    }
                                    else {
                                        onWorkResult = wsa.getResult();
                                    }
                                    onWorkStatus = wsa.getWorkStatus();
                                    onWorkStatusN = workStatusN;
                                    onWorkRecordTime = wsa.getRecordTime();
                                    if (wsa.getLateLeaveMinute() != null) {
                                        onLateLeaveMinuteN = formatTime(wsa.getLateLeaveMinute().intValue());
                                    }
                                    onLateLeaveMinute = onLateLeaveMinute;
                                    if ("0".equals(wsa.getResult())) {
                                        notSwipingNum++;
                                    }
                                } else if ("2".equals(wsa.getClassify())) {
                                    //下班
                                    if ("补卡".equals(wsa.getRemark())) {
                                        //补卡为11
                                        offWorkResult = "11";

                                        //"补卡原因";
                                        if (StringUtils.isNotEmpty(wsa.getSupplementWorkPersonId())) {
                                            SupplementWorkPerson supplementWorkPerson = supplementWorkPersonService.get(wsa.getSupplementWorkPersonId());
                                            if(supplementWorkPerson != null){
                                                SupplementWork supplementWork = supplementWorkService.get(supplementWorkPerson.getSupplementWorkId());
                                                if(supplementWork != null){
                                                    offSupplementWork = supplementWork.getReason();
                                                }
                                            }
                                        }
                                    } else if ("3".equals(wsa.getWorkStatus())) {
                                        //出差
                                        offWorkResult = "9";
                                    } else if ("4".equals(wsa.getWorkStatus())) {
                                        //请假
                                        offWorkResult = "13";
                                    }
                                    else if ("7".equals(wsa.getWorkStatus())) {
                                        //年假
                                        offWorkResult = "14";
                                    }
                                    else if (StringUtils.isEmpty(wsa.getWorkStatus())) {
                                        //状态为空 代表没有数据
                                        offWorkResult = "";
                                    } else if (StringUtils.isNotEmpty(wsa.getWorkOverPersonId())) {
                                        //为加班 只有下班存在 加班字段不为空代表加班
                                        offWorkResult = "12";
                                    } else {
                                        offWorkResult = wsa.getResult();
                                    }
                                    offWorkStatus = wsa.getWorkStatus();
                                    offWorkStatusN = workStatusN;
                                    offWorkRecordTime = wsa.getRecordTime();
                                    if (wsa.getLateLeaveMinute() != null) {
                                        offLateLeaveMinuteN = formatTime(wsa.getLateLeaveMinute().intValue());
                                    }
                                    offLateLeaveMinute = offLateLeaveMinute;
                                    if ("0".equals(wsa.getResult())) {
                                        notSwipingNum++;
                                    }
                                }
                            }

                            if (i == 0) {
                                wsaDayDTO.setOnWorkResult1(onWorkResult);
                                wsaDayDTO.setOnWorkStatus1(onWorkStatus);
                                wsaDayDTO.setOnWorkStatus1N(onWorkStatusN);
                                wsaDayDTO.setOnWorkRecordTime1(onWorkRecordTime);
                                wsaDayDTO.setOnLateLeaveMinute1(onLateLeaveMinute);
                                wsaDayDTO.setOnLateLeaveMinute1N(onLateLeaveMinuteN);
                                wsaDayDTO.setOnSupplementWork1(onSupplementWork);

                                wsaDayDTO.setOffWorkResult1(offWorkResult);
                                wsaDayDTO.setOffWorkStatus1(offWorkStatus);
                                wsaDayDTO.setOffWorkStatus1N(offWorkStatusN);
                                wsaDayDTO.setOffWorkRecordTime1(offWorkRecordTime);
                                wsaDayDTO.setOffLateLeaveMinute1(offLateLeaveMinute);
                                wsaDayDTO.setOffLateLeaveMinute1N(offLateLeaveMinuteN);
                                wsaDayDTO.setOffSupplementWork1(offSupplementWork);
                            } else if (i == 1) {
                                wsaDayDTO.setOnWorkResult2(onWorkResult);
                                wsaDayDTO.setOnWorkStatus2(onWorkStatus);
                                wsaDayDTO.setOnWorkStatus2N(onWorkStatusN);
                                wsaDayDTO.setOnWorkRecordTime2(onWorkRecordTime);
                                wsaDayDTO.setOnLateLeaveMinute2(onLateLeaveMinute);
                                wsaDayDTO.setOnLateLeaveMinute2N(onLateLeaveMinuteN);
                                wsaDayDTO.setOnSupplementWork2(onSupplementWork);

                                wsaDayDTO.setOffWorkResult2(offWorkResult);
                                wsaDayDTO.setOffWorkStatus2(offWorkStatus);
                                wsaDayDTO.setOffWorkStatus2N(offWorkStatusN);
                                wsaDayDTO.setOffWorkRecordTime2(offWorkRecordTime);
                                wsaDayDTO.setOffLateLeaveMinute2(offLateLeaveMinute);
                                wsaDayDTO.setOffLateLeaveMinute2N(offLateLeaveMinuteN);
                                wsaDayDTO.setOffSupplementWork2(offSupplementWork);
                            } else if (i == 2) {
                                wsaDayDTO.setOnWorkResult3(onWorkResult);
                                wsaDayDTO.setOnWorkStatus3(onWorkStatus);
                                wsaDayDTO.setOnWorkStatus3N(onWorkStatusN);
                                wsaDayDTO.setOnWorkRecordTime3(onWorkRecordTime);
                                wsaDayDTO.setOnLateLeaveMinute3(onLateLeaveMinute);
                                wsaDayDTO.setOnLateLeaveMinute3N(onLateLeaveMinuteN);
                                wsaDayDTO.setOnSupplementWork3(onSupplementWork);

                                wsaDayDTO.setOffWorkResult3(offWorkResult);
                                wsaDayDTO.setOffWorkStatus3(offWorkStatus);
                                wsaDayDTO.setOffWorkStatus3N(offWorkStatusN);
                                wsaDayDTO.setOffWorkRecordTime3(offWorkRecordTime);
                                wsaDayDTO.setOffLateLeaveMinute3(offLateLeaveMinute);
                                wsaDayDTO.setOffLateLeaveMinute3N(offLateLeaveMinuteN);
                                wsaDayDTO.setOffSupplementWork3(offSupplementWork);
                            }
                        }

                        wsaDayDTO.setNotSwipingNum(notSwipingNum);
                        String shiftNumberStrs = shiftNumbers.stream()
                                .map((shiftNumber) -> shiftNumber)
                                .collect(Collectors.joining(","));
                        wsaDayDTO.setShiftNumbers(shiftNumberStrs);
                        perWsaList.add(wsaDayDTO);

                        exist = true;
                    }
                }

                if (!exist) {
                    wsaDayDTO.setPersonInfo(pi);
                    wsaDayDTO.setAttendanceDate(sdf.parse(queryDate));
//                    //上班
//                    wsaDayDTO.setOnWorkResult(wsa.getResult());
//                    wsaDayDTO.setOnWorkStatus(wsa.getWorkStatus());
//                    wsaDayDTO.setOnWorkStatusN(workStatusN);
//                    wsaDayDTO.setOnWorkRecordTime(wsa.getRecordTime());
//                    //下班
//                    wsaDayDTO.setOffWorkResult(wsa.getResult());
//                    wsaDayDTO.setOffWorkStatus(wsa.getWorkStatus());
//                    wsaDayDTO.setOffWorkStatusN(workStatusN);
//                    wsaDayDTO.setOffWorkRecordTime(wsa.getRecordTime());
                    perWsaList.add(wsaDayDTO);
                }

            }
            msgMap.put("wsaList", perWsaList);
//            msgMap.put("recordsTotal", page.getTotal());
//            msgMap.put("recordsFiltered", page.getTotal());
//            msgMap.put("totalPage", page.getPages());
//            msgMap.put("pageNumber", page.getPageNum());
//            msgMap.put("pageSize", page.getPageSize());
            msgResult.setResult(true);
            msgResult.setData(msgMap);

        } catch (Exception ex) {
            ex.printStackTrace();
            logger.error(ex.getMessage(), ex);
            msgResult.setResult(false);
            msgResult.setMessage("查询失败");
        }

        return msgResult;
    }

    @ApiOperation(value = "导出后勤月报表")
    @PostMapping("exportHqMonthXls")
    public MessageResult<String> exportHqMonthXls(
            @RequestBody JSONObject requestBody,
            @RequestAttribute String subject) {
        MessageResult<String> msgResult = new MessageResult<>();

        try {
            XSSFWorkbook workbook = new XSSFWorkbook();
            XSSFSheet sheet = workbook.createSheet();
            //表头
            XSSFRow rowTitle = sheet.createRow(0);
            XSSFCell cellTitle0 = rowTitle.createCell(0);
            cellTitle0.setCellValue("部门");
            XSSFCell cellTitle1 = rowTitle.createCell(1);
            cellTitle1.setCellValue("工号");
            XSSFCell cellTitle2 = rowTitle.createCell(2);
            cellTitle2.setCellValue("姓名");

            XSSFCell cellTitle3 = rowTitle.createCell(3);
            cellTitle3.setCellValue("应出勤天数");
            XSSFCell cellTitle4 = rowTitle.createCell(4);
            cellTitle4.setCellValue("实际出勤天数");
            XSSFCell cellTitle5 = rowTitle.createCell(5);
            cellTitle5.setCellValue("迟到分钟");
            XSSFCell cellTitle6 = rowTitle.createCell(6);
            cellTitle6.setCellValue("迟到次数");
            XSSFCell cellTitle7 = rowTitle.createCell(7);
            cellTitle7.setCellValue("早退分钟");
            XSSFCell cellTitle8 = rowTitle.createCell(8);
            cellTitle8.setCellValue("早退次数");
            XSSFCell cellTitle9 = rowTitle.createCell(9);
            cellTitle9.setCellValue("加班小时");
            XSSFCell cellTitle10 = rowTitle.createCell(10);
            cellTitle10.setCellValue("旷工天数");
            XSSFCell cellTitle11 = rowTitle.createCell(11);
            cellTitle11.setCellValue("未打卡次数");
            XSSFCell cellTitle12 = rowTitle.createCell(12);
            cellTitle12.setCellValue("签到次数");
            XSSFCell cellTitle13 = rowTitle.createCell(13);
            cellTitle13.setCellValue("出差天数");
            XSSFCell cellTitle14 = rowTitle.createCell(14);
            cellTitle14.setCellValue("请假天数");
            XSSFCell cellTitle15 = rowTitle.createCell(15);
            cellTitle15.setCellValue("年假天数");
            XSSFCell cellTitle16 = rowTitle.createCell(16);
            cellTitle16.setCellValue("休息天数");
            XSSFCell cellTitle17 = rowTitle.createCell(17);
            cellTitle17.setCellValue("备注");

            JSONArray array = requestBody.getJSONArray("data");

            for (int i = 0; i < array.size(); i++) {
                Row row = sheet.createRow(i + 1);

                JSONObject jsonObject = array.getJSONObject(i);

                int colIndex = 0;

                if (jsonObject.getJSONObject("personInfo") != null) {
                    row.createCell(colIndex).setCellValue(jsonObject.getString("companyName"));
                    colIndex++;

                    row.createCell(colIndex).setCellValue(jsonObject.getJSONObject("personInfo").getString("jobNumber"));
                    colIndex++;

                    row.createCell(colIndex).setCellValue(jsonObject.getJSONObject("personInfo").getString("name"));
                    colIndex++;
                } else {
                    colIndex += 3;
                }

                row.createCell(colIndex).setCellValue(jsonObject.getString("attendanceDays"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("totalAttendanceDays"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("lateMinutes"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("lateNum"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("leaveEarlyMinutes"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("leaveEarlyNum"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("overtime"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("absenteeismDays"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("notSwipingNum"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("signNum"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("businessTripNum"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("leaveNum"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("yearLeaveNum"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("restDays"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("remark"));
                colIndex++;

                //todo 将wb保存到oss
                ByteArrayOutputStream output = new ByteArrayOutputStream();
                workbook.write(output);

                byte[] buffer = output.toByteArray();
                ByteArrayInputStream input = new ByteArrayInputStream(buffer);

                //格式化
                SimpleDateFormat sim = new SimpleDateFormat("yyyyMMddHHmmss");
                String fileName = "导出后勤考勤月统计数据" + sim.format(new Date()) + ".xlsx";
                String downloadUrl = OSSUtil.upload(ossConfig, "import", fileName, input);

                msgResult.setData(downloadUrl);
                msgResult.setResult(true);
            }
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value = "服务端导出考勤按月统计")
    @PostMapping("exportMonthXlsByServer")
    public MessageResult<String> exportMonthXlsByServer(
            @RequestParam(value = "companyId", defaultValue = "") String companyId,
            @RequestParam(value = "subordinate", defaultValue = "false") Boolean subordinate,
            @RequestParam(value = "name", defaultValue = "") String name,
            @DateTimeFormat(pattern = "") String startMonth,
            @DateTimeFormat(pattern = "") String endMonth,
            @RequestAttribute String subject) {
        MessageResult<String> msgResult = new MessageResult<>();

        try {
            XSSFWorkbook workbook = new XSSFWorkbook();
            XSSFSheet sheet = workbook.createSheet();
            //表头
            XSSFRow rowTitle = sheet.createRow(0);
            XSSFCell cellTitle0 = rowTitle.createCell(0);
            cellTitle0.setCellValue("序号");
            XSSFCell cellTitle1 = rowTitle.createCell(1);
            cellTitle1.setCellValue("工号");
            XSSFCell cellTitle2 = rowTitle.createCell(2);
            cellTitle2.setCellValue("姓名");
            XSSFCell cellTitle3 = rowTitle.createCell(3);
            cellTitle3.setCellValue("应出勤天数");
            XSSFCell cellTitle4 = rowTitle.createCell(4);
            cellTitle4.setCellValue("实际出勤天数");
            XSSFCell cellTitle5 = rowTitle.createCell(5);
            cellTitle5.setCellValue("迟到分钟");
            XSSFCell cellTitle6 = rowTitle.createCell(6);
            cellTitle6.setCellValue("迟到次数");
            XSSFCell cellTitle7 = rowTitle.createCell(7);
            cellTitle7.setCellValue("早退分钟");
            XSSFCell cellTitle8 = rowTitle.createCell(8);
            cellTitle8.setCellValue("早退次数");
            XSSFCell cellTitle9 = rowTitle.createCell(9);
            cellTitle9.setCellValue("加班小时");
            XSSFCell cellTitle10 = rowTitle.createCell(10);
            cellTitle10.setCellValue("旷工天数");
            XSSFCell cellTitle11 = rowTitle.createCell(11);
            cellTitle11.setCellValue("未打卡次数");
            XSSFCell cellTitle12 = rowTitle.createCell(12);
            cellTitle12.setCellValue("签到次数");
            XSSFCell cellTitle13 = rowTitle.createCell(13);
            cellTitle13.setCellValue("出差天数");
            XSSFCell cellTitle14 = rowTitle.createCell(14);
            cellTitle14.setCellValue("请假天数");
            XSSFCell cellTitle15 = rowTitle.createCell(15);
            cellTitle15.setCellValue("工作时长");

            Map<String, Object> searchParams = new HashMap<>();
            Map<String, Object> msgMap = new HashMap<>();

            List<Sort> sortList = new ArrayList<>();
            sortList.add(new Sort("a.id_", "asc"));

            if (StringUtils.isNotEmpty(name)) {
                String[] names = name.split(",");
                List nameList = new ArrayList();
                for (String n : names) {
                    nameList.add("%" + n + "%");
                }
                searchParams.put("nameList", nameList);
            }

            if (StringUtils.isNotEmpty(companyId)) {
                CompanyInfo parentCompanyInfo = companyInfoService.get(companyId);
                String parentCode = parentCompanyInfo.getCode();
                if (subordinate) {
                    searchParams.put("companyCode", parentCode + "%");
                } else {
                    searchParams.put("companyCode", parentCode);
                }
            }

            Page<PersonInfo> page = personInfoService.pageSearch(searchParams, 0, 1000000, false, sortList);
            List<PersonInfoMonthWSADTO> wsaList = new ArrayList<>();

            //头部是月份
            Date startDate = new SimpleDateFormat("yyyy-MM-dd").parse(startMonth + "-01");
            Date endDate = new SimpleDateFormat("yyyy-MM-dd").parse(endMonth + "-01");
            Boolean isDateEq = false;

            //获取开始查询的年月
            Map<String, Object> startMap = getDayByMonth(startDate);
            int sYear = Integer.parseInt(startMap.get("year").toString());
            int sMonth = Integer.parseInt(startMap.get("month").toString());
            List<Integer> months = new ArrayList<>();


            months.add(sMonth);
            if (startDate.equals(endDate)) {
                //如果日期相同 查的同年月
                isDateEq = true;
            } else {
                //获取结束查询的年月
                Map<String, Object> endMap = getDayByMonth(endDate);
                int eMonth = Integer.parseInt(endMap.get("month").toString());
                months.add(eMonth);
            }

            List<String> dateLst = new ArrayList<>();
            dateLst.add(startMonth + "%");
            dateLst.add(endMonth + "%");


            for (int i = 0; i < page.size(); i++) {
                PersonInfo pi = page.get(i);

                XSSFRow rowContent = sheet.createRow(i + 1);
                XSSFCell cellContent0 = rowContent.createCell(0);
                cellContent0.setCellValue(i + 1);

                //工号
                XSSFCell cellContent1 = rowContent.createCell(1);
                cellContent1.setCellValue(pi.getJobNumber());

                XSSFCell cellContent2 = rowContent.createCell(2);
                cellContent2.setCellValue(pi.getName());

                //先查总班次 确认正常上班和休息
                List<WorkPersonScheduling> startWorkPersonScheduling
                        = workPersonSchedulingService.findByPersonIdYearMonths(pi.getId(), sYear, months, false);


                //应出勤天数attendanceDays
                XSSFCell cellContent3 = rowContent.createCell(3);
                cellContent3.setCellValue(startWorkPersonScheduling.size());
                //全勤天数totalAttendanceDays
                BigDecimal totalAttendanceDays = workScheduleAttendanceService.findTotalAttendance(pi.getId(), startDate, endDate, "1");
                XSSFCell cellContent4 = rowContent.createCell(4);
                cellContent4.setCellValue(totalAttendanceDays.toString());
                //迟到分钟lateMinutes
                Map<String, Object> searchParams3 = new HashMap<>();
                searchParams3.put("result", "2");
                Double lateMinutes = workScheduleAttendanceService.findSumLMinuteByParams(pi.getId(), startDate, endDate, searchParams3);
                XSSFCell cellContent5 = rowContent.createCell(5);
                cellContent5.setCellValue(lateMinutes);
                //迟到次数lateNum
                Map<String, Object> searchParams4 = new HashMap<>();
                searchParams4.put("result", "2");
                searchParams4.put("classify", "1");//上班
                int lateNum = workScheduleAttendanceService.findCountByParams(pi.getId(), startDate, endDate, searchParams4);
                XSSFCell cellContent6 = rowContent.createCell(6);
                cellContent6.setCellValue(lateNum);
                //早退分钟leaveEarlyMinutes
                Map<String, Object> searchParams5 = new HashMap<>();
                searchParams5.put("result", "3");
                Double leaveEarlyMinutes = workScheduleAttendanceService.findSumLMinuteByParams(pi.getId(), startDate, endDate, searchParams5);
                XSSFCell cellContent7 = rowContent.createCell(7);
                cellContent7.setCellValue(leaveEarlyMinutes);
                //早退次数leaveEarlyNum
                Map<String, Object> searchParams6 = new HashMap<>();
                searchParams6.put("result", "3");
                searchParams6.put("classify", "2");//下班
                int leaveEarlyNum = workScheduleAttendanceService.findCountByParams(pi.getId(), startDate, endDate, searchParams6);
                XSSFCell cellContent8 = rowContent.createCell(8);
                cellContent8.setCellValue(leaveEarlyNum);
                //加班小时overtime
                Map<String, Object> searchParams7 = new HashMap<>();
                searchParams7.put("result", "3");
                searchParams7.put("classify", "2");//下班
                int overtime = workOverService.findSumHoursByParams(pi.getId(), startDate, endDate, searchParams7);
                XSSFCell cellContent9 = rowContent.createCell(9);
                cellContent9.setCellValue(overtime);
                //旷工天数absenteeismDays
                BigDecimal absenteeismCount = workScheduleAttendanceService.findAbsenteeism(pi.getId(), startDate, endDate, "0");
                XSSFCell cellContent10 = rowContent.createCell(10);
                cellContent10.setCellValue(absenteeismCount.toString());
                //未打卡次数
                Map<String, Object> searchParams9 = new HashMap<>();
                searchParams9.put("result", "0");
                int notSwipingNum = workScheduleAttendanceService.findCountByParams(pi.getId(), startDate, endDate, searchParams9);
                XSSFCell cellContent11 = rowContent.createCell(11);
                cellContent11.setCellValue(notSwipingNum);
                //签到次数signNum
                //0为未打卡 不等于0的为签到
                Map<String, Object> searchParams10 = new HashMap<>();
                searchParams10.put("noResult", "0");
                int signNum = workScheduleAttendanceService.findCountByParams(pi.getId(), startDate, endDate, searchParams10);
                XSSFCell cellContent12 = rowContent.createCell(12);
                cellContent12.setCellValue(signNum);
                //出差次数businessTripNum
                Map<String, Object> searchParams11 = new HashMap<>();
                searchParams11.put("workStatus", "3");
                int businessTripNum = workScheduleAttendanceService.findCountByParams(pi.getId(), startDate, endDate, searchParams11);
                XSSFCell cellContent13 = rowContent.createCell(13);
                cellContent13.setCellValue(businessTripNum);
                //请假天数leaveNum
                Map<String, Object> searchParams12 = new HashMap<>();
                searchParams12.put("workStatus", "4");
                int leaveNum = workScheduleAttendanceService.findCountByParams(pi.getId(), startDate, endDate, searchParams12);
                XSSFCell cellContent14 = rowContent.createCell(14);
                cellContent14.setCellValue(leaveNum);

                Map<String, Object> workMinuteParams = new HashMap<>();
                workMinuteParams.put("classify", "2");

                BigDecimal workMinutes = workScheduleAttendanceService.findSumWorkMinuteByParams(pi.getId(), startDate, endDate, workMinuteParams);
                XSSFCell cellContent15 = rowContent.createCell(15);
                cellContent15.setCellValue(formatTime(workMinutes.intValue()));

                //todo 将wb保存到oss
                ByteArrayOutputStream output = new ByteArrayOutputStream();
                workbook.write(output);

                byte[] buffer = output.toByteArray();
                ByteArrayInputStream input = new ByteArrayInputStream(buffer);

                //格式化
                SimpleDateFormat sim = new SimpleDateFormat("yyyyMMddHHmmss");
                String fileName = "导出考勤统计数据" + sim.format(new Date()) + ".xlsx";
                String downloadUrl = OSSUtil.upload(ossConfig, "import", fileName, input);

                //todo 返回导入失败报表下载链接

                msgResult.setData(downloadUrl);
                msgResult.setResult(true);
            }
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    public static Map<String, Object> getDayByMonth(Date queryMonth) {
        Map<String, Object> returnMap = new HashMap<>();
        List list = new ArrayList();
        Calendar aCalendar = Calendar.getInstance(Locale.CHINA);
        aCalendar.setTime(queryMonth);
        //aCalendar.set(yearParam,monthParam,1);
        int year = aCalendar.get(Calendar.YEAR);//年份
        int month = aCalendar.get(Calendar.MONTH) + 1;//月份
        int day = aCalendar.getActualMaximum(Calendar.DATE);
        for (int i = 1; i <= day; i++) {
            int aDate = i;
            list.add(aDate);
        }
        returnMap.put("year", year);
        returnMap.put("month", month);
        returnMap.put("days", list);
        return returnMap;
    }

    //分钟转小时
    private String formatTime(int minute) {

        String resultStr = "";

        if (minute != 0) {
            if (minute != 0) {
                if (minute / 60 == 0) {
                    resultStr = minute % 60 + "分";
                } else {
                    if (minute % 60 == 0) {
                        resultStr = minute / 60 + "小时";
                    } else {
                        resultStr = (minute / 60 + "小时" + minute % 60 + "分");
                    }
                }
            } else {
                resultStr = "0时0分";
            }
        } else {
            resultStr = "0时0分";
        }
        return resultStr;
    }

    @ApiOperation(value = "导出后勤日报表")
    @PostMapping("exportHqDayXls")
    public MessageResult<String> exportHqDayXls(
            @RequestBody JSONObject requestBody,
            @RequestAttribute String subject) {
        MessageResult<String> msgResult = new MessageResult<>();

        try {
            XSSFWorkbook workbook = new XSSFWorkbook();
            XSSFSheet sheet = workbook.createSheet();
            //表头
            XSSFRow rowTitle = sheet.createRow(0);
            XSSFCell cellTitle0 = rowTitle.createCell(0);
            cellTitle0.setCellValue("部门");
            XSSFCell cellTitle1 = rowTitle.createCell(1);
            cellTitle1.setCellValue("工号");
            XSSFCell cellTitle2 = rowTitle.createCell(2);
            cellTitle2.setCellValue("姓名");
            XSSFCell cellTitle3 = rowTitle.createCell(3);
            cellTitle3.setCellValue("日期");

            XSSFCell cellTitle4 = rowTitle.createCell(4);
            cellTitle4.setCellValue("上班打卡时间");
            XSSFCell cellTitle5 = rowTitle.createCell(5);
            cellTitle5.setCellValue("上班打卡状态");
            XSSFCell cellTitle6 = rowTitle.createCell(6);
            cellTitle6.setCellValue("下班打卡时间");
            XSSFCell cellTitle7 = rowTitle.createCell(7);
            cellTitle7.setCellValue("下班打卡状态");

            XSSFCell cellTitle8 = rowTitle.createCell(8);
            cellTitle8.setCellValue("上班打卡时间");
            XSSFCell cellTitle9 = rowTitle.createCell(9);
            cellTitle9.setCellValue("上班打卡状态");
            XSSFCell cellTitle10 = rowTitle.createCell(10);
            cellTitle10.setCellValue("下班打卡时间");
            XSSFCell cellTitle11 = rowTitle.createCell(11);
            cellTitle11.setCellValue("下班打卡状态");

            XSSFCell cellTitle12 = rowTitle.createCell(12);
            cellTitle12.setCellValue("上班打卡时间");
            XSSFCell cellTitle13 = rowTitle.createCell(13);
            cellTitle13.setCellValue("上班打卡状态");
            XSSFCell cellTitle14 = rowTitle.createCell(14);
            cellTitle14.setCellValue("下班打卡时间");
            XSSFCell cellTitle15 = rowTitle.createCell(15);
            cellTitle15.setCellValue("下班打卡状态");

            XSSFCell cellTitle16 = rowTitle.createCell(16);
            cellTitle16.setCellValue("旷工天数");
            XSSFCell cellTitle17 = rowTitle.createCell(17);
            cellTitle17.setCellValue("未打卡次数");

            JSONArray array = requestBody.getJSONArray("data");

            for (int i = 0; i < array.size(); i++) {
                Row row = sheet.createRow(i + 1);

                JSONObject jsonObject = array.getJSONObject(i);

                int colIndex = 0;

                if (jsonObject.getJSONObject("personInfo") != null) {
                    row.createCell(colIndex).setCellValue(jsonObject.getJSONObject("personInfo").getString("companyName"));
                    colIndex++;

                    row.createCell(colIndex).setCellValue(jsonObject.getJSONObject("personInfo").getString("jobNumber"));
                    colIndex++;

                    row.createCell(colIndex).setCellValue(jsonObject.getJSONObject("personInfo").getString("name"));
                    colIndex++;
                } else {
                    colIndex += 3;
                }

                row.createCell(colIndex).setCellValue(jsonObject.getString("attendanceDate"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("onWorkRecordTime1"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("onWorkResult1N"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("offWorkRecordTime1"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("offWorkResult1N"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("onWorkRecordTime2"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("onWorkResult2N"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("offWorkRecordTime2"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("offWorkResult2N"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("onWorkRecordTime3"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("onWorkResult3N"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("offWorkRecordTime3"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("offWorkResult3N"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("absenteeismDays"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("notSwipingNum"));
                colIndex++;

                //todo 将wb保存到oss
                ByteArrayOutputStream output = new ByteArrayOutputStream();
                workbook.write(output);

                byte[] buffer = output.toByteArray();
                ByteArrayInputStream input = new ByteArrayInputStream(buffer);

                //格式化
                SimpleDateFormat sim = new SimpleDateFormat("yyyyMMddHHmmss");
                String fileName = "导出后勤考勤日统计数据" + sim.format(new Date()) + ".xlsx";
                String downloadUrl = OSSUtil.upload(ossConfig, "import", fileName, input);

                msgResult.setData(downloadUrl);
                msgResult.setResult(true);
            }
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    @ApiOperation(value = "导出考勤月报表")
    @PostMapping("exportMonthXls")
    public MessageResult<String> exportMonthXls(
            @RequestBody JSONObject requestBody,
            @RequestAttribute String subject) {
        MessageResult<String> msgResult = new MessageResult<>();

        try {
            XSSFWorkbook workbook = new XSSFWorkbook();
            XSSFSheet sheet = workbook.createSheet();
            //表头
            XSSFRow rowTitle = sheet.createRow(0);
            XSSFCell cellTitle0 = rowTitle.createCell(0);
            cellTitle0.setCellValue("部门");
            XSSFCell cellTitle1 = rowTitle.createCell(1);
            cellTitle1.setCellValue("工号");
            XSSFCell cellTitle2 = rowTitle.createCell(2);
            cellTitle2.setCellValue("姓名");

            XSSFCell cellTitle3 = rowTitle.createCell(3);
            cellTitle3.setCellValue("应出勤天数");
            XSSFCell cellTitle4 = rowTitle.createCell(4);
            cellTitle4.setCellValue("实际出勤天数");
            XSSFCell cellTitle5 = rowTitle.createCell(5);
            cellTitle5.setCellValue("迟到分钟");
            XSSFCell cellTitle6 = rowTitle.createCell(6);
            cellTitle6.setCellValue("迟到次数");
            XSSFCell cellTitle7 = rowTitle.createCell(7);
            cellTitle7.setCellValue("早退分钟");
            XSSFCell cellTitle8 = rowTitle.createCell(8);
            cellTitle8.setCellValue("早退次数");
            XSSFCell cellTitle9 = rowTitle.createCell(9);
            cellTitle9.setCellValue("加班小时");
            XSSFCell cellTitle10 = rowTitle.createCell(10);
            cellTitle10.setCellValue("旷工天数");
            XSSFCell cellTitle11 = rowTitle.createCell(11);
            cellTitle11.setCellValue("未打卡次数");
            XSSFCell cellTitle12 = rowTitle.createCell(12);
            cellTitle12.setCellValue("签到次数");
            XSSFCell cellTitle13 = rowTitle.createCell(13);
            cellTitle13.setCellValue("出差天数");
            XSSFCell cellTitle14 = rowTitle.createCell(14);
            cellTitle14.setCellValue("请假天数");
            XSSFCell cellTitle15 = rowTitle.createCell(15);
            cellTitle15.setCellValue("年假天数");
            XSSFCell cellTitle16 = rowTitle.createCell(16);
            cellTitle16.setCellValue("工作时长");
            XSSFCell cellTitle17 = rowTitle.createCell(17);
            cellTitle17.setCellValue("备注");

            JSONArray array = requestBody.getJSONArray("data");

            for (int i = 0; i < array.size(); i++) {
                Row row = sheet.createRow(i + 1);

                JSONObject jsonObject = array.getJSONObject(i);

                int colIndex = 0;

                if (jsonObject.getJSONObject("personInfo") != null) {
                    row.createCell(colIndex).setCellValue(jsonObject.getString("companyName"));
                    colIndex++;

                    row.createCell(colIndex).setCellValue(jsonObject.getJSONObject("personInfo").getString("jobNumber"));
                    colIndex++;

                    row.createCell(colIndex).setCellValue(jsonObject.getJSONObject("personInfo").getString("name"));
                    colIndex++;
                } else {
                    colIndex += 3;
                }

                row.createCell(colIndex).setCellValue(jsonObject.getString("attendanceDays"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("totalAttendanceDays"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("lateMinutes"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("lateNum"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("leaveEarlyMinutes"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("leaveEarlyNum"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("overtime"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("absenteeismDays"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("notSwipingNum"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("signNum"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("businessTripNum"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("leaveNum"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("yearLeaveNum"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("workTimes"));
                colIndex++;

                row.createCell(colIndex).setCellValue(jsonObject.getString("remark"));
                colIndex++;

                //todo 将wb保存到oss
                ByteArrayOutputStream output = new ByteArrayOutputStream();
                workbook.write(output);

                byte[] buffer = output.toByteArray();
                ByteArrayInputStream input = new ByteArrayInputStream(buffer);

                //格式化
                SimpleDateFormat sim = new SimpleDateFormat("yyyyMMddHHmmss");
                String fileName = "导出考勤月统计数据" + sim.format(new Date()) + ".xlsx";
                String downloadUrl = OSSUtil.upload(ossConfig, "import", fileName, input);

                msgResult.setData(downloadUrl);
                msgResult.setResult(true);
            }
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);

            msgResult.setResult(false);
            msgResult.setMessage(ex.getMessage());
        }

        return msgResult;
    }

    //根据传入的查询日期 统计有多少天 除去周日
    public int calculateNotSunDays(Date t1, Date t2) {
        int workdays = 0;
        try {
            //初始化第一个日期
            Calendar cal1 = Calendar.getInstance();
            //初始化第二个日期，这里的天数可以随便的设置
            Calendar cal2 = Calendar.getInstance();

            // 设置传入的时间格式
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            // 指定一个日期
            Date date1 = dateFormat.parse(dateFormat.format(t1));
            Date date2 = dateFormat.parse(dateFormat.format(t2));
            // 对 calendar 设置为 date 所定的日期
            cal1.setTime(date1);
            cal2.setTime(date2);

            //确定一个 大日期
            if (cal1.compareTo(cal2) > 0) {
                Calendar temp = cal1;
                cal1 = cal2;
                cal2 = temp;
                temp = null;
            }

            while (cal1.compareTo(cal2) <= 0) {
                //不是星期天
                if (cal1.get(Calendar.DAY_OF_WEEK) != 1) {
                    List<HolidayInfo> holidayInfoList = holidayInfoService.findByDate(cal1.getTime());

                    //不是节假日
                    if (holidayInfoList.size() == 0) {
                        workdays++;
                    }
                }

                cal1.add(Calendar.DAY_OF_YEAR, 1);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        return workdays;
    }

    /**
     * 计算两个日期之间相差的天数
     *
     * @param smdate 较小的时间
     * @param bdate  较大的时间
     * @return 相差天数
     */
    public static int daysBetween(String smdate, String bdate) {
        long between_days = 0;
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Calendar cal = Calendar.getInstance();
            cal.setTime(sdf.parse(smdate));
            long time1 = cal.getTimeInMillis();
            cal.setTime(sdf.parse(bdate));
            long time2 = cal.getTimeInMillis();
            between_days = (time2 - time1) / (1000 * 3600 * 24);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Integer.parseInt(String.valueOf(between_days));
    }
}
