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

import com.github.pagehelper.Page;
import com.jpsoft.shinestar.config.OSSConfig;
import com.jpsoft.shinestar.modules.base.entity.AlarmConfig;
import com.jpsoft.shinestar.modules.base.entity.CompanyInfo;
import com.jpsoft.shinestar.modules.base.entity.PersonInfo;
import com.jpsoft.shinestar.modules.base.entity.PersonPopedom;
import com.jpsoft.shinestar.modules.base.service.AlarmConfigService;
import com.jpsoft.shinestar.modules.base.service.CompanyInfoService;
import com.jpsoft.shinestar.modules.base.service.PersonInfoService;
import com.jpsoft.shinestar.modules.base.service.PersonPopedomService;
import com.jpsoft.shinestar.modules.business.entity.FillAttendance;
import com.jpsoft.shinestar.modules.business.service.FillAttendanceService;
import com.jpsoft.shinestar.modules.business.service.RequestForLeaveInfoService;
import com.jpsoft.shinestar.modules.common.utils.OSSUtil;
import com.jpsoft.shinestar.modules.common.dto.Sort;
import com.jpsoft.shinestar.modules.common.dto.MessageResult;
import com.jpsoft.shinestar.modules.business.entity.WorkAttendance;
import com.jpsoft.shinestar.modules.business.service.WorkAttendanceService;
import com.jpsoft.shinestar.modules.sys.entity.SysLog;
import com.jpsoft.shinestar.modules.sys.service.SysLogService;
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.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.ss.usermodel.*;
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.Months;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@RequestMapping("/business/workAttendance")
@Api(description = "考勤统计表")
@Slf4j
public class WorkAttendanceController {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private WorkAttendanceService workAttendanceService;

    @Autowired
    private CompanyInfoService companyInfoService;

    @Autowired
    private PersonInfoService personInfoService;

    @Autowired
    private AlarmConfigService alarmConfigService;

    @Autowired
    private OSSConfig ossConfig;

    @Autowired
    private RequestForLeaveInfoService requestForLeaveInfoService;

    @Autowired
    private ValueOperations<String, Object> valueOperations;

    @Autowired
    private PersonPopedomService personPopedomService;

    @Autowired
    private FillAttendanceService fillAttendanceService;

    @Autowired
    private SysLogService sysLogService;

    private Map<String,Object> pageSearch(String companyId,Boolean subordinate,String name,
                                        String position1,String position2,
                                        String position3,String position4,
                                        String position5,
                                        Date startDate,Date endDate,
                                        int pageIndex,int pageSize) throws Exception{
        Map<String,Object> dataMap = new HashMap<>();

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

        DateTime startTime = new DateTime(startDate);

        DateTime endTime = null;

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

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

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

        CompanyInfo companyInfo = companyInfoService.get(companyId);

        //todo 查询考勤设置
        List<AlarmConfig> alarmConfigList = alarmConfigService.findByCompanyId(companyId);

        Set<String> alarmConfigSet = new HashSet<>();

        for (AlarmConfig alarmConfig : alarmConfigList) {
            alarmConfigSet.add(alarmConfig.getId());
        }

        //todo 查询单位人员
        Map<String,Object> searchParams = new HashMap<>();

        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(position1)) {
            searchParams.put("position1", "%" + position1 + "%");
        }

        if (StringUtils.isNotEmpty(position2)) {
            searchParams.put("position2", "%" + position2 + "%");
        }

        if (StringUtils.isNotEmpty(position3)) {
            searchParams.put("position3", "%" + position3 + "%");
        }

        if (StringUtils.isNotEmpty(position4)) {
            searchParams.put("position4", "%" + position4 + "%");
        }

        if (StringUtils.isNotEmpty(position5)) {
            searchParams.put("position5", "%" + position5 + "%");
        }

        if (subordinate){
            searchParams.put("companyCode",companyInfo.getCode() + "%");
        }
        else{
            searchParams.put("companyCode",companyInfo.getCode());
        }

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

        Page<PersonInfo> personInfoPage = personInfoService.pageSearch(searchParams,pageIndex,pageSize,true,sortList);

        int days = Days.daysBetween(startTime,endTime).getDays();

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

        List<Map> personMapList = new ArrayList<>();

        for (PersonInfo personInfo : personInfoPage) {
            //todo 每个人在指定时间段（出勤天数，迟到次数，早退次数，上班缺卡次数，下班缺卡次数，旷工天数）
            int lateNum=0,leaveNum=0,missCardOnWorkCount=0,missCardOffWorkCount=0,missCardAllDayCount=0;

            BigDecimal workDays = new BigDecimal(0);

            Map<String,Object> personMap = new HashMap<>();
            Map<String,List> workAttendanceMap = new HashMap<>();

            for (int i=0;i<days;i++){
                List<WorkAttendance> list = new ArrayList<>();
                DateTime dt = startTime.plusDays(i);
                workAttendanceMap.put(dt.toString("yyyy-MM-dd"),list);
            }

            //todo 每个人在指定时间段内每天的考勤情况
            List<WorkAttendance> workAttendanceList = workAttendanceService.findByPersonIdAndDate(personInfo.getId(),startTime.toDate(),endTime.toDate());

            //todo 查询当天请假
//          Set<String> leaveHalfDays = requestForLeaveInfoService.findHalfDaysByPersonIdAndDate(personInfo.getId(),startTime.toDate(),endTime.toDate());
            Set<String> leaveHalfDays = new HashSet<>();
            Set<String> workHalfDays = new HashSet<>();

//          BigDecimal restDays = new BigDecimal(leaveHalfDays.size()/2);

            for (WorkAttendance workAttendance : workAttendanceList) {
                //考勤要属于当前考勤公司的记录
//                if(alarmConfigSet.contains(workAttendance.getAlarmConfigId())){
                    if(workAttendance.getRecordTime()!=null) {
                        String key = sdf.format(workAttendance.getRecordTime());

                        //如果是外勤打卡，读取备注
                        if ("1".equals(workAttendance.getType())){
                            FillAttendance fillAttendance = fillAttendanceService.findByBusinessWorkAttendanceId(workAttendance.getId());

                            if(fillAttendance!=null){
                                workAttendance.setWorkOutRemark(fillAttendance.getRemark());
                            }
                        }

                        workAttendanceMap.get(key).add(workAttendance);
                    }
//                }
            }

            for (int i=0;i<days;i++){
                DateTime dt = startTime.plusDays(i);
                String key = dt.toString("yyyy-MM-dd");

                List<WorkAttendance> workAttendances = workAttendanceMap.get(key);

                if (workAttendances.size()==0){
                    //单天不需要考勤则不会有记录
                    //restDays++;
                }
                else{
                    //周六上班算半天
                    if (dt.getDayOfWeek()==6) {
                        workDays = workDays.add(new BigDecimal(0.5));
                    }
                    else{
                        workDays = workDays.add(new BigDecimal(1));
                    }

                    int missCount = 0;

                    for (WorkAttendance workAttendance : workAttendances) {
                        String result = workAttendance.getResult();
                        DateTime recordTime = new DateTime(workAttendance.getRecordTime());

                        AlarmConfig alarmConfig = alarmConfigService.get(workAttendance.getAlarmConfigId());
                        DateTime attendanceTime = new DateTime(sdf2.parse(recordTime.toString("yyyy-MM-dd") + " " + alarmConfig.getAttendanceTime()));

                        int middleDay = 12*60; //每天12点，作为上下午分界点

                        if (result==null){
                            result = "";
                        }

                        if (result.equals(WorkAttendance.SUCCESS)
                        || result.equals(WorkAttendance.LATE)
                        || result.equals(WorkAttendance.LEAVE_EARLY)){
                            if (result.equals(WorkAttendance.LATE)){
                                lateNum++; //迟到
                            }
                            else if(result.equals(WorkAttendance.LEAVE_EARLY)){
                                leaveNum++; //早退
                            }

                            /**
                             * 查看打卡时间对应的考勤时间,查看打卡记录时间有可能是周六下午才打下班卡，但考勤时间是中午12点
                             * 但如果上下班考勤时间都设置为12点，就无法计算下午是否正常上班(出差打卡)
                             */
//                            if (attendanceTime.getMinuteOfDay()<= middleDay) {
//                                workHalfDays.add(recordTime.toString("yyyy-MM-dd") + " 上午");
//                            } else {
//                                workHalfDays.add(recordTime.toString("yyyy-MM-dd") + " 下午");
//                            }
                        }
                        else if(result.equals(WorkAttendance.MISSING)){
                            if (workAttendance.getClassifier().equals(1)) {
                                //上班缺卡
                                missCardOnWorkCount++;
                            } else {
                                //下班缺卡
                                missCardOffWorkCount++;
                            }

                            missCount++;
                        }
                        else if(result.equals(WorkAttendance.REST)){
                            if (attendanceTime.getMinuteOfDay()<= middleDay) {
                                leaveHalfDays.add(recordTime.toString("yyyy-MM-dd") + " 上午");
                            } else {
                                leaveHalfDays.add(recordTime.toString("yyyy-MM-dd") + " 下午");
                            }
                        }
                    }

                    if (missCount == workAttendances.size()){
                        //当天的考勤全部缺卡
                        missCardAllDayCount++;
                    }
                }
            }

            //上班天数
            //BigDecimal workDays = new BigDecimal(workHalfDays.size()).divide(new BigDecimal(2));

            //请假天数
            BigDecimal restDays = new  BigDecimal(leaveHalfDays.size()).divide(new BigDecimal(2));

            personMap.put("name",personInfo.getName());
            personMap.put("personId",personInfo.getId());
            personMap.put("companyId",personInfo.getCompanyId());

            //todo 人员有可能有多个单位，要找当前与选择单位有上下级关系的
            CompanyInfo _companyInfo = companyInfoService.get(personInfo.getCompanyId());

            if (!_companyInfo.getCode().startsWith(companyInfo.getCode())) {
                List<PersonPopedom> personPopedoms = personPopedomService.findByPersonIdAndCompanyCode(personInfo.getId(), companyInfo.getCode() + "%");

                if (personPopedoms.size() > 0) {
                    String _companyId = personPopedoms.get(0).getCompanyId();
                    _companyInfo = companyInfoService.get(_companyId);
                }
            }

            //所有上级单位
            String[] arr = _companyInfo.getCode().split(",");

            CompanyInfo company = null;
            CompanyInfo parentDepartment = null;
            CompanyInfo department = null;

            for(int j=0;j<arr.length;j++) {
                //找出上级单位中类型为公司的记录
                CompanyInfo parent = companyInfoService.get(arr[j]);

                if ("1".equals(parent.getUnitType())){
                    company = parent;

                    if(j+1<arr.length){
                        parentDepartment =  companyInfoService.get(arr[j+1]);
                    }

                    if(j+2<arr.length){
                        department =  companyInfoService.get(arr[j+2]);
                    }

                    break;
                }
            }

            //公司
            if(company!=null){
                personMap.put("companyName",company.getName());
            }

            //上级部门
            if(parentDepartment!=null) {
                if (!parentDepartment.getId().equals(_companyInfo.getId())) {
                    personMap.put("parentDepartmentName",parentDepartment.getName());
                }
            }

            //部门
            if(department!=null) {
                personMap.put("departmentName",department.getName());
            }
            else{
                personMap.put("departmentName",_companyInfo.getName());
            }

            //打卡天数-请假天数-缺卡天数
            personMap.put("workDays",workDays.subtract(restDays).subtract(new BigDecimal(missCardAllDayCount)));
            personMap.put("restDays",restDays);
            personMap.put("lateNum",lateNum);
            personMap.put("leaveNum",leaveNum);
            personMap.put("missCardOnWorkCount",missCardOnWorkCount);
            personMap.put("missCardOffWorkCount",missCardOffWorkCount);
            personMap.put("missCardAllDayCount",missCardAllDayCount);
            personMap.put("workAttendanceMap",workAttendanceMap);

            personMapList.add(personMap);
        }

        dataMap.put("totalElements",personInfoPage.getTotal());
        dataMap.put("totalPage",personInfoPage.getPages());
        dataMap.put("pageNumber",personInfoPage.getPageNum());
        dataMap.put("pageSize",personInfoPage.getPageSize());
        dataMap.put("data", personMapList);

        List<Map> dayColumns = new ArrayList<>();

        for (int i=0;i<days;i++){
            Map<String,Object> map = new HashMap<>();
            DateTime dt = startTime.plusDays(i);

            map.put("name",dt.toString("yyyy-MM-dd"));
            map.put("label",dt.toString("MM-dd") + " " + dt.dayOfWeek().getAsShortText(Locale.CHINA));

            dayColumns.add(map);
        }

        dataMap.put("dayColumns", dayColumns);

        return dataMap;
    }

    @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 = "statList",method = RequestMethod.POST)
    public MessageResult<Map> statList(
            String companyId,String name,
            String position1,String position2,
            String position3,String position4,
            String position5,
            @RequestParam(value="subordinate",defaultValue="false")  Boolean subordinate,
            @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
            @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate,
            @RequestParam(value="pageIndex",defaultValue="1") int pageIndex,
            @RequestParam(value="pageSize",defaultValue="20") int pageSize,
            @RequestAttribute String subject){
        MessageResult<Map> msgResult = new MessageResult<>();

        try {
            Map<String,Object> dataMap = pageSearch(companyId,subordinate,name,position1,position2,position3,position4,position5,startDate,endDate,pageIndex,pageSize);

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

        return msgResult;
    }

    private CellStyle createCellStyle(Workbook wb){
        CellStyle cellStyle = wb.createCellStyle();

        cellStyle.setBorderTop(BorderStyle.THIN);
        cellStyle.setBorderBottom(BorderStyle.THIN);
        cellStyle.setBorderLeft(BorderStyle.THIN);
        cellStyle.setBorderRight(BorderStyle.THIN);
        cellStyle.setWrapText(true);
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

        return cellStyle;
    }

    @ApiOperation(value="导出考勤报表")
    @RequestMapping(value = "exportXls",method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name="companyId",value = "单位编号",required = true,paramType = "form"),
            @ApiImplicitParam(name = "subordinate",value = "是否查询下级单位", required = false, paramType = "form",dataType = "String"),
            @ApiImplicitParam(name="name",value = "用户姓名",required = false,paramType = "form"),
            @ApiImplicitParam(name="jobNumber",value = "工号",required = false,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")
    })
    public MessageResult<String> exportXls(
            String companyId,String name,String jobNumber,
            String position1,String position2,
            String position3,String position4,
            String position5,
            @RequestParam(value="subordinate",defaultValue="false")  Boolean subordinate,
            @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
            @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate,
            @RequestAttribute String subject) throws Exception {
        MessageResult<String> msgResult = new MessageResult<>();

        try {
            DateTime startTime = new DateTime(startDate);
            DateTime endTime = new DateTime(endDate);

            Map<String,Object> dataMap = pageSearch(companyId,subordinate,name,position1,position2,position3,position4,position5,startDate,endDate,1,10000);

            List<Map> personMapList = (List<Map>)dataMap.get("data");

            int days = Days.daysBetween(startTime, endTime).getDays();
            ClassPathResource resource = new ClassPathResource("static/workAttendanceReport.xls");

            Workbook wb = WorkbookFactory.create(resource.getInputStream());

            Sheet sheet = wb.getSheetAt(0);

            Row row1 = sheet.getRow(0);
            Row row2 = sheet.getRow(1);
            Row row3 = sheet.getRow(2);

            String title = row1.getCell(0).getStringCellValue();
            String subTitle = row2.getCell(0).getStringCellValue();

            row1.getCell(0).setCellValue(String.format(title, startTime.toString("yyyy-MM-dd"), endTime.toString("yyyy-MM-dd")));
            row2.getCell(0).setCellValue(String.format(subTitle, DateTime.now().toString("yyyy-MM-dd HH:mm")));

            int dayStartColIndex = 11;

            for (int i = 0; i <= days; i++) {
                DateTime dt = startTime.plusDays(i);
                row3.getCell(dayStartColIndex + i).setCellValue(dt.toString("MM-dd") + "\r\n" + dt.dayOfWeek().getAsShortText(Locale.CHINA));
            }

            //todo 写考勤记录
            int startRowIndex = 3;

            Font redFont = wb.createFont();
            redFont.setColor(IndexedColors.RED.index);

            Font greenFont = wb.createFont();
            greenFont.setColor(IndexedColors.GREEN.index);

            Font greyFont = wb.createFont();
            greyFont.setColor(IndexedColors.BLUE_GREY.index);

            for (int i = 0; i < personMapList.size(); i++) {
                int colIndex = 0;

                Row row = sheet.createRow(startRowIndex + i);
                Map personMap = personMapList.get(i);

                String personName = (String) personMap.get("name");
                row.createCell(colIndex).setCellValue(personName);
                colIndex++;

                String _companyId = (String) personMap.get("companyId");

                //公司
                if(personMap.get("companyName")!=null){
                    row.createCell(colIndex).setCellValue(personMap.get("companyName").toString());
                }

                colIndex++;

                //上级部门
                if(personMap.get("parentDepartmentName")!=null){
                    row.createCell(colIndex).setCellValue(personMap.get("parentDepartmentName").toString());
                }

                colIndex++;

                //部门
                if(personMap.get("departmentName")!=null){
                    row.createCell(colIndex).setCellValue(personMap.get("departmentName").toString());
                }

                colIndex++;

                Double workDays = Double.valueOf(personMap.get("workDays").toString());
                row.createCell(colIndex).setCellValue(workDays);

                colIndex++;

                Double restDays = Double.valueOf(personMap.get("restDays").toString());
                row.createCell(colIndex).setCellValue(restDays);
                colIndex++;

                Double lateNum = Double.valueOf(personMap.get("lateNum").toString());
                row.createCell(colIndex).setCellValue(lateNum);
                colIndex++;

                Double leaveNum = Double.valueOf(personMap.get("leaveNum").toString());
                row.createCell(colIndex).setCellValue(leaveNum);
                colIndex++;

                Double missCardOnWorkCount = Double.valueOf(personMap.get("missCardOnWorkCount").toString());
                row.createCell(colIndex).setCellValue(missCardOnWorkCount);
                colIndex++;

                Double missCardOffWorkCount = Double.valueOf(personMap.get("missCardOffWorkCount").toString());
                row.createCell(colIndex).setCellValue(missCardOffWorkCount);
                colIndex++;

                Double missCardAllDayCount = Double.valueOf(personMap.get("missCardAllDayCount").toString());
                row.createCell(colIndex).setCellValue(missCardAllDayCount);
                colIndex++;

                Map<String, List> workAttendanceMap = (Map<String, List>) personMap.get("workAttendanceMap");

                SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");

                for (int j = 0; j <= days; j++) {
                    String key = startTime.plusDays(j).toString("yyyy-MM-dd");

                    if (workAttendanceMap.containsKey(key)) {
                        List<WorkAttendance> workAttendanceList = workAttendanceMap.get(key);

                        List<Map> posList = new ArrayList<>();

                        StringBuilder sb = new StringBuilder();

                        for (WorkAttendance item : workAttendanceList) {
                            if (sb.length() != 0) {
                                sb.append("\r\n");
                            }

                            if (item.getSources().equals("1")) {
                                sb.append("内勤");
                            } else {
                                sb.append("外勤");
                            }

                            if (item.getClassifier().equals(1)) {
                                sb.append("上班");
                            } else {
                                sb.append("下班");
                            }

                            String status = item.getResult();

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

                            int offset = 4;

                            if (WorkAttendance.MISSING.equals(status)) {
                                pos.put("start", sb.length() - offset);
                                sb.append("缺卡");
                                pos.put("font", redFont);
                            } else if (WorkAttendance.SUCCESS.equals(status)) {
                                pos.put("start", sb.length() - offset);
                                sb.append("打卡");
                                pos.put("font", greenFont);
                            } else if (WorkAttendance.LEAVE_EARLY.equals(status)) {
                                pos.put("start", sb.length() - offset);
                                sb.append("早退");
                                pos.put("font", greyFont);
                            } else if (WorkAttendance.LATE.equals(status)) {
                                pos.put("start", sb.length() - offset);
                                sb.append("迟到");
                                pos.put("font", greyFont);
                            }else if (WorkAttendance.REST.equals(status)) {
                                pos.put("start", sb.length() - offset);
                                sb.append("请假");
                                pos.put("font", greyFont);
                            }

                            if (item.getRecordTime() != null) {
                                sb.append(" " + sdf.format(item.getRecordTime()));
                            }

                            if (StringUtils.isNotEmpty(item.getWorkOutRemark())){
                                sb.append("(" + item.getWorkOutRemark() + ")");
                            }

                            pos.put("end", sb.length());
                            posList.add(pos);
                        }

                        HSSFRichTextString sText = new HSSFRichTextString(sb.toString());

                        for (Map map : posList) {
                            int start = Integer.valueOf(map.get("start").toString());
                            int end = Integer.valueOf(map.get("end").toString());
                            Font font = (Font)map.get("font");

                            sText.applyFont(start, end, font);
                        }

                        row.createCell(dayStartColIndex + j).setCellValue(sText);
                    }
                }
            }

            CellStyle cellStyle1 = createCellStyle(wb);

            for (int i = 0; i < personMapList.size(); i++) {
                Row row = sheet.getRow(startRowIndex + i);

                if (row != null) {
                    for (int j = 0; j < row.getLastCellNum(); j++) {
                        if (row.getCell(j) == null) {
                            row.createCell(j);
                        }

                        row.getCell(j).setCellStyle(cellStyle1);
                    }
                }
            }

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

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

            String fileName = "考勤统计表.xls";

            String downloadUrl = OSSUtil.upload(ossConfig, "workAttendance", fileName, input);

            wb.write(output);
            wb.close();
            output.close();

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

        return msgResult;
    }

    @ApiOperation(value="更新考勤记录")
    @ApiImplicitParams({
            @ApiImplicitParam(name="companyId",value = "单位编号",required = true,paramType = "form"),
            @ApiImplicitParam(name = "startDate",value = "开始时间", required = true,paramType="form"),
            @ApiImplicitParam(name = "endDate",value = "截止时间", required = true,paramType="form"),
            @ApiImplicitParam(name = "alarmConfigId",value = "考勤编号", required = false,paramType="form"),
            @ApiImplicitParam(name = "subject",value = "subject", required = false,paramType="form")
    })
    @RequestMapping(value = "batchUpdate",method = RequestMethod.POST)
    public MessageResult<String> batchUpdate(
            String companyId,
            @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
            @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate,
            String alarmConfigId,
            @RequestAttribute String subject) {
        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("最多只能更新一个月内的考勤记录!");
            }

            if (StringUtils.isEmpty(alarmConfigId)){
                alarmConfigId = null;
            }

            SysLog sysLog = new SysLog();
            sysLog.setPointcut("更新考勤记录");
            sysLog.setUrl("batchUpdate");
            sysLog.setRemark("更新单位：" + companyId + ",考勤时段：" + startTime.toString("yyyy-MM-dd") + "," + endTime.toString("yyyy-MM-dd"));
            sysLog.setUserId(subject);
            sysLog.setCreateTime(new Date());
            sysLogService.insert(sysLog);

            log.warn("用户:{}更新单位:{},{}至{}时段考勤记录。",subject,companyId,
                    startTime.toString("yyyy-MM-dd"),endTime.toString("yyyy-MM-dd"));

            int affectCount = workAttendanceService.batchUpdate(companyId,alarmConfigId, startDate, endDate);

            messageResult.setResult(true);
            messageResult.setMessage("共添加" + affectCount + "考勤记录");
        }
        catch (Exception ex){
            logger.error(ex.getMessage(),ex);
            messageResult.setResult(false);
            messageResult.setMessage(ex.getMessage());
        }

        return messageResult;
    }

    @ApiOperation(value="微信通知")
    @ApiImplicitParams({
            @ApiImplicitParam(name="alarmConfigId",value = "单位编号",required = true,paramType = "form")
    })
    @RequestMapping(value = "wxNotice",method = RequestMethod.POST)
    public MessageResult<String> wxNotice(String alarmConfigId) {
        MessageResult<String> messageResult = new MessageResult<>();

        try {
            AlarmConfig alarmConfig = alarmConfigService.get(alarmConfigId);

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
            String date = DateTime.now().toString("yyyy-MM-dd");

            DateTime startTime = new DateTime(sdf.parse(date + " " + alarmConfig.getStartTime()));
            DateTime endTime = new DateTime(sdf.parse(date + " " + alarmConfig.getEndTime()));

//            unmeasureTemperatureAlarmTask.noticePerson(alarmConfig,startTime,endTime);
//            unmeasureTemperatureAlarmTask.noticeManager(alarmConfig,startTime,endTime);

            messageResult.setResult(true);
        }
        catch (Exception ex){
            logger.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") Date recordTime) {
        MessageResult<String> messageResult = new MessageResult<>();

        try {
            boolean result = workAttendanceService.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;
    }

    public static void main(String[] args) {
        System.out.println(DateTime.now().getDayOfWeek());
    }
}
