package com.ruoyi.web.controller.kaoqin;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.MapToObjectUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.vo.BaobiaoVo;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.ICardReplacementRecordService;
import com.ruoyi.system.service.IKaoqinConfigService;
import com.ruoyi.system.service.IKaoqinRecordService;
import com.ruoyi.system.service.ISysDictDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

import static com.ruoyi.common.constant.CacheConstants.WEEK;
import static com.ruoyi.common.constant.Constants.*;

/**
 * 实现考勤打卡
 *
 * @Author: tjf
 * @Date: 2023/2/1 14:46
 * @Describe:
 */
@RestController
@RequestMapping("/kaoQin")
public class KaoQinController extends BaseController {

    @Autowired
    private IKaoqinConfigService kaoqinConfigService;

    @Autowired
    private IKaoqinRecordService kaoqinRecordService;


    @Autowired
    private ISysDictDataService dictDataService;

    @Autowired
    private CardReplacementRecordMapper cardReplacementRecordMapper;

    @Autowired
    private RecordLeaveMapper recordLeaveMapper;

    @Autowired
    private BusinessTripMapper businessTripMapper;

    @Autowired
    private AttendanceTimeMapper attendanceTimeMapper;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private SysDeptMapper deptMapper;

    @Autowired
    private KaoqinRecordMapper kaoqinRecordMapper;

    /**
     * 定位打卡提供计算参数
     *
     * @param kaoqinConfig
     * @return
     */
    @PreAuthorize("@ss.hasPermi('kaoqin:daKa:param')")
    @GetMapping(value = "/daKa")
    public AjaxResult daKa(KaoqinConfig kaoqinConfig) {
        //查询考勤规则
        KaoqinConfig kaoqinConfigDept = kaoqinConfigService.selectKaoqinConfigBynew();
        //先去 根据当前人员的部门id查询是否有规则,没有再去查祖籍列表
        /*KaoqinConfig kaoqinConfigDept = kaoqinConfigService.selectKaoqinConfigByDeptId(kaoqinConfig.getDeptId());
        if (kaoqinConfigDept == null) {
            //根据部门祖籍列表,查询该部门考勤范围 ,经纬度
            List<KaoqinConfig> kaoqinConfigs = kaoqinConfigService.selectKaoqinConfigList(kaoqinConfig);
            if (kaoqinConfigs != null && kaoqinConfigs.size() > 1) {
                //如果有多条考勤规则,先选离自己最近的规则
                String ancestors = kaoqinConfig.getAncestors();
                String[] split = ancestors.split(",");
                Map<Long, List<KaoqinConfig>> collect = kaoqinConfigs.stream().collect(Collectors.groupingBy(KaoqinConfig::getDeptId));
                for (int i = split.length - 1; i >= 0; i--) {
                    String s = split[i];
                    List<KaoqinConfig> kaoqinConfigsDept = collect.get(Long.parseLong(s));
                    if (kaoqinConfigsDept != null) {
                        return AjaxResult.success(kaoqinConfigsDept);
                    }
                }
            }
        }*/
        return AjaxResult.success(kaoqinConfigDept);
    }


    /**
     * 查询考勤记录列表
     */
    @GetMapping("/list")
    public TableDataInfo list(KaoqinRecord kaoqinRecord) {
        List<KaoqinRecord> list = kaoqinRecordService.selectKaoqinRecordList(kaoqinRecord);
        return getDataTable(list);
    }

    /**
     * 查询考勤异常数据信息
     * 包括所有异常的数量
     * 本月考勤记录的异常分类数量
     */
    @PreAuthorize("@ss.hasPermi('kaoqin:statistics:abnormal')")
    @GetMapping("/abnormal")
    public AjaxResult abnormal(KaoqinRecord kaoqinRecord) {

        //传入userId/年 和 月份 设置查询异常的考勤
        //kaoqinRecord.setKaStatus("2");
        List<KaoqinRecord> kaoQinRecords = kaoqinRecordMapper.selectKaoqinRecordList(kaoqinRecord);
        //记录该月有多少次异常总数
        Long count = 0L;
        SysDictData dictData = new SysDictData();
        dictData.setDictType("kaoqin_abnormal");
        List<SysDictData> sysDictData = dictDataService.selectDictDataList(dictData);
        Map<String, Long> map = new HashMap();
        for (SysDictData sysDictDatum : sysDictData) {
            //获取异常的值
            String dictValue = sysDictDatum.getDictValue();
            if (!ONE.equals(dictValue)) {
                //获取异常名称
                String dictLabel = dictToString(sysDictDatum.getDictValue());
                Long aLong = 0L;
                map.put(dictLabel, aLong);
            }
        }
        for (KaoqinRecord kaoQinRecord : kaoQinRecords) {
            String kaTypeAmIn = kaoQinRecord.getKaTypeAmIn();
            String kaTypeAmOut = kaoQinRecord.getKaTypeAmOut();
            String kaTypePmIn = kaoQinRecord.getKaTypePmIn();
            String kaTypePmOut = kaoQinRecord.getKaTypePmOut();
            if (!ONE.equals(kaTypeAmIn) && StringUtils.isNotBlank(kaTypeAmIn)) {
                //获取异常名称
                String dictLabel = dictToString(kaTypeAmIn);
                map.compute(dictLabel, (k, aLong) -> aLong + 1);
                if (!SIX.equals(kaTypeAmIn) && !SEVEN.equals(kaTypeAmIn) && !EIGHT.equals(kaTypeAmIn)) {
                    count = count + 1;
                }

            }
            if (!ONE.equals(kaTypeAmOut) && StringUtils.isNotBlank(kaTypeAmOut)) {
                //获取异常名称
                String dictLabel = dictToString(kaTypeAmOut);
                map.compute(dictLabel, (k, aLong) -> aLong + 1);
                if (!SIX.equals(kaTypeAmOut) && !SEVEN.equals(kaTypeAmOut) && !EIGHT.equals(kaTypeAmOut)) {
                    count = count + 1;
                }
            }
            if (!ONE.equals(kaTypePmIn) && StringUtils.isNotBlank(kaTypePmIn)) {
                //获取异常名称
                String dictLabel = dictToString(kaTypePmIn);
                map.compute(dictLabel, (k, aLong) -> aLong + 1);
                if (!SIX.equals(kaTypePmIn) && !SEVEN.equals(kaTypePmIn) && !EIGHT.equals(kaTypePmIn)) {
                    count = count + 1;
                }
            }
            if (!ONE.equals(kaTypePmOut) && StringUtils.isNotBlank(kaTypePmOut)) {
                //获取异常名称
                String dictLabel = dictToString(kaTypePmOut);
                map.compute(dictLabel, (k, aLong) -> aLong + 1);
                if (!SIX.equals(kaTypePmOut) && !SEVEN.equals(kaTypePmOut) && !EIGHT.equals(kaTypePmOut)) {
                    count = count + 1;
                }
            }
        }
        map.put("count", count);
        return AjaxResult.success(map);
    }


    /**
     * 考勤日历
     */
    @PreAuthorize("@ss.hasPermi('kaoqin:statistics:calendar')")
    @GetMapping("/calendar")
    public AjaxResult calendar(KaoqinRecord kaoqinRecord) {
        //根据打卡人id和月份去找对应的打卡记录
        List<KaoqinRecord> kaoqinRecords = kaoqinRecordMapper.selectKaoqinRecordList(kaoqinRecord);
        //查询传入月补卡信息
        CardReplacementRecord cardReplacementRecord = new CardReplacementRecord();
        cardReplacementRecord.setUserId(kaoqinRecord.getUserId());
        String qDate = kaoqinRecord.getKaYear() + "-" + kaoqinRecord.getKaMonth() + "-01";
        cardReplacementRecord.setApplicationDate(qDate);
        //cardReplacementRecord.setIsPass("2");
        List<CardReplacementRecord> cardReplacementRecordList = cardReplacementRecordMapper.selectCardReplacementRecordList(cardReplacementRecord);
        Map<String, List<CardReplacementRecord>> cardReplacementCollect = cardReplacementRecordList.stream().collect(Collectors.groupingBy(CardReplacementRecord::getApplicationDate));
        //查询传入月请假信息
        RecordLeave recordLeave = new RecordLeave();
        String month = kaoqinRecord.getKaYear() + "-" + kaoqinRecord.getKaMonth();
        recordLeave.setStartTime(DateUtils.parseDate(month + "-" + "01 00:00:00"));
        String fin = DateUtils.getLastDayOfMonth(Integer.parseInt(kaoqinRecord.getKaYear()), Integer.parseInt(kaoqinRecord.getKaMonth()));
        recordLeave.setEndTime(DateUtils.parseDate(fin + " 23:59:59"));
        recordLeave.setAbsenteeId(String.valueOf(kaoqinRecord.getUserId()));
        //recordLeave.setIsPass("2");
        List<RecordLeave> recordLeaves = recordLeaveMapper.selectRecordLeaveList(recordLeave);
        //查询传入月出差信息
        BusinessTrip businessTrip = new BusinessTrip();
        businessTrip.setStartTime(DateUtils.parseDate(month + "-" + "01 00:00:00"));
        businessTrip.setEndTime(DateUtils.parseDate(fin + " 23:59:59"));
        businessTrip.setUserId(kaoqinRecord.getUserId());
        //businessTrip.setIsPass("2");
        List<BusinessTrip> businessTrips = businessTripMapper.selectBusinessTripListLb(businessTrip);

        //查询考勤日期
        SysDept sysDept = deptMapper.selectDeptById(kaoqinRecord.getDeptId());
        //查询部门考勤日期规则
        AttendanceTime attendanceTime = new AttendanceTime();
        attendanceTime.setDeptName(sysDept.getDeptName());
        List<AttendanceTime> attendanceTimes = attendanceTimeMapper.selectAttendanceTimeList(attendanceTime);

        String key = "monthHoliday" + kaoqinRecord.getKaYear() + "-" + kaoqinRecord.getKaMonth();
        String jsonResult = redisCache.getCacheObject(key);
        Map<String, Integer> holidayMap = new HashMap<>();
        if(StringUtils.isNotBlank(jsonResult)){
            Gson gson = new Gson();
            //判断当天天是否是法定节假日  0 上班 1周末 2节假日 mapKey为去掉-的日期：20250101
            holidayMap = gson.fromJson(jsonResult,
                    new TypeToken<Map<String, Integer>>() {
                    }.getType());
        }


        //获取月份的所有日期
        List<String> allDate = DateUtils.getAllDateStringsInMonth(Integer.parseInt(kaoqinRecord.getKaYear()), Integer.parseInt(kaoqinRecord.getKaMonth()));
        List list = new ArrayList();
        Map<String, List<KaoqinRecord>> collect = new HashMap<>();
        if (kaoqinRecords != null && kaoqinRecords.size() > 0) {
            collect = kaoqinRecords.stream().collect(Collectors.groupingBy(KaoqinRecord::getKaTime));
        }

        for (String date : allDate) {

            Map<String, Object> map = new HashMap();
            //日期
            map.put("data", date);
            //1上班 2休息
            map.put("type", "1");
            //判断放假还是工作 0 上班 1周末 2节假日
            if (holidayMap.containsKey(date.replace("-", "")) && 0 != holidayMap.get(date.replace("-", ""))) {
                map.put("type", "2");
            }
            if(attendanceTimes != null && !attendanceTimes.isEmpty()){
                for (AttendanceTime time : attendanceTimes) {
                    if(DateUtils.isDateBetween(DateUtils.parseDate(date), time.getStartTime(), time.getEndTime())){
                        map.put("type", "2");
                        break;
                    }
                }
            }

            List<RecordLeave> recordList = new ArrayList<>();
            List<BusinessTrip> businessList = new ArrayList<>();
            //请假信息
            for (RecordLeave recordLeaf : recordLeaves) {
                if (DateUtils.isDateBetween(DateUtils.parseDate(date), recordLeaf.getStartTime(), recordLeaf.getEndTime())) {
                    recordList.add(recordLeaf);
                }

            }
            //出差信息
            for (BusinessTrip trip : businessTrips) {
                if (DateUtils.isDateBetween(DateUtils.parseDate(date), trip.getStartTime(), trip.getEndTime())) {
                    businessList.add(trip);
                }

            }
            //定义标签显示状态
            String abnormal = "";
            List<KaoqinRecord> kaoqinRecords1 = new ArrayList<>();
            if (collect.containsKey(date)) {
                kaoqinRecords1 = collect.get(date);
                Boolean flag = true;
                for (KaoqinRecord record : kaoqinRecords1) {
                    String kaTypeAmIn = record.getKaTypeAmIn();
                    String kaTypeAmOut = record.getKaTypeAmOut();
                    String kaTypePmIn = record.getKaTypePmIn();
                    String kaTypePmOut = record.getKaTypePmOut();
                    if (!"1".equals(kaTypeAmIn) && StringUtils.isNotBlank(kaTypeAmIn)) {
                        abnormal = kaTypeAmIn + ",";
                        flag = false;
                    }
                    if (!"1".equals(kaTypeAmOut) && StringUtils.isNotBlank(kaTypeAmOut)) {
                        abnormal = kaTypeAmOut + ",";
                        flag = false;
                    }
                    if (!"1".equals(kaTypePmIn) && StringUtils.isNotBlank(kaTypePmIn)) {
                        abnormal = kaTypePmIn + ",";
                        flag = false;
                    }
                    if (!"1".equals(kaTypePmOut) && StringUtils.isNotBlank(kaTypePmOut)) {
                        abnormal = kaTypePmOut + ",";
                        flag = false;
                    }
                }
                if (flag) {
                    abnormal = "1";
                } else {
                    abnormal = abnormal.substring(0, abnormal.length() - 1);
                }
            }

            //标签显示状态
            map.put("info", abnormal);
            //标签显示状态补卡，出差，请假
            Boolean fo = false;
            if(cardReplacementCollect.get(date)!=null || !recordList.isEmpty() || !businessList.isEmpty()){
                fo = true;
            }
            map.put("fo", fo);
            //打卡记录列表
            map.put("list", kaoqinRecords1);
            //补卡信息
            map.put("bk", cardReplacementCollect.get(date));
            //请假信息
            map.put("qj", recordList);
            //出差信息
            map.put("cc", businessList);
            list.add(map);
        }
        return AjaxResult.success(list);
    }

    /**
     * 个人中心,打卡记录统计
     * 只有管理员能看到
     *
     * @param
     * @return
     */
    @PreAuthorize("@ss.hasPermi('kaoqin:statistics:clockRecord')")
    @PostMapping("/clockRecord")
    public AjaxResult clockRecord(KaoqinRecord kaoqinRecord) {

        List<Map<String, Object>> list = kqRecord(kaoqinRecord);
        return AjaxResult.success(list);
    }

    private List<Map<String, Object>> kqRecord(KaoqinRecord kaoqinRecord) {
        if (StringUtils.isEmpty(kaoqinRecord.getKaMonth())) {
            kaoqinRecord.setKaYear(DateUtils.getYear());
            kaoqinRecord.setKaMonth(DateUtils.justMonth());
        }
        //定义返回值
        List<Map<String, Object>> list = new ArrayList();
        //根据部门id查询考勤数据
        List<KaoqinRecord> kaoqinRecords = kaoqinRecordMapper.selectKaoqinRecordList(kaoqinRecord);
        if (kaoqinRecords != null) {
            //根据userId进行分组
            Map<Long, List<KaoqinRecord>> kaoQinRecords = kaoqinRecords.stream().collect(Collectors.groupingBy(KaoqinRecord::getUserId));
            SysDictData dictData = new SysDictData();
            dictData.setDictType("kaoqin_abnormal");
            //找到所有的异常
            List<SysDictData> sysDictData = dictDataService.selectDictDataList(dictData);
            /*Map<String, String> map = new HashMap<>();
            if (sysDictData != null) {
                for (SysDictData sysDictDatum : sysDictData) {
                    //获取异常名称
                    String dictLabel = sysDictDatum.getDictLabel();
                    //获取异常的值
                    String dictValue = sysDictDatum.getDictValue();
                    map.put(dictValue, dictValue);
                }
            }*/

            for (List<KaoqinRecord> value : kaoQinRecords.values()) {
                if (value != null) {
                    //定义返回的人
                    Map<String, Object> userMap = new HashMap();
                    userMap.put("userName", value.get(0).getUserName());
                    userMap.put("deptName", value.get(0).getDeptName());
                    userMap.put("list", value);

                    for (SysDictData sysDictDatum : sysDictData) {
                        //获取异常的值
                        String dictValue = dictToString(sysDictDatum.getDictValue());
                        userMap.put(dictValue, 0);
                    }

                    for (KaoqinRecord kaoQinRecord : value) {
                        String kaTypeAmIn = kaoQinRecord.getKaTypeAmIn();
                        String kaTypeAmOut = kaoQinRecord.getKaTypeAmOut();
                        String kaTypePmIn = kaoQinRecord.getKaTypePmIn();
                        String kaTypePmOut = kaoQinRecord.getKaTypePmOut();
                        if (StringUtils.isNotBlank(kaTypeAmIn)) {
                            //获取异常的名称
                            String dictLabel = dictToString(kaTypeAmIn);
                            Integer num = (Integer) userMap.get(dictLabel);
                            userMap.put(dictLabel, num + 1);
                        }
                        if (StringUtils.isNotBlank(kaTypeAmOut)) {
                            String dictLabel = dictToString(kaTypeAmOut);
                            //获取异常的名称
                            Integer num = (Integer) userMap.get(dictLabel);
                            userMap.put(dictLabel, num + 1);
                        }
                        if (StringUtils.isNotBlank(kaTypePmIn)) {
                            String dictLabel = dictToString(kaTypePmIn);
                            //获取异常的名称
                            Integer num = (Integer) userMap.get(dictLabel);
                            userMap.put(dictLabel, num + 1);
                        }
                        if (StringUtils.isNotBlank(kaTypePmOut)) {
                            String dictLabel = dictToString(kaTypePmOut);
                            //获取异常的名称
                            Integer num = (Integer) userMap.get(dictLabel);
                            userMap.put(dictLabel, num + 1);
                        }
                    }
                    list.add(userMap);
                }
            }
        }
        return list;
    }

    /**
     * 查询考勤异常数据信息
     * 包括所有异常的数量
     * 今日打卡统计
     */
    @PreAuthorize("@ss.hasPermi('kaoqin:statistics:dayAbnormal')")
    @GetMapping("/day/abnormal")
    public AjaxResult dayAbnormal(KaoqinRecord kaoqinRecord) {
        if (StringUtils.isEmpty(kaoqinRecord.getKaTime())) {
            kaoqinRecord.setKaTime(DateUtils.getDate());
        }
        Map<String, Object> map = new HashMap();
        //查询当天考勤数据
        Map<String, Long> todayMap = day(kaoqinRecord);
        //查询昨天考勤数据
        //获取昨天日期
        String yesterday = DateUtils.getYesterday(kaoqinRecord.getKaTime());
        kaoqinRecord.setKaTime(yesterday);
        Map<String, Long> yesterdayMap = day(kaoqinRecord);
        for (String s : todayMap.keySet()) {
            Map<String, Object> mapZj = new HashMap();
            String zz = "0%";
            //1:正，2负 3:平
            String zt = "3";
            mapZj.put("num", todayMap.get(s));

            BigDecimal todayBd = new BigDecimal(todayMap.get(s));
            BigDecimal yesterdayBd = new BigDecimal(yesterdayMap.get(s));
            BigDecimal fz = todayBd.subtract(yesterdayBd);
            //比较是否等于0，返回true则不等于0，返回false，则等于0
            if (fz.compareTo(BigDecimal.ZERO) != 0 && yesterdayBd.compareTo(BigDecimal.ZERO) != 0) {
                BigDecimal percentage = BigDecimal.ZERO;
                //昨天数据>0
                if (yesterdayBd.compareTo(BigDecimal.ZERO) > 0) {
                    percentage = fz.multiply(new BigDecimal("100"))
                            .divide(yesterdayBd, 3, RoundingMode.HALF_UP) // 先计算百分比并保留三位小数以处理可能的精度问题
                            .setScale(1, RoundingMode.HALF_UP);     // 再设置为一位小数
                }
                zz = percentage + "%";
                zt = "1";
                if (percentage.compareTo(BigDecimal.ZERO) < 0) {
                    zt = "2";
                    zz = (percentage.multiply(new BigDecimal("-1"))) + "%";
                    ;
                }
            } else {
                if (yesterdayBd.compareTo(BigDecimal.ZERO) == 0  && todayBd.compareTo(BigDecimal.ZERO) != 0) {
                    zz = "100%";
                }
            }

            mapZj.put("bfb", zz);
            mapZj.put("zf", zt);
            map.put(s, mapZj);
        }


        return AjaxResult.success(map);
    }

    /**
     * 查询考勤异常数据信息
     * 包括所有异常的数量
     * 本月打卡统计
     */
    @PreAuthorize("@ss.hasPermi('kaoqin:statistics:monthCount')")
    @GetMapping("/month/count")
    public AjaxResult monthCount(KaoqinRecord kaoqinRecord) {
        if (StringUtils.isEmpty(kaoqinRecord.getKaMonth())) {
            kaoqinRecord.setKaYear(DateUtils.getYear());
            kaoqinRecord.setKaMonth(DateUtils.justMonth());
        }
        // 判断角色
        SysUser user = SecurityUtils.getLoginUser().getUser();
        if (!"admin".equals(user.getUserName())){
            List<SysRole> roles = user.getRoles();
            Boolean bl = false;
            for (SysRole role : roles) {
                if("conservator".equals(role.getRoleKey())) {
                    bl = true;
                    break;
                }
            }
            if (bl) {
                kaoqinRecord.setDeptId(user.getDeptId());
            }else{
                kaoqinRecord.setUserId(user.getUserId());
            }
        }

        Map<String, Object> map = new HashMap();
        //查询当天考勤数据
        Map<String, Long> todayMap = day(kaoqinRecord);
        //查询昨天考勤数据
        //获取上个月
        kaoqinRecord.setKaMonth(String.valueOf(Integer.parseInt(kaoqinRecord.getKaMonth()) - 1));
        if ("01".equals(kaoqinRecord.getKaMonth())) {
            kaoqinRecord.setKaYear(String.valueOf(Integer.parseInt(kaoqinRecord.getKaYear()) - 1));
            kaoqinRecord.setKaMonth("12");
        }
        Map<String, Long> yesterdayMap = day(kaoqinRecord);
        for (String s : todayMap.keySet()) {
            Map<String, Object> mapZj = new HashMap();
            String zz = "0%";
            //1:正，2负 3:平
            String zt = "3";
            mapZj.put("num", todayMap.get(s));

            BigDecimal todayBd = new BigDecimal(todayMap.get(s));
            BigDecimal yesterdayBd = new BigDecimal(yesterdayMap.get(s));
            BigDecimal fz = todayBd.subtract(yesterdayBd);
            if (fz.compareTo(BigDecimal.ZERO) != 0 && yesterdayBd.compareTo(BigDecimal.ZERO) != 0) {
                BigDecimal percentage = BigDecimal.ZERO;
                //昨天数据>0
                if (yesterdayBd.compareTo(BigDecimal.ZERO) > 0) {
                    percentage = fz.multiply(new BigDecimal("100"))
                            .divide(yesterdayBd, 3, RoundingMode.HALF_UP) // 先计算百分比并保留三位小数以处理可能的精度问题
                            .setScale(1, RoundingMode.HALF_UP);     // 再设置为一位小数
                }
                zz = percentage + "%";
                zt = "1";
                if (percentage.compareTo(BigDecimal.ZERO) < 0) {
                    zt = "2";
                    zz = (percentage.multiply(new BigDecimal("-1"))) + "%";
                    ;
                }
            } else {
                if (yesterdayBd.compareTo(BigDecimal.ZERO) == 0 && todayBd.compareTo(BigDecimal.ZERO) != 0) {
                    zz = "100%";
                }
            }
            mapZj.put("bfb", zz);
            mapZj.put("zf", zt);
            map.put(s, mapZj);
        }


        return AjaxResult.success(map);
    }


    /**
     * 查询考勤异常数据信息
     * 包括所有异常的数量
     * 月打卡统计
     */
    @PreAuthorize("@ss.hasPermi('kaoqin:statistics:monthyAbnormal')")
    @GetMapping("/month/abnormal")
    public AjaxResult monthAbnormal(KaoqinRecord kaoqinRecord) {
        if (StringUtils.isEmpty(kaoqinRecord.getKaMonth())) {
            kaoqinRecord.setKaYear(DateUtils.getYear());
            kaoqinRecord.setKaMonth(DateUtils.justMonth());
        }
        Map<String, Object> mapTj = new HashMap();
        Map<String, Long> mapCount = new HashMap();
        List<KaoqinRecord> kaoQinRecords = kaoqinRecordMapper.selectKaoqinRecordList(kaoqinRecord);
        //外勤打卡次数
        Long wq = 0L;
        //迟到打卡次数
        Long cd = 0L;
        //早退打卡次数
        Long zt = 0L;
        //缺卡打卡次数
        Long qk = 0L;
        //记录该月有多少次异常总数
        Long count = 0L;
        SysDictData dictData = new SysDictData();
        dictData.setDictType("kaoqin_abnormal");
        List<SysDictData> sysDictData = dictDataService.selectDictDataList(dictData);
        Map<String, Long> map = new HashMap();
        for (SysDictData sysDictDatum : sysDictData) {
            //获取异常的值
            String dictValue = sysDictDatum.getDictValue();
            if (!"1".equals(dictValue)) {
                Long aLong = 0L;
                map.put("num" + dictValue, aLong);
            }
        }
        for (KaoqinRecord kaoQinRecord : kaoQinRecords) {
            String kaTypeAmIn = kaoQinRecord.getKaTypeAmIn();
            String kaTypeAmOut = kaoQinRecord.getKaTypeAmOut();
            String kaTypePmIn = kaoQinRecord.getKaTypePmIn();
            String kaTypePmOut = kaoQinRecord.getKaTypePmOut();
            if (!"1".equals(kaTypeAmIn) && StringUtils.isNotBlank(kaTypeAmIn)) {
                Long aLong = map.get("num" + kaTypeAmIn);
                map.put("num" + kaTypeAmIn, aLong + 1);
                count = count + 1;
            }
            if (!"1".equals(kaTypeAmOut) && StringUtils.isNotBlank(kaTypeAmOut)) {
                Long aLong = map.get("num" + kaTypeAmOut);
                map.put("num" + kaTypeAmOut, aLong + 1);
                count = count + 1;
            }
            if (!"1".equals(kaTypePmIn) && StringUtils.isNotBlank(kaTypePmIn)) {
                Long aLong = map.get("num" + kaTypePmIn);
                map.put("num" + kaTypePmIn, aLong + 1);
                count = count + 1;
            }
            if (!"1".equals(kaTypePmOut) && StringUtils.isNotBlank(kaTypePmOut)) {
                Long aLong = map.get("num" + kaTypePmOut);
                map.put("num" + kaTypePmOut, aLong + 1);
                count = count + 1;
            }
        }
        wq = map.get("num3");
        cd = map.get("num2");
        zt = map.get("num4");
        qk = map.get("num5");

        mapCount.put("wq", wq);
        mapCount.put("cd", cd);
        mapCount.put("zt", zt);
        mapCount.put("qk", qk);
        for (String s : mapCount.keySet()) {
            Map<String, Object> mapZj = new HashMap();
            mapZj.put("num", mapCount.get(s));
            String zz = "0%";
            BigDecimal countBd = new BigDecimal(count);
            BigDecimal num = new BigDecimal(mapCount.get(s));
            if (countBd.compareTo(BigDecimal.ZERO) != 0 ) {
                BigDecimal percentage = num.multiply(new BigDecimal("100"))
                        .divide(countBd, 3, RoundingMode.HALF_UP) // 先计算百分比并保留三位小数以处理可能的精度问题
                        .setScale(1, RoundingMode.HALF_UP);     // 再设置为一位小数
                zz = percentage + "%";
            }
            mapZj.put("bfb", zz);
            mapTj.put(s, mapZj);
        }
        return AjaxResult.success(mapTj);
    }


    public Map<String, Long> day(KaoqinRecord kaoqinRecord) {

        Map<String, Long> map = new HashMap();
        //传入日期设置查询异常的考勤
        //kaoqinRecord.setKaStatus("2");
        //查找最新的考勤规则
        KaoqinConfig kaoqinConfigDept = kaoqinConfigService.selectKaoqinConfigBynew();
        List<KaoqinRecord> kaoQinRecords = kaoqinRecordMapper.selectKaoqinRecordList(kaoqinRecord);
        //打卡总数
        Long zcs = 0L;
        //正常打卡次数
        Long zc = 0L;
        //外勤打卡次数
        Long wq = 0L;
        //迟到打卡次数
        Long cd = 0L;
        //早退打卡次数
        Long zt = 0L;
        //缺卡打卡次数
        Long qk = 0L;
        //补卡打卡次数
        Long bk = 0L;
        //记录该月打卡总人数
        Long count = Long.valueOf(kaoQinRecords.size());
        SysDictData dictData = new SysDictData();
        dictData.setDictType("kaoqin_abnormal");
        List<SysDictData> sysDictData = dictDataService.selectDictDataList(dictData);
        Map<String, Long> todayMap = new HashMap();
        for (SysDictData sysDictDatum : sysDictData) {
            //获取异常的值
            String dictValue = sysDictDatum.getDictValue();
            Long aLong = 0L;
            todayMap.put(dictValue, aLong);

        }
        for (KaoqinRecord kaoQinRecord : kaoQinRecords) {
            String kaTypeAmIn = kaoQinRecord.getKaTypeAmIn();
            String kaTypeAmOut = kaoQinRecord.getKaTypeAmOut();
            String kaTypePmIn = kaoQinRecord.getKaTypePmIn();
            String kaTypePmOut = kaoQinRecord.getKaTypePmOut();
            if (StringUtils.isNotBlank(kaTypeAmIn) && !SIX.equals(kaTypeAmIn) && !SEVEN.equals(kaTypeAmIn) && !EIGHT.equals(kaTypeAmOut)) {
                zcs = zcs + 1;
                Long aLong = todayMap.get(kaTypeAmIn);
                todayMap.put(kaTypeAmIn, aLong + 1);
            }
            //如果只配置了两次打卡，中间两次打卡不计入统计
            if ("4".equals(kaoqinConfigDept.getKaNum())) {
                if (StringUtils.isNotBlank(kaTypeAmOut) && !SIX.equals(kaTypeAmOut) && !SEVEN.equals(kaTypeAmOut) && !EIGHT.equals(kaTypeAmOut)) {
                    zcs = zcs + 1;
                    Long aLong = todayMap.get(kaTypeAmOut);
                    todayMap.put(kaTypeAmOut, aLong + 1);
                }
                if (StringUtils.isNotBlank(kaTypePmIn) && !SIX.equals(kaTypePmIn) && !SEVEN.equals(kaTypePmIn) && !EIGHT.equals(kaTypePmIn)) {
                    zcs = zcs + 1;
                    Long aLong = todayMap.get(kaTypePmIn);
                    todayMap.put(kaTypePmIn, aLong + 1);
                }
            }
            if (StringUtils.isNotBlank(kaTypePmOut) && !SIX.equals(kaTypePmOut) && !SEVEN.equals(kaTypePmOut) && !EIGHT.equals(kaTypePmOut)) {
                zcs = zcs + 1;
                Long aLong = todayMap.get(kaTypePmOut);
                todayMap.put(kaTypePmOut, aLong + 1);
            }
        }
        zc = todayMap.get("1");
        wq = todayMap.get("3");
        cd = todayMap.get("2");
        zt = todayMap.get("4");
        qk = todayMap.get("5");
        bk = todayMap.get("6");

        map.put("zs", count);
        map.put("zcs", zcs);
        map.put("zc", zc);
        map.put("wq", wq);
        map.put("cd", cd);
        map.put("zt", zt);
        map.put("qk", qk);
        map.put("bk", bk);
        return map;
    }

    public String dictToString(String value) {
        String str = "";
        if ("1".equals(value)) {
            str = "ydk";
        } else if ("2".equals(value)) {
            str = "cd";
        } else if ("3".equals(value)) {
            str = "wq";
        } else if ("4".equals(value)) {
            str = "zt";
        } else if ("5".equals(value)) {
            str = "qk";
        } else if ("6".equals(value)) {
            str = "bk";
        } else if ("7".equals(value)) {
            str = "qj";
        } else if ("8".equals(value)) {
            str = "cc";
        }
        return str;
    }

    /**
     * 本周补卡统计
     */
    @PreAuthorize("@ss.hasPermi('kaoqin:statistics:weekBk')")
    @GetMapping("/week/bk")
    public AjaxResult weekBk() {


        Map<String, Object> map = new HashMap();
        //周一到周六的日期
        List<String> weekDates = DateUtils.getWeekDatesFromMondayToSaturday();
        List<String> weekName = Arrays.asList(WEEK);
        //查询本周的补卡信息
        // 判断角色
        CardReplacementRecord cardReplacementRecord = new CardReplacementRecord();
        SysUser user = SecurityUtils.getLoginUser().getUser();
        if (!"admin".equals(user.getUserName())){
            cardReplacementRecord.setDeptId(user.getDeptId());
        }
        List<CardReplacementRecord> cardReplacementRecordList = cardReplacementRecordMapper.selectCardReplacementRecordListWeek(cardReplacementRecord);
        Map<String, List<CardReplacementRecord>> cardMap = cardReplacementRecordList.stream().collect(Collectors.groupingBy(CardReplacementRecord::getApplicationDate));
        List<Integer> nums = new ArrayList<>();
        for (int i = 0; i < weekDates.size(); i++) {
            int num = 0;
            if (cardMap.get(weekDates.get(i)) != null && !cardMap.get(weekDates.get(i)).isEmpty()) {
                num = cardMap.get(weekDates.get(i)).size();
            }
            nums.add(num);
        }
        map.put("x", weekName);
        map.put("y", nums);
        return AjaxResult.success(map);
    }

    /**
     * 本周请假统计
     */
    @PreAuthorize("@ss.hasPermi('kaoqin:statistics:weekQj')")
    @GetMapping("/week/qj")
    public AjaxResult weekQj() {
        Map<String, Object> map = new HashMap();
        //周一到周六的日期
        List<String> weekDates = DateUtils.getWeekDatesFromMondayToSaturday();
        List<String> weekName = Arrays.asList(WEEK);
        //查询本周的请假信息
        // 判断角色
        RecordLeave recordLeave = new RecordLeave();
        SysUser user = SecurityUtils.getLoginUser().getUser();
        if (!"admin".equals(user.getUserName())){
            recordLeave.setDeptId(user.getDeptId());
        }
        List<RecordLeave> recordLeaves = recordLeaveMapper.selectRecordLeaveListWeek(recordLeave);

        List<Integer> nums = new ArrayList<>();
        for (int i = 0; i < weekDates.size(); i++) {
            int num = 0;
            if (recordLeaves != null && !recordLeaves.isEmpty()) {
                for (RecordLeave recordLeaf : recordLeaves) {
                    if (DateUtils.isDateBetween(DateUtils.parseDate(weekDates.get(i)), recordLeaf.getStartTime(), recordLeaf.getEndTime())) {
                        num++;
                    }
                }
            }

            nums.add(num);
        }
        map.put("x", weekName);
        map.put("y", nums);
        return AjaxResult.success(map);
    }


    /**
     * 导出人员打卡情况报表
     */
    @PreAuthorize("@ss.hasPermi('kaoqin:statistics:export')")
    @Log(title = "导出人员打卡情况报表", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, KaoqinRecord kaoqinRecord) {
        List<Map<String, Object>> maps = kqRecord(kaoqinRecord);
        List<BaobiaoVo> baobiaoVoList = new ArrayList<>();
        try {
            for (Map<String, Object> map : maps) {

                BaobiaoVo baobiaoVo = MapToObjectUtils.populate(map, BaobiaoVo.class);
                baobiaoVoList.add(baobiaoVo);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        ExcelUtil<BaobiaoVo> util = new ExcelUtil<BaobiaoVo>(BaobiaoVo.class);
        util.exportExcel(response,baobiaoVoList, "考勤统计数据");

    }

    /**
     * 导出人员打卡情况报表 返回文件地址
     */
    @PreAuthorize("@ss.hasPermi('kaoqin:statistics:urlExport')")
    @Log(title = "导出人员打卡情况报表", businessType = BusinessType.EXPORT)
    @PostMapping("/url/export")
    public AjaxResult urlExport(HttpServletResponse response, KaoqinRecord kaoqinRecord) {
        List<Map<String, Object>> maps = kqRecord(kaoqinRecord);
        List<BaobiaoVo> baobiaoVoList = new ArrayList<>();
        try {
            for (Map<String, Object> map : maps) {

                BaobiaoVo baobiaoVo = MapToObjectUtils.populate(map, BaobiaoVo.class);
                baobiaoVoList.add(baobiaoVo);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        ExcelUtil<BaobiaoVo> util = new ExcelUtil<BaobiaoVo>(BaobiaoVo.class);

        return util.exportExcel(baobiaoVoList, "考勤统计数据");

    }
}
