package com.xunmei.core.resumption.task;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.xunmei.common.core.constant.SecurityConstants;
import com.xunmei.common.core.domain.R;
import com.xunmei.common.core.utils.Ymd;
import com.xunmei.common.core.utils.snowId.DateHelper;
import com.xunmei.core.resumption.domain.AppPlan;
import com.xunmei.core.resumption.domain.SysResumption;
import com.xunmei.core.resumption.service.AppPlanService;
import com.xunmei.core.resumption.service.IAppRulePointService;
import com.xunmei.core.resumption.service.ISysResumptionService;
import com.xunmei.common.core.utils.KeyValue;
import com.xunmei.common.core.utils.ResumptionStatus;
import com.xunmei.common.core.utils.ResumptionType;
import com.xunmei.core.resumption.vo.AppRulePointTaskVo;
import com.xunmei.core.resumption.vo.WorkChangeResumptionVo;
import com.xunmei.system.api.RemoteConfigService;
import com.xunmei.system.api.RemoteOrgService;
import com.xunmei.system.api.RemoteWorkTimeService;
import com.xunmei.system.api.domain.SysConfig;
import com.xunmei.system.api.domain.SysOrg;
import com.xunmei.system.api.domain.SysWorkTime;
import com.xunmei.system.api.enums.OrgType;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;


/**
 * @author oy
 */
@Slf4j
@Component
public class ResumptionTaskBusiness {

    @Autowired
    private ISysResumptionService resumptionService;
    @Autowired
    private RemoteWorkTimeService workTimeService;
    @Autowired
    private RemoteOrgService orgService;
    @Autowired
    private AppPlanService appPlanService;
    @Autowired
    private IAppRulePointService appRulePointService;
    @Autowired
    private RemoteConfigService systemParameService;



//    @Resource
//    DelayTaskService delayTaskService;
    /**
     * 添加每小时作息
     *
     * @param dateTime
     */
    /**
     * 食堂履职执行时刻
     */
    List<Integer> canteenPlanExec = Arrays.asList(4, 5, 6);

    @Async
    public void syncHour(final DateTime dateTime, int plancycle) {//plancycle==6
        //获取履职计划
        List<AppPlan> appPlanList = appPlanService.list((new QueryWrapper<AppPlan>()).lambda()
                .eq(AppPlan::getPlanStatus, 0)
                .eq(AppPlan::getPlanCycle, plancycle)
                .eq(AppPlan::getPlanType, 0)
                .notIn(AppPlan::getPlanExec, canteenPlanExec));//findExecOrgByPlan(6);
        for (AppPlan appPlan : appPlanList) {
            //获取履职计划中对应的检查要点
            List<AppRulePointTaskVo> pointList = appRulePointService.findPointByPlan(appPlan.getId());
            if (pointList.size() <= 0) {//没有检查项不生成履职任务
//                RESUMPTIONLOG.error("error:该计划ID：{}没有检查项", appPlan.getId());
                continue;
            }
            //根据计划获取履职任务执行机构
            List<Long> orgIds = getPlanOrgIds(appPlan);
            if (orgIds == null || orgIds.size() <= 0) {//没有检查项不生成履职任务
//                RESUMPTIONLOG.error("error:该计划ID：{}没有执行机构", appPlan.getId());
                continue;
            }
            //获取履职角色
            List<Long> roleIds = appPlanService.findRoleByPlan(appPlan.getId());
            if (roleIds.size() <= 0) {//没有检查项不生成履职任务
//                RESUMPTIONLOG.error("error:该计划ID：{}没有履职角色", appPlan.getId());
                continue;
            }
            //获取所有要点中的区域id
            Set<Long> nfcBindIdList = new HashSet<>();
            for (AppRulePointTaskVo p : pointList) {
                if (p.getNfcBindId() != null && p.getPointScan() == 1) {
                    nfcBindIdList.add(p.getNfcBindId());
                }
            }

            //根据区域获取区域内绑定的nfc
          /*  NFCBindJobDto jobDto = new NFCBindJobDto();
            jobDto.setAreaIds(new ArrayList(areaList));
            List<NFCBindPageVo> nfcList =  nfcBindService.all(jobDto,NFCBindPageVo::to);*/
            //获取有 作息的机构id
            R<List<Long>> listR = workTimeService.findOrgIdsByYmd(dateTime.toString().substring(0, 10), SecurityConstants.INNER);
            List<Long> orgIdsNew=new ArrayList<>();
            if (listR.getCode()==200) {
                orgIdsNew = listR.getData();
            }
            List<Long> finalOrgIdsNew = orgIdsNew;
            List<Long> orgIdList = orgIds.stream().filter(r -> finalOrgIdsNew.contains(r)).collect(Collectors.toList());
            //List<Long> orgIdsNew =  StreamHelper.filter(orgIds,(v)->workTimeList.contains(v));
            for (final Long orgId : orgIdList) {
                //获取当天的作息
                /*NFCBindJobDto jobDto = new NFCBindJobDto();
                jobDto.setNfcBindIdList(new ArrayList(nfcBindIdList));
                jobDto.setOrgId(orgId);
                List<NFCBindPageVo> nfcList =  nfcBindService.all(jobDto,NFCBindPageVo::to);*/
                Ymd ymd=toYmd(dateTime,"DAY");
                ymd.setOrgId(orgId);
                ymd.setEnable(true);
                SysWorkTime workTime =workTimeService.findWorkTimeByYmd(ymd).getData();
                if (workTime != null) {
                    List<String[]> workTimes = new ArrayList<>();
                    if (appPlan.getNotResumptionOnRest() != null && appPlan.getNotResumptionOnRest() == 1 &&
                            StringUtils.isNotEmpty(workTime.getNoonbreakStart()) && StringUtils.isNotEmpty(workTime.getNoonbreakEnd())) {
                        workTimes.add(new String[]{workTime.getOpenTime(), workTime.getNoonbreakStart()});
                        workTimes.add(new String[]{workTime.getNoonbreakEnd(), workTime.getCloseTime()});
                    } else {
                        workTimes.add(new String[]{workTime.getOpenTime(), workTime.getCloseTime()});
                    }
                    for (int ti = 0; ti < workTimes.size(); ti++) {
                        String[] time = workTimes.get(ti);
                        String openStr = time[0];
                        String closeStr = time[1];
                        String[] openArr = openStr.split(":");
                        String[] closeArr = closeStr.split(":");
                        /*如果营业前是00：00-09：00，营业后是17：00-24：00，
                        当前每小时履职任务是10：00-16：00，少了09：00-10：00和16：00-17：00的任务，
                        建议这2个时间段也生成履职任务*/
                        //如果有午休，要考虑分段第一段往前移1个小时第二段不移
                        int openHour = 0;
                        if (ti == 0) {
                            openHour = Integer.parseInt(openArr[0]) - 1;
                        } else {
                            openHour = Integer.parseInt(openArr[0]);
                        }
                        int openMinute = Integer.parseInt(openArr[1]);
                        int closeHour = Integer.parseInt(closeArr[0]);
                        //int closeHour = Integer.parseInt(closeArr[0])+1;
                        int closeMinute = Integer.parseInt(closeArr[1]);
                        if (openMinute < closeMinute) {
                            closeHour += 1;
                        }
                        int len = closeHour - openHour;
                        if (len > 1) {
                            int i = ti == 0 ? 1 : 0;
                            for (; i < len; i++) {//为每个作息点生成履职任务
                                dateTime.setField(DateField.HOUR_OF_DAY, openHour + i);
                                dateTime.setField(DateField.MINUTE, openMinute);
                                //this.resumptionService.build(orgId, ResumptionType.HOUR, dateTime, true);
                                //每个作息点的开始时间和结束时间,不能直接操作dateTime，后面的操作会覆盖前面的操作
                                DateTime time1 = new DateTime(dateTime);
                                time1.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                                DateTime time2 = new DateTime(dateTime);
                                time2.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                                DateTime planstartTime = time1.setField(DateField.HOUR_OF_DAY, openHour + i).setField(DateField.MINUTE, openMinute).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
                                DateTime planendTime = time2.setField(DateField.HOUR_OF_DAY, openHour + i + 1).setField(DateField.MINUTE, openMinute).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
                                //for(Long roleId:roleIds){
                                resumptionService.newbuild(orgId, ResumptionType.HOUR, dateTime, true, appPlan, null, pointList, roleIds, planstartTime, planendTime);
                                // }

                            }
                        }
                    }


                } else {
//                    RESUMPTIONLOG.error("{} 没有作息", ResumptionType.DAY.toYmd(dateTime));
                }
            }
        }

    }


    /**
     * 添加日作息
     *
     * @param dateTime
     */
    @Async
    public void syncDay(final DateTime dateTime, int plancycle) {//plancycle==0
//        R<SysConfig> officeBuilding_open_allhours = systemParameService.findFirstByCode("officeBuilding_open_allhours", SecurityConstants.INNER);
//        SysConfig officeAllHourParam = officeBuilding_open_allhours.getData();
        //获取履职计划
        List<AppPlan> AppPlanList = appPlanService.list((new QueryWrapper<AppPlan>()).lambda()
                .eq(AppPlan::getPlanStatus, 1)
                .eq(AppPlan::getPlanCycle, plancycle));
//                .eq(AppPlan::getPlanType, 1)
//                .notIn(AppPlan::getPlanExec, canteenPlanExec));
        for (AppPlan appPlan : AppPlanList) {
            //获取履职计划中对应的检查要点
            List<AppRulePointTaskVo> pointList = appRulePointService.findPointByPlan(appPlan.getId());
            if (pointList.size() <= 0) {//没有检查项不生成履职任务
//                RESUMPTIONLOG.error("error:该计划ID：{}没有检查项", appPlan.getId());
                continue;
            }

            List<Long> orgIds = getPlanOrgIds(appPlan);
            if (orgIds == null || orgIds.size() <= 0) {//没有检查项不生成履职任务
//                RESUMPTIONLOG.error("error:该计划ID：{}没有执行机构", appPlan.getId());
                continue;
            }
            //获取履职角色
            List<Long> roleIds = appPlanService.findRoleByPlan(appPlan.getId());
            if (roleIds.size() <= 0) {//没有检查项不生成履职任务
//                RESUMPTIONLOG.error("error:该计划ID：{}没有履职角色", appPlan.getId());
                continue;
            }
            //获取所有要点中的区域id
            Set<Long> nfcBindIdList = new HashSet<>();
            for (AppRulePointTaskVo p : pointList) {
                if (p.getNfcBindId() != null && p.getPointScan() == 1) {
                    nfcBindIdList.add(p.getNfcBindId());
                }
            }
            //根据区域获取区域内绑定的nfc
            /*NFCBindJobDto jobDto = new NFCBindJobDto();
            jobDto.setAreaIds(new ArrayList(areaList));
            List<NFCBindPageVo> nfcList =  nfcBindService.all(jobDto,NFCBindPageVo::to);*/
//            boolean officeAllHour = officeAllHourParam != null && "1".equals(officeAllHourParam.getValue());
            List<Long> orgIdList;


            orgIdList = orgIds;

            //不需要类型判断直接用上面的机构ids


//            if (ObjectUtil.equal(appPlan.getExecType(), 1)) {
//                if (officeAllHour) {
//                    List<SysOrg> orgs = orgService.listByIds(orgIds, SecurityConstants.INNER).getData();
//                    orgIdList = orgs.stream().filter(o -> ObjectUtil.equal(o.getType(), OrgType.BGDL)).map(o -> o.getId()).collect(Collectors.toList());
//                    List<Long> tempOrgIds = orgs.stream().filter(o -> ObjectUtil.notEqual(o.getType(), OrgType.BGDL)).map(o -> o.getId()).collect(Collectors.toList());
//                    List<Long> orgIdsNew = this.workTimeService.findOrgIdsByYmd(dateTime.toString().substring(0, 10),SecurityConstants.INNER).getData();
//                    orgIdList.addAll(tempOrgIds.stream().filter(r -> orgIdsNew.contains(r)).collect(Collectors.toList()));
//                } else {
//                    List<Long> orgIdsNew = this.workTimeService.findOrgIdsByYmd(dateTime.toString().substring(0, 10),SecurityConstants.INNER).getData();
//                    orgIdList = orgIds.stream().filter(r -> orgIdsNew.contains(r)).collect(Collectors.toList());
//                }
//            } else {
//                if (officeAllHour && ObjectUtil.equal(appPlan.getExecOrgType(), OrgType.BGDL.ordinal())) {
//                    orgIdList = orgIds;
//                } else {
//                    List<Long> orgIdsNew = this.workTimeService.findOrgIdsByYmd(dateTime.toString().substring(0, 10),SecurityConstants.INNER).getData();
//                    orgIdList = orgIds.stream().filter(r -> orgIdsNew.contains(r)).collect(Collectors.toList());
//                }
//            }


            for (Long orgId : orgIdList) {
               /* NFCBindJobDto jobDto = new NFCBindJobDto();
                jobDto.setNfcBindIdList(new ArrayList(nfcBindIdList));
                jobDto.setOrgId(orgId);
                List<NFCBindPageVo> nfcList =  nfcBindService.all(jobDto,NFCBindPageVo::to);*/
                SysWorkTime workTime;
//                if (officeAllHour) {
//                    workTime  = new SysWorkTime();
//                    workTime.setOpenTime("00:00");
//                    workTime.setCloseTime("23:59");
//                } else {
                    Ymd ymd=toYmd(dateTime,"DAY");
                    ymd.setOrgId(orgId);
                    ymd.setEnable(true);
                    workTime = this.workTimeService.findWorkTimeByYmd(ymd).getData();
//                }

                DateTime planstartTime = null;
                DateTime planendTime = null;

                if (workTime != null) {

                    String opentime = workTime.getOpenTime();//营业时间
                    String closetime = workTime.getCloseTime();//营业终了
                    if (appPlan.getPlanExec() == 1) {//全天 上班时间-下班时间 00:00:00-23:59:59
                        DateTime time1 = new DateTime(dateTime);
                        time1.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                        DateTime time2 = new DateTime(dateTime);
                        time2.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                        planstartTime = time1.setField(DateField.HOUR_OF_DAY, 0).setField(DateField.MINUTE, 0).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
                        planendTime = DateUtil.endOfDay(time2).setField(DateField.MILLISECOND, 0);//.offset(DateField.MILLISECOND, -999);
                        //planstartTime = time1.setField(DateField.HOUR_OF_DAY,Integer.parseInt(worktime.split(":")[0])).setField(DateField.MINUTE,Integer.parseInt(worktime.split(":")[1])).setField(DateField.SECOND,0);
                        //planendTime = time2.setField(DateField.HOUR_OF_DAY,Integer.parseInt(workofftime.split(":")[0])).setField(DateField.MINUTE,Integer.parseInt(workofftime.split(":")[1])).setField(DateField.SECOND,0);
                    } else if (appPlan.getPlanExec() == 2) {//营业前 上班时间-营业时间
                        DateTime time1 = new DateTime(dateTime);
                        time1.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                        DateTime time2 = new DateTime(dateTime);
                        time2.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                        planstartTime = time1.setField(DateField.HOUR_OF_DAY, 0).setField(DateField.MINUTE, 0).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
                        planendTime = time2.setField(DateField.HOUR_OF_DAY, Integer.parseInt(opentime.split(":")[0])).setField(DateField.MINUTE, Integer.parseInt(opentime.split(":")[1])).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
                    } else if (appPlan.getPlanExec() == 3) {//营业期间 营业时间-营业终了
                        DateTime time1 = new DateTime(dateTime);
                        time1.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                        DateTime time2 = new DateTime(dateTime);
                        time2.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                        planstartTime = time1.setField(DateField.HOUR_OF_DAY, Integer.parseInt(opentime.split(":")[0])).setField(DateField.MINUTE, Integer.parseInt(opentime.split(":")[1])).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
                        planendTime = time2.setField(DateField.HOUR_OF_DAY, Integer.parseInt(closetime.split(":")[0])).setField(DateField.MINUTE, Integer.parseInt(closetime.split(":")[1])).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
                    } else if (appPlan.getPlanExec() == 4) {//营业终 营业终了-23.59.59
                        DateTime time1 = new DateTime(dateTime);
                        time1.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                        DateTime time2 = new DateTime(dateTime);
                        time2.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                        planstartTime = time1.setField(DateField.HOUR_OF_DAY, Integer.parseInt(closetime.split(":")[0])).setField(DateField.MINUTE, Integer.parseInt(closetime.split(":")[1])).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
                        planendTime = DateUtil.endOfDay(time2).setField(DateField.MILLISECOND, 0);//.offset(DateField.MILLISECOND, -999);
                        // planendTime = time2.setField(DateField.HOUR_OF_DAY,Integer.parseInt(workofftime.split(":")[0])).setField(DateField.MINUTE,Integer.parseInt(workofftime.split(":")[1])).setField(DateField.SECOND,0);
                    }

                    //for(Long roleId:roleIds){
                    resumptionService.newbuild(orgId, ResumptionType.DAY, dateTime, true, appPlan, null, pointList, roleIds, planstartTime, planendTime);
                    // }
                } else {
//                    RESUMPTIONLOG.error("{} 没有作息", ResumptionType.DAY.toYmd(dateTime));
                }
            }
        }
    }

    /**
     * 添加食堂履职
     */


    /**
     * 添加周履职, 只要这周有一天营业就得加
     *
     * @param dateTime
     */
    @Async
    public void syncWeek(DateTime dateTime, int plancycle) {//plancycle==1
        List<AppPlan> AppPlanList = appPlanService.list((new QueryWrapper<AppPlan>()).lambda()
                .eq(AppPlan::getPlanStatus, 1)
                .eq(AppPlan::getPlanCycle, plancycle));
//                        .eq(AppPlan::getPlanType, 0)
//                .notIn(AppPlan::getPlanExec, canteenPlanExec));
        KeyValue<Integer, Integer> yearWeek = new KeyValue<>(DateUtil.year(dateTime), DateUtil.weekOfYear(dateTime));
        DateTime time1 = new DateTime(dateTime);
        time1.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        DateTime time2 = new DateTime(DateHelper.getLastDayOfWeek(yearWeek.getKey(), yearWeek.getValue()));
        if (time2.isBefore(time1)) {//说明跨年了
            time2 = new DateTime(DateHelper.getLastDayOfWeek(yearWeek.getKey() + 1, yearWeek.getValue()));
        }
        time2.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        DateTime planstartTime = time1.setField(DateField.HOUR_OF_DAY, 0).setField(DateField.MINUTE, 0).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
        ;
        DateTime planendTime = DateUtil.endOfDay(time2).setField(DateField.MILLISECOND, 0);//.offset(DateField.MILLISECOND, -999);
        for (AppPlan appPlan : AppPlanList) {
            //获取履职计划中对应的检查要点
            List<AppRulePointTaskVo> pointList = appRulePointService.findPointByPlan(appPlan.getId());
            if (pointList.size() <= 0) {//没有检查项不生成履职任务
//                RESUMPTIONLOG.error("error:该计划ID：{}没有检查项", appPlan.getId());
                continue;
            }
            //根据计划获取履职任务执行机构
            List<Long> orgIds = getPlanOrgIds(appPlan);
            if (orgIds == null || orgIds.size() <= 0) {//没有检查项不生成履职任务
//                RESUMPTIONLOG.error("error:该计划ID：{}没有执行机构", appPlan.getId());
                continue;
            }
            //获取履职角色
            List<Long> roleIds = appPlanService.findRoleByPlan(appPlan.getId());
            if (roleIds.size() <= 0) {//没有检查项不生成履职任务
//                RESUMPTIONLOG.error("error:该计划ID：{}没有履职角色", appPlan.getId());
                continue;
            }
            //获取所有要点中的采集点
            Set<Long> nfcBindIdList = new HashSet<>();
            for (AppRulePointTaskVo p : pointList) {
                if (p.getNfcBindId() != null && p.getPointScan() == 1) {
                    nfcBindIdList.add(p.getNfcBindId());
                }
            }
            for (Long orgId : orgIds) {
                //根据区域获取区域内绑定的nfc
                /*NFCBindJobDto jobDto = new NFCBindJobDto();
                jobDto.setNfcBindIdList(new ArrayList(nfcBindIdList));
                jobDto.setOrgId(orgId);
                List<NFCBindPageVo> nfcList =  nfcBindService.all(jobDto,NFCBindPageVo::to);*/
                // 判断这周是否有作息
                boolean isExist = workTimeService.existByYmd( Ymd.builder().year(yearWeek.getKey()).week(yearWeek.getValue()).orgId(orgId).isEnable(true).build()).getData();
//                final boolean isExist = false;
                // 应该用周的第一天, 不然页面查是查询不到的
                //dateTime即为本周第一天
                //final Date dateTime = DateHelper.getFirstDayOfWeek(yearWeek.getKey(), yearWeek.getValue());
                // for(Long roleId:roleIds){
                this.resumptionService.newbuild(orgId, ResumptionType.WEEK, dateTime, isExist, appPlan, null, pointList, roleIds, planstartTime, planendTime);
                //}


            }
        }


    }

    /**
     * 添加月履职
     *
     * @param dateTime
     */
    @Async
    public void syncMonth(DateTime dateTime, int plancycle) {//plancycle==2
        List<AppPlan> AppPlanList = appPlanService.list((new QueryWrapper<AppPlan>()).lambda()
                .eq(AppPlan::getPlanStatus, 1)
                .eq(AppPlan::getPlanCycle, plancycle));
//                .eq(AppPlan::getPlanType, 0)
//                .notIn(AppPlan::getPlanExec, canteenPlanExec));
        KeyValue<Integer, Integer> yearMonth = new KeyValue<>(DateUtil.year(dateTime), DateUtil.month(dateTime) + 1);

        DateTime time1 = new DateTime(dateTime);
        time1.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        DateTime time2 = new DateTime(DateHelper.getLastDayOfMonth(yearMonth.getKey(), yearMonth.getValue()));
        time2.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        DateTime planstartTime = time1.setField(DateField.HOUR_OF_DAY, 0).setField(DateField.MINUTE, 0).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
        DateTime planendTime = DateUtil.endOfDay(time2).setField(DateField.MILLISECOND, 0);//.offset(DateField.MILLISECOND, -999);

        for (AppPlan appPlan : AppPlanList) {
            //获取履职计划中对应的检查要点
            List<AppRulePointTaskVo> pointList = appRulePointService.findPointByPlan(appPlan.getId());
            if (pointList.size() <= 0) {//没有检查项不生成履职任务
//                RESUMPTIONLOG.error("error:该计划ID：{}没有检查项", appPlan.getId());
                continue;
            }
            //根据计划获取履职任务执行机构 2每月履职
            List<Long> orgIds = getPlanOrgIds(appPlan);
            if (orgIds == null || orgIds.size() <= 0) {//没有检查项不生成履职任务
//                RESUMPTIONLOG.error("error:该计划ID：{}没有执行机构", appPlan.getId());
                continue;
            }
            //获取履职角色
            List<Long> roleIds = appPlanService.findRoleByPlan(appPlan.getId());
            if (roleIds.size() <= 0) {//没有检查项不生成履职任务
//                RESUMPTIONLOG.error("error:该计划ID：{}没有履职角色", appPlan.getId());
                continue;
            }
            //获取所有要点中的区域id
            Set<Long> nfcBindIdList = new HashSet<>();
            for (AppRulePointTaskVo p : pointList) {
                if (p.getNfcBindId() != null && p.getPointScan() == 1) {
                    nfcBindIdList.add(p.getNfcBindId());
                }
            }
            //根据区域获取区域内绑定的nfc
       /*     NFCBindJobDto jobDto = new NFCBindJobDto();
            jobDto.setAreaIds(new ArrayList(areaList));
            List<NFCBindPageVo> nfcList =  nfcBindService.all(jobDto,NFCBindPageVo::to);*/
            for (Long orgId : orgIds) {
              /*  NFCBindJobDto jobDto = new NFCBindJobDto();
                jobDto.setNfcBindIdList(new ArrayList(nfcBindIdList));
                jobDto.setOrgId(orgId);
                List<NFCBindPageVo> nfcList =  nfcBindService.all(jobDto,NFCBindPageVo::to);*/
                // 判断这月是否有作息
//                final boolean isExist = this.workTimeService.existByYmd(orgId, Ymd.builder().year(yearMonth.getKey()).month(yearMonth.getValue()).build(), true);
                final boolean isExist = workTimeService.existByYmd( Ymd.builder().year(yearMonth.getKey()).week(yearMonth.getValue()).orgId(orgId).isEnable(true).build()).getData();

                // 应该用月的第一天, 不然页面查是查询不到的
                //dateTime即为本月第一天
                //final Date dateTime = DateHelper.getFirstDayOfMonth(yearMonth.getKey(), yearMonth.getValue());
                //for(Long roleId:roleIds){
                this.resumptionService.newbuild(orgId, ResumptionType.MONTH, dateTime, isExist, appPlan, null, pointList, roleIds, planstartTime, planendTime);
                // }

            }
        }

    }

    /**
     * 添加季履职
     *
     * @param dateTime
     */
    @Async
    public void syncQuarter(DateTime dateTime, int plancycle) {//plancycle==3
        List<AppPlan> AppPlanList = appPlanService.list((new QueryWrapper<AppPlan>()).lambda()
                .eq(AppPlan::getPlanStatus, 1)
                .eq(AppPlan::getPlanCycle, plancycle));
//                .eq(AppPlan::getPlanType, 0)
//                .notIn(AppPlan::getPlanExec, canteenPlanExec));
        KeyValue<Integer, Integer> yearQuarter = new KeyValue<>(DateUtil.year(dateTime), DateUtil.quarter(dateTime));
        DateTime time1 = new DateTime(dateTime);
        time1.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        DateTime time2 = new DateTime(DateHelper.getLastDayOfQuarter(yearQuarter.getKey(), yearQuarter.getValue()));
        time2.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        DateTime planstartTime = time1.setField(DateField.HOUR_OF_DAY, 0).setField(DateField.MINUTE, 0).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
        DateTime planendTime = DateUtil.endOfDay(time2).setField(DateField.MILLISECOND, 0);//.offset(DateField.MILLISECOND, -999);
        System.out.println(planstartTime);
        System.out.println(planendTime);
        for (AppPlan appPlan : AppPlanList) {
            //获取履职计划中对应的检查要点
            List<AppRulePointTaskVo> pointList = appRulePointService.findPointByPlan(appPlan.getId());
            if (pointList.size() <= 0) {//没有检查项不生成履职任务
//                RESUMPTIONLOG.error("error:该计划ID：{}没有检查项", appPlan.getId());
                continue;
            }
            //根据计划获取履职任务执行机构
            List<Long> orgIds = getPlanOrgIds(appPlan);
            if (orgIds == null || orgIds.size() <= 0) {//没有检查项不生成履职任务
//                RESUMPTIONLOG.error("error:该计划ID：{}没有执行机构", appPlan.getId());
                continue;
            }
            //获取履职角色
            List<Long> roleIds = appPlanService.findRoleByPlan(appPlan.getId());
            if (roleIds.size() <= 0) {//没有检查项不生成履职任务
//                RESUMPTIONLOG.error("error:该计划ID：{}没有履职角色", appPlan.getId());
                continue;
            }
            //获取所有要点中的区域id
            Set<Long> nfcBindIdList = new HashSet<>();
            for (AppRulePointTaskVo p : pointList) {
                if (p.getNfcBindId() != null && p.getPointScan() == 1) {
                    nfcBindIdList.add(p.getNfcBindId());
                }
            }
            //根据区域获取区域内绑定的nfc
          /*  NFCBindJobDto jobDto = new NFCBindJobDto();
            jobDto.setAreaIds(new ArrayList(areaList));
            List<NFCBindPageVo> nfcList =  nfcBindService.all(jobDto,NFCBindPageVo::to);*/
            for (Long orgId : orgIds) {
               /* NFCBindJobDto jobDto = new NFCBindJobDto();
                jobDto.setNfcBindIdList(new ArrayList(nfcBindIdList));
                jobDto.setOrgId(orgId);
                List<NFCBindPageVo> nfcList =  nfcBindService.all(jobDto,NFCBindPageVo::to);*/
                // 判断这季度是否有作息
                //final boolean isExist = this.workTimeService.existByYmd(orgId, Ymd.builder().year(yearQuarter.getKey()).quarter(yearQuarter.getValue()).build(), true);
                // 应该用季度的第一天, 不然页面查是查询不到的
                //dateTime即为本季度第一天
                //final Date dateTime = DateHelper.getFirstDayOfQuarter(yearQuarter.getKey(), yearQuarter.getValue());
                // for(Long roleId:roleIds){
                this.resumptionService.newbuild(orgId, ResumptionType.QUARTER, dateTime, true, appPlan, null, pointList, roleIds, planstartTime, planendTime);
                // }
            }
        }

    }

    /**
     * 添加半年履职
     *
     * @param dateTime
     */
    @Async
    public void syncHalfYear(DateTime dateTime, int plancycle) {//plancycle==4
        List<AppPlan> AppPlanList = appPlanService.list((new QueryWrapper<AppPlan>()).lambda()
                .eq(AppPlan::getPlanStatus, 1)
                .eq(AppPlan::getPlanCycle, plancycle));
//                .eq(AppPlan::getPlanType, 0)
//                .notIn(AppPlan::getPlanExec, canteenPlanExec));
        DateHelper dateHelper = new DateHelper(dateTime);
        KeyValue<Integer, Integer> yearHalfYear = new KeyValue<>(DateUtil.year(dateTime), dateHelper.getHalfyear());

        DateTime time1 = new DateTime(dateTime);
        time1.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        DateTime time2 = new DateTime(DateHelper.getLastDayOfHalfyear(yearHalfYear.getKey(), yearHalfYear.getValue()));
        time2.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        DateTime planstartTime = time1.setField(DateField.HOUR_OF_DAY, 0).setField(DateField.MINUTE, 0).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
        DateTime planendTime = DateUtil.endOfDay(time2).setField(DateField.MILLISECOND, 0);//.offset(DateField.MILLISECOND, -999);
        for (AppPlan appPlan : AppPlanList) {
            //获取履职计划中对应的检查要点
            List<AppRulePointTaskVo> pointList = appRulePointService.findPointByPlan(appPlan.getId());
            if (pointList.size() <= 0) {//没有检查项不生成履职任务
//                RESUMPTIONLOG.error("error:该计划ID：{}没有检查项", appPlan.getId());
                continue;
            }
            //根据计划获取履职任务执行机构
            List<Long> orgIds = getPlanOrgIds(appPlan);
            if (orgIds == null || orgIds.size() <= 0) {//没有检查项不生成履职任务
//                RESUMPTIONLOG.error("error:该计划ID：{}没有执行机构", appPlan.getId());
                continue;
            }
            //获取履职角色
            List<Long> roleIds = appPlanService.findRoleByPlan(appPlan.getId());
            if (roleIds.size() <= 0) {//没有检查项不生成履职任务
//                RESUMPTIONLOG.error("error:该计划ID：{}没有履职角色", appPlan.getId());
                continue;
            }
            //获取所有要点中的区域id
            Set<Long> nfcBindIdList = new HashSet<>();
            for (AppRulePointTaskVo p : pointList) {
                if (p.getNfcBindId() != null && p.getPointScan() == 1) {
                    nfcBindIdList.add(p.getNfcBindId());
                }
            }
            //根据区域获取区域内绑定的nfc
           /* NFCBindJobDto jobDto = new NFCBindJobDto();
            jobDto.setAreaIds(new ArrayList(areaList));
            List<NFCBindPageVo> nfcList =  nfcBindService.all(jobDto,NFCBindPageVo::to);*/
            for (Long orgId : orgIds) {
              /*  NFCBindJobDto jobDto = new NFCBindJobDto();
                jobDto.setNfcBindIdList(new ArrayList(nfcBindIdList));
                jobDto.setOrgId(orgId);
                List<NFCBindPageVo> nfcList =  nfcBindService.all(jobDto,NFCBindPageVo::to);*/
                //for(Long roleId:roleIds){
                this.resumptionService.newbuild(orgId, ResumptionType.HALFYEAR, dateTime, true, appPlan, null, pointList, roleIds, planstartTime, planendTime);
                // }
            }
        }

    }

    /**
     * 添加年履职
     *
     * @param dateTime
     */
    @Async
    public void syncYear(DateTime dateTime, int plancycle) {//plancycle==5
        List<AppPlan> AppPlanList = appPlanService.list((new QueryWrapper<AppPlan>()).lambda()
                .eq(AppPlan::getPlanStatus, 1)
                .eq(AppPlan::getPlanCycle, plancycle));
//                .eq(AppPlan::getPlanType, 0)
//                .notIn(AppPlan::getPlanExec, canteenPlanExec));
        DateTime time1 = new DateTime(dateTime);
        time1.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        DateTime time2 = new DateTime(DateHelper.getLastDayOfYear(DateUtil.year(dateTime)));
        time2.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        DateTime planstartTime = time1.setField(DateField.HOUR_OF_DAY, 0).setField(DateField.MINUTE, 0).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
        DateTime planendTime = DateUtil.endOfDay(time2).setField(DateField.MILLISECOND, 0);//.offset(DateField.MILLISECOND, -999);
        for (AppPlan appPlan : AppPlanList) {
            //获取履职计划中对应的检查要点
            List<AppRulePointTaskVo> pointList = appRulePointService.findPointByPlan(appPlan.getId());
            if (pointList.size() <= 0) {//没有检查项不生成履职任务
//                RESUMPTIONLOG.error("error:该计划ID：{}没有检查项", appPlan.getId());
                continue;
            }
            //根据计划获取履职任务执行机构
            List<Long> orgIds = getPlanOrgIds(appPlan);
            if (orgIds == null || orgIds.size() <= 0) {//没有检查项不生成履职任务
//                RESUMPTIONLOG.error("error:该计划ID：{}没有执行机构", appPlan.getId());
                continue;
            }
            //获取履职角色
            List<Long> roleIds = appPlanService.findRoleByPlan(appPlan.getId());
            if (roleIds.size() <= 0) {//没有检查项不生成履职任务
//                RESUMPTIONLOG.error("error:该计划ID：{}没有履职角色", appPlan.getId());
                continue;
            }
            //获取所有要点中的区域id
            Set<Long> nfcBindIdList = new HashSet<>();
            for (AppRulePointTaskVo p : pointList) {
                if (p.getNfcBindId() != null && p.getPointScan() == 1) {
                    nfcBindIdList.add(p.getNfcBindId());
                }
            }
            //根据区域获取区域内绑定的nfc
           /* NFCBindJobDto jobDto = new NFCBindJobDto();
            jobDto.setAreaIds(new ArrayList(areaList));
            List<NFCBindPageVo> nfcList =  nfcBindService.all(jobDto,NFCBindPageVo::to);*/
            for (Long orgId : orgIds) {
                /*NFCBindJobDto jobDto = new NFCBindJobDto();
                jobDto.setNfcBindIdList(new ArrayList(nfcBindIdList));
                jobDto.setOrgId(orgId);
                List<NFCBindPageVo> nfcList =  nfcBindService.all(jobDto,NFCBindPageVo::to);*/
                // for(Long roleId:roleIds){
                this.resumptionService.newbuild(orgId, ResumptionType.YEAR, dateTime, true, appPlan, null, pointList, roleIds, planstartTime, planendTime);
                //}

            }
        }

    }


    public Ymd toYmd(final Date date, String value) {
        DateHelper dateHelper = new DateHelper(date);
        switch (value) {
            case "DAY":
                return Ymd.builder()
                        .year(dateHelper.getYear())
                        .month(dateHelper.getMonth())
                        .day(dateHelper.getDay())
                        .build();
            case "WEEK":
                return Ymd.builder()
                        .year(DateUtil.year(date))
                        .week(DateUtil.weekOfYear(date))
                        .build();
            case "MONTH":
                return Ymd.builder()
                        .year(dateHelper.getYear())
                        .month(dateHelper.getMonth())
                        .build();
            case "QUARTER":
                return Ymd.builder()
                        .year(dateHelper.getYear())
                        .quarter(dateHelper.getQuarter())
                        .build();
            case "HALFYEAR":
                return Ymd.builder()
                        .year(dateHelper.getYear())
                        .halfyear(dateHelper.getHalfyear())
                        .build();
            case "HOUR":
                return Ymd.builder()
                        .year(dateHelper.getYear())
                        .month(dateHelper.getMonth())
                        .day(dateHelper.getDay())
                        .hour(dateHelper.getHour())
                        .minute(dateHelper.getMin())
                        .build();
            default:
                return Ymd.builder()
                        .year(dateHelper.getYear())
                        .build();
        }
    }

//    public void updateTaskStatus() {
//        this.resumptionService.updateTaskStatus();
//    }

    /**
     * 获取计划的执行机构id
     *
     * @param appPlan
     * @return
     */
    private List<Long> getPlanOrgIds(AppPlan appPlan) {
        List<Long> orgIds = null;
        if (appPlan.getExecType()!=null&&appPlan.getExecType() == 0) {//0机构类型需要安类型去机构里查询所以的机构
            orgIds = orgService.findListByOrgType(appPlan.getExecOrgType(),SecurityConstants.INNER).getData();
        } else {
            List<SysOrg> sysOrgs = orgService.selectByOrgType(appPlan.getExecOrgType(), SecurityConstants.INNER);
             orgIds = sysOrgs.stream().map(SysOrg::getId).collect(Collectors.toList());
//            orgIds = appPlanService.findExecOrgByPlan(appPlan.getId());
        }

        return orgIds;
    }

    private List<SysOrg> getPlanOrgs(AppPlan appPlan) {
        List<Long> orgIds = null;
        if (appPlan.getExecType() == 0) {//0机构类型需要安类型去机构里查询所以的机构
            orgIds = orgService.findListByOrgType(appPlan.getExecOrgType(),SecurityConstants.INNER).getData();
        } else {
            orgIds = appPlanService.findExecOrgByPlan(appPlan.getId());
        }

        return orgService.listByIds(orgIds,SecurityConstants.INNER).getData();
    }



    /**
     * 根据作息变更生成新的每日每小时履职任务
     *
     * @param event
     */
//    @Async
//    public void createNewResumption(WorkChangeEvent event) {
//        List<Long> orgIds = event.getOrgIds();
//        DateTime dateTime = event.getDateTime();
//        dateTime.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
//        for (Long orgId : orgIds) {
//            // 作息修改后,履职任务变更,删除待办缓存
//            iTodoService.delTodoCache(orgId);
//        }
//        //获取作息
//        // final WorkTime workTime = this.workTimeService.findWorkTimeByYmd(orgId, ResumptionType.DAY.toYmd(dateTime), true);
//        List<WorkTime> workTimes = objectMapper.findWorkTimesByYmd(orgIds, DateTime.of(dateTime), 1);
//        //修改后没有作息的情况
//        if (workTimes == null || workTimes.size() == 0) {
//            RESUMPTIONLOG.info("作息变更，未找到作息：" + JSON.toJSONString(event));
//            List<WorkChangeResumptionVo> listDayAndHour = this.findDayAndHourResumption(orgIds, dateTime);
////            listDayAndHour.stream().filter(r->r.ex)
//            //删除任务和代办
//            if (listDayAndHour.size() > 0) {
//                this.deletedResumptionAdnTodo(listDayAndHour, dateTime);
//            }
//        } else {//修改后有作息的情况
//            RESUMPTIONLOG.info("作息变更，找到作息：" + JSON.toJSONString(event));
//            //每日任务未做的可以直接删除重新生成
//            this.dayResumption(workTimes, orgIds, dateTime);
//            this.hourResumption(workTimes, orgIds, dateTime);
//        }
//        for (Long orgId : orgIds) {
//            iTodoService.delTodoCache(orgId);
//        }
//        delayTaskService.flushDelayQueueTodoData();
//    }


    /**
     * 按机构生成单机构的每日履职任务
     *
     * @param workTimes
     * @param orgIds
     * @param dateTime
     */
    public void dayResumption(List<SysWorkTime> workTimes, List<Long> orgIds, DateTime dateTime) {
        //获取每日任务
        int year = DateUtil.year(dateTime);
        int quarter = DateUtil.quarter(dateTime);
        List<WorkChangeResumptionVo> listDay = resumptionService.findResumptionList(orgIds, DateTime.of(dateTime), 0, null, year, quarter);
        Set<Long> planIds = new HashSet<>();
        Set<Long> planIdsa = new HashSet<>();
        List<Map<String, Long>> planIdAndOrgs = new ArrayList<>();
        List<AppPlan> appPlanList = null;
        List<WorkChangeResumptionVo> listDayWwc = null;
        List<SysResumption> listResumption = new ArrayList<>();
        //已有任务
        if (listDay != null && listDay.size() > 0) {
            //获取未完成的任务
            listDayWwc = listDay.stream().filter(r -> r.getStatus() == 0).collect(Collectors.toList());
            List<WorkChangeResumptionVo> listDayYwc = listDay.stream().filter(r -> r.getStatus() == 1 || r.getStatus() == 2 || r.getStatus() == 5).collect(Collectors.toList());
            for (WorkChangeResumptionVo vo : listDayWwc) {
                planIds.add(vo.getPlanId());
            }
            for (WorkChangeResumptionVo vo : listDayYwc) {
                planIdsa.add(vo.getPlanId());
                Map<String, Long> map = new HashMap<>();
                map.put("planId", vo.getPlanId());
                map.put("orgId", vo.getOrgId());
                planIdAndOrgs.add(map);
            }
            if (planIds.size() == 0) {
                QueryWrapper<AppPlan> qw = new QueryWrapper();
                qw.lambda().eq(AppPlan::getPlanStatus, 0);
                qw.lambda().eq(AppPlan::getPlanCycle, 0);
                qw.lambda().eq(AppPlan::getPlanType, 0);
                qw.lambda().notIn(AppPlan::getPlanExec, canteenPlanExec);
                qw.lambda().notIn(AppPlan::getId, planIdsa);
                appPlanList = appPlanService.list(qw);
            } else {
                QueryWrapper<AppPlan> qw = new QueryWrapper();
                qw.lambda().in(AppPlan::getId, planIds);
                appPlanList = appPlanService.list(qw);
            }


        } else {//没得任务
            QueryWrapper<AppPlan> qw = new QueryWrapper();
            qw.lambda().eq(AppPlan::getPlanStatus, 0);
            qw.lambda().eq(AppPlan::getPlanCycle, 0);
            qw.lambda().eq(AppPlan::getPlanType, 0);
            qw.lambda().notIn(AppPlan::getPlanExec, canteenPlanExec);
            appPlanList = appPlanService.list(qw);
        }

        for (AppPlan appPlan : appPlanList) {
            List<Long> roleIds = appPlanService.findRoleByPlan(appPlan.getId());
            if (roleIds.size() <= 0) {
//                RESUMPTIONLOG.error("error:该计划ID：{}没有履职角色", appPlan.getId());
                continue;
            }
            List<Long> zxOrgIds = getPlanOrgIds(appPlan);
            if (zxOrgIds == null || zxOrgIds.size() <= 0) {//没有检查项不生成履职任务
//                RESUMPTIONLOG.error("error:该计划ID：{}没有执行机构", appPlan.getId());
                continue;
            }

            for (Long orgId : orgIds) {
                if (!zxOrgIds.contains(orgId)) {
//                    RESUMPTIONLOG.error("机构{}没有此计划", orgId);
                    continue;

                }
                List<SysWorkTime> workTimesa = workTimes.stream().filter(r -> r.getOrgId().equals(orgId)).collect(Collectors.toList());
                if (workTimesa != null && workTimesa.size() > 0) {
                    SysWorkTime workTime = workTimesa.get(0);
                    Map<String, DateTime> map = this.buildDayPlanTiem(appPlan, workTime, dateTime);
                    DateTime planstartTime = map.get("planstartTime");
                    DateTime planendTime = map.get("planendTime");
                    List<SysResumption> resumptionList = buildResumptionList(orgId, ResumptionType.DAY, dateTime, appPlan, roleIds, planstartTime, planendTime);
                    if (resumptionList != null) {
                        listResumption.addAll(resumptionList);
                    }

                    // resumptionService.newbuild(orgId, ResumptionType.DAY, dateTime, true, appPlan, null, null, roleIds, planstartTime, planendTime);
                }
            }
        }
        //todo 保存履职任务
        //删除任务和代表
        resumptionService.saveResumption(listResumption, appPlanList, planIdAndOrgs);
        if (listDayWwc != null) {
            this.deletedResumptionAdnTodo(listDayWwc, dateTime);
        }
    }

  /*  public void saveResumption(List<Resumption> listResumption,List<AppPlan> appPlanList) {
        resumptionService.save(listResumption);
        for(Resumption resumption:listResumption){
            AppPlan appPlan = appPlanList.stream().filter(r->r.getId().equals(resumption.getPlanId())).collect(Collectors.toList()).get(0);
            resumptionService.daiban(resumption,resumption.getRoleId(),appPlan,resumption.getOrgId(),resumption.getType().ordinal());
        }
    }*/

    private Map<String, DateTime> buildDayPlanTiem(AppPlan appPlan, SysWorkTime workTime, DateTime dateTime) {
        Map<String, DateTime> map = new HashMap<>();
        DateTime planstartTime = null;
        DateTime planendTime = null;
        if (workTime != null) {
            String opentime = workTime.getOpenTime();//营业时间
            String closetime = workTime.getCloseTime();//营业终了
            if (appPlan.getPlanExec() == 0) {//全天 上班时间-下班时间 00:00:00-23:59:59
                DateTime time1 = new DateTime(dateTime);
                time1.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                DateTime time2 = new DateTime(dateTime);
                time2.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                planstartTime = time1.setField(DateField.HOUR_OF_DAY, 0).setField(DateField.MINUTE, 0).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
                ;
                planendTime = DateUtil.endOfDay(time2).setField(DateField.MILLISECOND, 0);
            } else if (appPlan.getPlanExec() == 1) {//营业前 上班时间-营业时间
                DateTime time1 = new DateTime(dateTime);
                time1.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                DateTime time2 = new DateTime(dateTime);
                time2.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                planstartTime = time1.setField(DateField.HOUR_OF_DAY, 0).setField(DateField.MINUTE, 0).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
                ;
                planendTime = time2.setField(DateField.HOUR_OF_DAY, Integer.parseInt(opentime.split(":")[0])).setField(DateField.MINUTE, Integer.parseInt(opentime.split(":")[1])).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
                ;
            } else if (appPlan.getPlanExec() == 2) {//营业期间 营业时间-营业终了
                DateTime time1 = new DateTime(dateTime);
                time1.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                DateTime time2 = new DateTime(dateTime);
                time2.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                planstartTime = time1.setField(DateField.HOUR_OF_DAY, Integer.parseInt(opentime.split(":")[0])).setField(DateField.MINUTE, Integer.parseInt(opentime.split(":")[1])).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
                ;
                planendTime = time2.setField(DateField.HOUR_OF_DAY, Integer.parseInt(closetime.split(":")[0])).setField(DateField.MINUTE, Integer.parseInt(closetime.split(":")[1])).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
                ;
            } else if (appPlan.getPlanExec() == 3) {//营业终 营业终了-23.59.59
                DateTime time1 = new DateTime(dateTime);
                time1.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                DateTime time2 = new DateTime(dateTime);
                time2.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                planstartTime = time1.setField(DateField.HOUR_OF_DAY, Integer.parseInt(closetime.split(":")[0])).setField(DateField.MINUTE, Integer.parseInt(closetime.split(":")[1])).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
                ;
                planendTime = DateUtil.endOfDay(time2).setField(DateField.MILLISECOND, 0);//.offset(DateField.MILLISECOND, -999);
            }
        }
        map.put("planstartTime", planstartTime);
        map.put("planendTime", planendTime);
        return map;
    }

    public void hourResumption(List<SysWorkTime> workTimes, List<Long> orgIds, DateTime dateTime) {
        //获取每小时任务
        int year = DateUtil.year(dateTime);
        int quarter = DateUtil.quarter(dateTime);
        List<WorkChangeResumptionVo> listHour = resumptionService.findResumptionList(orgIds, DateTime.of(dateTime), 6, null, year, quarter);
        Set<Long> planIds = new HashSet<>();
        List<Map<String, Long>> planIdAndOrgs = new ArrayList<>();
        List<AppPlan> appPlanList = null;
        List<AppPlan> appPlanListAll = new ArrayList<>();
        List<WorkChangeResumptionVo> listDaydelete = new ArrayList<>();
        List<SysResumption> listResumption = new ArrayList<>();
        //将数据按机构分组
        if (listHour != null && listHour.size() > 0) {
            Map<Long, List<WorkChangeResumptionVo>> listHourMap = listHour.stream().collect(Collectors.groupingBy(WorkChangeResumptionVo::getOrgId));
            for (Long key : listHourMap.keySet()) {
                List<SysWorkTime> workTimesa = workTimes.stream().filter(r -> r.getOrgId().equals(key)).collect(Collectors.toList());
                List<WorkChangeResumptionVo> listHourOneOrg = listHourMap.get(key);
                //已有任务
                if (listHourOneOrg != null && listHourOneOrg.size() > 0) {
                    //将任务按计划分组
                    Map<Long, List<WorkChangeResumptionVo>> listHourOneOrgMap = listHourOneOrg.stream().collect(Collectors.groupingBy(r -> r.getPlanId()));
                    for (Long keya : listHourOneOrgMap.keySet()) {
                        List<WorkChangeResumptionVo> listOnePlan = listHourOneOrgMap.get(keya);
                        int num = (int) listOnePlan.stream().filter(r -> r.getStatus() == 1 || r.getStatus() == 2 || r.getStatus() == 5).count();
                        //已完成的任务数大于0
                        if (num > 0) {
                            Map<String, Long> map = new HashMap<>();
                            map.put("planId", keya);
                            map.put("orgId", key);
                            planIdAndOrgs.add(map);
                            continue;
                        } else {
                            planIds.add(keya);
                            listDaydelete.addAll(listOnePlan);

                        }
                    }
                    if (planIds != null && planIds.size() > 0) {
                        QueryWrapper<AppPlan> qw = new QueryWrapper();
                        qw.lambda().in(AppPlan::getId, planIds);
                        appPlanList = appPlanService.list(qw);
                        if (appPlanList != null) {
                            appPlanListAll.addAll(appPlanList);
                        }
                    }

                    if (appPlanList != null && appPlanList.size() > 0 && workTimesa.size() > 0) {
                        List<SysResumption> resumptionList = this.buildResumption(appPlanList, workTimesa.get(0), dateTime, key);
                        if (resumptionList != null && resumptionList.size() > 0) {
                            listResumption.addAll(resumptionList);
                        }
                    }

                } else {//没得任务直接通过计划和作息生成任务
                    QueryWrapper<AppPlan> qw = new QueryWrapper();
                    qw.lambda().eq(AppPlan::getPlanStatus, "0");
                    qw.lambda().eq(AppPlan::getPlanType, 0);
                    qw.lambda().eq(AppPlan::getPlanCycle, 6);
                    qw.lambda().notIn(AppPlan::getPlanExec, canteenPlanExec);
                    appPlanList = appPlanService.list(qw);
                    if (appPlanList != null) {
                        appPlanListAll.addAll(appPlanList);
                    }
                    if (appPlanList != null && appPlanList.size() > 0 && workTimesa.size() > 0) {
                        List<SysResumption> resumptionList = this.buildResumption(appPlanList, workTimesa.get(0), dateTime, key);
                        if (resumptionList != null && resumptionList.size() > 0) {
                            listResumption.addAll(resumptionList);
                        }
                    }

                }
            }
        } else {
            QueryWrapper<AppPlan> qw = new QueryWrapper();
            qw.lambda().eq(AppPlan::getPlanStatus, "0");
            qw.lambda().eq(AppPlan::getPlanCycle, 6);
            qw.lambda().notIn(AppPlan::getPlanExec, canteenPlanExec);
            appPlanList = appPlanService.list(qw);
            if (appPlanList != null) {
                appPlanListAll.addAll(appPlanList);
            }
            for (Long orgId : orgIds) {
                List<SysWorkTime> workTimesa = workTimes.stream().filter(r -> r.getOrgId().equals(orgId)).collect(Collectors.toList());
                if (appPlanList != null && appPlanList.size() > 0 && workTimesa.size() > 0) {
                    List<SysResumption> resumptionList = this.buildResumption(appPlanList, workTimesa.get(0), dateTime, orgId);
                    if (resumptionList != null && resumptionList.size() > 0) {
                        listResumption.addAll(resumptionList);
                    }
                }
            }
        }

        if (listResumption.size() > 0) {
            //todo 保存履职任务
            resumptionService.saveResumption(listResumption, appPlanListAll, planIdAndOrgs);
        }
        if (listDaydelete.size() > 0) {
            this.deletedResumptionAdnTodo(listDaydelete, dateTime);
        }

    }

    public List<SysResumption> buildResumption(List<AppPlan> appPlanList, SysWorkTime workTime, DateTime dateTime, Long orgId) {
        List<SysResumption> resumptions = new ArrayList<>();
        for (AppPlan appPlan : appPlanList) {
            List<Long> zxOrgIds = getPlanOrgIds(appPlan);
            if (zxOrgIds == null || zxOrgIds.size() <= 0) {//没有检查项不生成履职任务
//                RESUMPTIONLOG.error("error:该计划ID：{}没有执行机构", appPlan.getId());
                continue;
            }
            if (!zxOrgIds.contains(orgId)) {
//                RESUMPTIONLOG.error("机构{}没有此计划", orgId);
                continue;
            }
            List<Map<String, DateTime>> mapList = this.buildHourPlanTiem(appPlan, workTime, dateTime);
            List<Long> roleIds = appPlanService.findRoleByPlan(appPlan.getId());
            if (roleIds.size() <= 0) {
//                RESUMPTIONLOG.error("error:该计划ID：{}没有履职角色", appPlan.getId());
                continue;
            }
            for (Map<String, DateTime> map : mapList) {
                DateTime planstartTime = map.get("planstartTime");
                DateTime planendTime = map.get("planendTime");
                List<SysResumption> resumptionList = buildResumptionList(orgId, ResumptionType.HOUR, dateTime, appPlan, roleIds, planstartTime, planendTime);
                if (resumptionList != null) {
                    resumptions.addAll(resumptionList);
                }
            }
        }
        return resumptions;
    }

    public List<SysResumption> buildResumptionList(final Long orgId, final ResumptionType type, final Date dateTime, AppPlan appPlan, List<Long> roleIds, DateTime planstartTime, DateTime planendTime) {
        final Ymd ymd = Ymd.of(dateTime);
        List<SysResumption> resumptions = new ArrayList<>();
        Date time = new Date();
        for (Long roleId : roleIds) {
            //结束时间 23:59:59变00:00:00的问题(周，月，季，半年，年)
            String id = UUID.randomUUID().toString().replaceAll("-", "");
            SysResumption resumption = new SysResumption();
            resumption.setStatus((long) ResumptionStatus.WAIT.ordinal());
            resumption.setYmd(ymd);
            resumption.setPlanId(appPlan.getId());
            resumption.setType((long) type.ordinal());
            resumption.setRoleId(roleId);
            resumption.setPlanStartTime(planstartTime);
            resumption.setPlanEndTime(planendTime);
            resumption.setCreateTime(time);
            resumption.setOrgId(orgId);
            resumption.setId(id);
            resumptions.add(resumption);

        }
        return resumptions;
    }

    private List<Map<String, DateTime>> buildHourPlanTiem(AppPlan appPlan, SysWorkTime workTime, DateTime dateTime) {
        List<String[]> workTimes = new ArrayList<>();
        if (appPlan.getNotResumptionOnRest() != null && appPlan.getNotResumptionOnRest() == 1 &&
                StringUtils.isNotEmpty(workTime.getNoonbreakStart()) && StringUtils.isNotEmpty(workTime.getNoonbreakEnd())) {
            workTimes.add(new String[]{workTime.getOpenTime(), workTime.getNoonbreakStart()});
            workTimes.add(new String[]{workTime.getNoonbreakEnd(), workTime.getCloseTime()});
        } else {
            workTimes.add(new String[]{workTime.getOpenTime(), workTime.getCloseTime()});
        }
        List<Map<String, DateTime>> mapList = new ArrayList<>();
        for (int ti = 0; ti < workTimes.size(); ti++) {
            String[] time = workTimes.get(ti);
            String openStr = time[0];
            String closeStr = time[1];
            String[] openArr = openStr.split(":");
            String[] closeArr = closeStr.split(":");
            int openHour = 0;
            if (ti == 0) {
                openHour = Integer.parseInt(openArr[0]) - 1;
            } else {
                openHour = Integer.parseInt(openArr[0]);
            }
            int openMinute = Integer.parseInt(openArr[1]);
            //int closeHour = Integer.parseInt(closeArr[0])+1;
            int closeHour = Integer.parseInt(closeArr[0]);
            int closeMinute = Integer.parseInt(closeArr[1]);
            if (openMinute < closeMinute) {
                closeHour += 1;
            }
            int len = closeHour - openHour;
            if (len > 1) {
                int i = ti == 0 ? 1 : 0;
                for (; i < len; i++) {//为每个作息点生成履职任务
                    Map<String, DateTime> map = new HashMap<>();
                    dateTime.setField(DateField.HOUR_OF_DAY, openHour + i);
                    dateTime.setField(DateField.MINUTE, openMinute);
                    //this.resumptionService.build(orgId, ResumptionType.HOUR, dateTime, true);
                    //每个作息点的开始时间和结束时间,不能直接操作dateTime，后面的操作会覆盖前面的操作
                    DateTime time1 = new DateTime(dateTime);
                    time1.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                    DateTime time2 = new DateTime(dateTime);
                    time2.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                    DateTime planstartTime = time1.setField(DateField.HOUR_OF_DAY, openHour + i).setField(DateField.MINUTE, openMinute).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
                    DateTime planendTime = time2.setField(DateField.HOUR_OF_DAY, openHour + i + 1).setField(DateField.MINUTE, openMinute).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
                    map.put("planstartTime", planstartTime);
                    map.put("planendTime", planendTime);
                    mapList.add(map);
                }
            }
        }
        return mapList;
    }

    private List<WorkChangeResumptionVo> findDayAndHourResumption(List<Long> orgIds, DateTime dateTime) {
        List<WorkChangeResumptionVo> listDayAndHour = new ArrayList<>();
        //获取每日履职任务
        int year = DateUtil.year(dateTime);
        int quarter = DateUtil.quarter(dateTime);
        List<WorkChangeResumptionVo> listDay = resumptionService.findResumptionList(orgIds, DateTime.of(dateTime), 0, null, year, quarter);
        //获取每小时的任务
        List<WorkChangeResumptionVo> listHour = resumptionService.findResumptionList(orgIds, DateTime.of(dateTime), 6, null, year, quarter);
        //如果没得每日任务不做操作
        if (listDay != null && listDay.size() != 0) {
            //将数据按机构分组
            Map<Long, List<WorkChangeResumptionVo>> listDayMap = listDay.stream().collect(Collectors.groupingBy(WorkChangeResumptionVo::getOrgId));
            for (Long key : listDayMap.keySet()) {
                List<WorkChangeResumptionVo> listDayOneOrg = listDayMap.get(key);
                //删除未完成的任务
                List<WorkChangeResumptionVo> listDayOneOrgWwc = listDayOneOrg.stream().filter(r -> r.getStatus() == 0).collect(Collectors.toList());
                //删除任务
                listDayAndHour.addAll(listDayOneOrgWwc);
                //获取一个机构完成的任务数据
                /*int num= (int) listDayOneOrg.stream().filter(r->r.getStatus()==1||r.getStatus()==2||r.getStatus()==5).count();
                //如果有完成的数据，则不做操作，否则删除任务及代办
                if(num==0){
                    //删除任务
                    listDayAndHour.addAll(listDayOneOrg);
                }*/
            }

        }
        //如果没得每小时任务不做操作
        if (listHour != null && listHour.size() != 0) {
            //将数据按机构分组
            Map<Long, List<WorkChangeResumptionVo>> listHourMap = listHour.stream().collect(Collectors.groupingBy(WorkChangeResumptionVo::getOrgId));
            for (Long key : listHourMap.keySet()) {
                List<WorkChangeResumptionVo> listHourOneOrg = listHourMap.get(key);
                //获取完成的任务数据
                int num = (int) listHourOneOrg.stream().filter(r -> r.getStatus() == 1 || r.getStatus() == 2 || r.getStatus() == 5).count();
                //如果有完成的数据，则不做操作，否则删除任务及代办
                if (num == 0) {
                    //删除任务
                    listDayAndHour.addAll(listHourOneOrg);
                }
            }

        }

        return listDayAndHour;
    }

    /**
     * 删除任务和代办
     *
     * @param list
     */
    @Transactional(rollbackFor = Exception.class)
    public void deletedResumptionAdnTodo(List<WorkChangeResumptionVo> list, DateTime dateTime) {
        List<String> ids = new ArrayList<>();
        for (WorkChangeResumptionVo vo : list) {
            ids.add(vo.getId());
        }
        if (ids.size() > 0) {
            //删除任务
            int year = DateUtil.year(dateTime);
            int quarter = DateUtil.quarter(dateTime);
            resumptionService.deleteResumption(ids, year, quarter);
            //删除代表
//            todoService.remove(ids);
        }

    }

//    public void createResumption(doTaskDto request) {
//        String time = request.getTime();
//        DateTime datetime = new DateTime(DateUtil.parse(time, "yyyy-MM-dd"));
//        datetime.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
//        //当有周期存在时保持原有接口不变（doTask），否则按照新的接口创建
//        Integer plancycle = request.getPlancycle();
//        if (plancycle != null) {
//            if (plancycle == 6) {
//                this.syncHour(datetime, plancycle);
//            }
//            if (plancycle == 0) {
//                this.syncDay(datetime, plancycle);
//            }
//            if (plancycle == 1) {
//                this.syncWeek(datetime, plancycle);
//            }
//            if (plancycle == 2) {
//                this.syncMonth(datetime, plancycle);
//            }
//            if (plancycle == 3) {
//                this.syncQuarter(datetime, plancycle);
//            }
//            if (plancycle == 4) {
//                this.syncHalfYear(datetime, plancycle);
//            }
//            if (plancycle == 5) {
//                this.syncYear(datetime, plancycle);
//            }
//        } else {
//            //按照新的接口创建
//            List<Long> orgIds = request.getOrgIds();
//            List<Long> planIds = request.getPlanIds();
//            this.createNewResumptionByOrgAndPlan(orgIds, planIds, datetime);
//        }
//    }

    private void createNewResumptionByOrgAndPlan(List<Long> orgIds, List<Long> planIds, DateTime datetime) {
        //更加计划id获取启用状态的计划
        List<AppPlan> appPlans = getAppPlanByPlanIds(planIds);
        //获取有作息的机构id
        List<Long> workOrgIds = this.workTimeService.findOrgIdsByYmd(datetime.toString().substring(0, 10),SecurityConstants.INNER).getData();
        for (AppPlan plan : appPlans) {
            //获取每个计划要生成任务的机构
            List<Long> orgIdsByPlanListNew = getOrgIdsByPlanIds(plan, orgIds, workOrgIds);
            //获取履职角色
            List<Long> roleIds = appPlanService.findRoleByPlan(plan.getId());
            //开始生成任务
            saveResumptionByOrgAndPlan(orgIdsByPlanListNew, plan, roleIds, datetime);
        }

    }

    private void saveResumptionByOrgAndPlan(List<Long> orgIdsByPlanListNew, AppPlan plan, List<Long> roleIds, DateTime datetime) {
        if (plan.getPlanCycle() == 0) {
            //按天生成任务
            saveResumptionByDay(orgIdsByPlanListNew, plan, roleIds, datetime);
        }
        if (plan.getPlanCycle() == 1) {
            //按周生成任务
            saveResumptionByWeek(orgIdsByPlanListNew, plan, roleIds, datetime);
        }
        if (plan.getPlanCycle() == 2) {
            //按月生成任务
            saveResumptionByMonth(orgIdsByPlanListNew, plan, roleIds, datetime);
        }
        if (plan.getPlanCycle() == 3) {
            //按季度生成任务
            saveResumptionByQuarter(orgIdsByPlanListNew, plan, roleIds, datetime);
        }
        if (plan.getPlanCycle() == 4) {
            //按半年生成任务
            saveResumptionByHalfYear(orgIdsByPlanListNew, plan, roleIds, datetime);
        }
        if (plan.getPlanCycle() == 5) {
            //按年生成任务
            saveResumptionByYear(orgIdsByPlanListNew, plan, roleIds, datetime);
        }
        if (plan.getPlanCycle() == 6) {
            //按小时生成任务
            saveResumptionByHour(orgIdsByPlanListNew, plan, roleIds, datetime);
        }
    }

    private void saveResumptionByDay(List<Long> orgIdsByPlanListNew, AppPlan appPlan, List<Long> roleIds, DateTime dateTime) {
        for (Long orgId : orgIdsByPlanListNew) {
            Ymd ymd=toYmd(dateTime,"DAY");
            ymd.setOrgId(orgId);
            ymd.setEnable(true);
            final SysWorkTime workTime = this.workTimeService.findWorkTimeByYmd(ymd).getData();
            DateTime planstartTime = null;
            DateTime planendTime = null;
            if (workTime != null) {
                String worktime = workTime.getWorkTime();//上班时间
                String workofftime = workTime.getWorkOffTime();//下班时间
                String opentime = workTime.getOpenTime();//营业时间
                String closetime = workTime.getCloseTime();//营业终了
                if (appPlan.getPlanExec() == 0) {//全天 上班时间-下班时间 00:00:00-23:59:59
                    DateTime time1 = new DateTime(dateTime);
                    time1.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                    DateTime time2 = new DateTime(dateTime);
                    time2.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                    planstartTime = time1.setField(DateField.HOUR_OF_DAY, 0).setField(DateField.MINUTE, 0).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
                    planendTime = DateUtil.endOfDay(time2).setField(DateField.MILLISECOND, 0);//.offset(DateField.MILLISECOND, -999);
                    //planstartTime = time1.setField(DateField.HOUR_OF_DAY,Integer.parseInt(worktime.split(":")[0])).setField(DateField.MINUTE,Integer.parseInt(worktime.split(":")[1])).setField(DateField.SECOND,0);
                    //planendTime = time2.setField(DateField.HOUR_OF_DAY,Integer.parseInt(workofftime.split(":")[0])).setField(DateField.MINUTE,Integer.parseInt(workofftime.split(":")[1])).setField(DateField.SECOND,0);
                } else if (appPlan.getPlanExec() == 1) {//营业前 上班时间-营业时间
                    DateTime time1 = new DateTime(dateTime);
                    time1.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                    DateTime time2 = new DateTime(dateTime);
                    time2.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                    planstartTime = time1.setField(DateField.HOUR_OF_DAY, 0).setField(DateField.MINUTE, 0).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
                    planendTime = time2.setField(DateField.HOUR_OF_DAY, Integer.parseInt(opentime.split(":")[0])).setField(DateField.MINUTE, Integer.parseInt(opentime.split(":")[1])).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
                } else if (appPlan.getPlanExec() == 2) {//营业期间 营业时间-营业终了
                    DateTime time1 = new DateTime(dateTime);
                    time1.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                    DateTime time2 = new DateTime(dateTime);
                    time2.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                    planstartTime = time1.setField(DateField.HOUR_OF_DAY, Integer.parseInt(opentime.split(":")[0])).setField(DateField.MINUTE, Integer.parseInt(opentime.split(":")[1])).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
                    planendTime = time2.setField(DateField.HOUR_OF_DAY, Integer.parseInt(closetime.split(":")[0])).setField(DateField.MINUTE, Integer.parseInt(closetime.split(":")[1])).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
                } else if (appPlan.getPlanExec() == 3) {//营业终 营业终了-23.59.59
                    DateTime time1 = new DateTime(dateTime);
                    time1.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                    DateTime time2 = new DateTime(dateTime);
                    time2.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                    planstartTime = time1.setField(DateField.HOUR_OF_DAY, Integer.parseInt(closetime.split(":")[0])).setField(DateField.MINUTE, Integer.parseInt(closetime.split(":")[1])).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
                    planendTime = DateUtil.endOfDay(time2).setField(DateField.MILLISECOND, 0);//.offset(DateField.MILLISECOND, -999);
                }
                resumptionService.newbuild(orgId, ResumptionType.DAY, dateTime, true, appPlan, null, null, roleIds, planstartTime, planendTime);
            } else {
//                RESUMPTIONLOG.error("{} 没有作息", ResumptionType.DAY.toYmd(dateTime));
            }
        }
    }

    private void saveResumptionByWeek(List<Long> orgIdsByPlanListNew, AppPlan appPlan, List<Long> roleIds, DateTime dateTime) {
        KeyValue<Integer, Integer> yearWeek = new KeyValue<>(DateUtil.year(dateTime), DateUtil.weekOfYear(dateTime));
        DateTime time1 = new DateTime(dateTime);
        time1.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        DateTime time2 = new DateTime(DateHelper.getLastDayOfWeek(yearWeek.getKey(), yearWeek.getValue()));
        if (time2.isBefore(time1)) {//说明跨年了
            time2 = new DateTime(DateHelper.getLastDayOfWeek(yearWeek.getKey() + 1, yearWeek.getValue()));
        }
        time2.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        DateTime planstartTime = time1.setField(DateField.HOUR_OF_DAY, 0).setField(DateField.MINUTE, 0).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
        ;
        DateTime planendTime = DateUtil.endOfDay(time2).setField(DateField.MILLISECOND, 0);//.offset(DateField.MILLISECOND, -999);
        for (Long orgId : orgIdsByPlanListNew) {
            this.resumptionService.newbuild(orgId, ResumptionType.WEEK, dateTime, true, appPlan, null, null, roleIds, planstartTime, planendTime);
        }
    }

    private void saveResumptionByMonth(List<Long> orgIdsByPlanListNew, AppPlan appPlan, List<Long> roleIds, DateTime dateTime) {
        KeyValue<Integer, Integer> yearMonth = new KeyValue<>(DateUtil.year(dateTime), DateUtil.month(dateTime) + 1);
        DateTime time1 = new DateTime(dateTime);
        time1.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        DateTime time2 = new DateTime(DateHelper.getLastDayOfMonth(yearMonth.getKey(), yearMonth.getValue()));
        time2.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        DateTime planstartTime = time1.setField(DateField.HOUR_OF_DAY, 0).setField(DateField.MINUTE, 0).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
        DateTime planendTime = DateUtil.endOfDay(time2).setField(DateField.MILLISECOND, 0);
        for (Long orgId : orgIdsByPlanListNew) {
            this.resumptionService.newbuild(orgId, ResumptionType.MONTH, dateTime, true, appPlan, null, null, roleIds, planstartTime, planendTime);

        }
    }

    private void saveResumptionByQuarter(List<Long> orgIdsByPlanListNew, AppPlan appPlan, List<Long> roleIds, DateTime dateTime) {
        KeyValue<Integer, Integer> yearQuarter = new KeyValue<>(DateUtil.year(dateTime), DateUtil.quarter(dateTime));
        DateTime time1 = new DateTime(dateTime);
        time1.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        DateTime time2 = new DateTime(DateHelper.getLastDayOfQuarter(yearQuarter.getKey(), yearQuarter.getValue()));
        time2.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        DateTime planstartTime = time1.setField(DateField.HOUR_OF_DAY, 0).setField(DateField.MINUTE, 0).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
        DateTime planendTime = DateUtil.endOfDay(time2).setField(DateField.MILLISECOND, 0);//.offset(DateField.MILLISECOND, -999);
        for (Long orgId : orgIdsByPlanListNew) {
            this.resumptionService.newbuild(orgId, ResumptionType.QUARTER, dateTime, true, appPlan, null, null, roleIds, planstartTime, planendTime);
        }
    }

    private void saveResumptionByHalfYear(List<Long> orgIdsByPlanListNew, AppPlan appPlan, List<Long> roleIds, DateTime dateTime) {
        DateHelper dateHelper = new DateHelper(dateTime);
        KeyValue<Integer, Integer> yearHalfYear = new KeyValue<>(DateUtil.year(dateTime), dateHelper.getHalfyear());
        DateTime time1 = new DateTime(dateTime);
        time1.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        DateTime time2 = new DateTime(DateHelper.getLastDayOfHalfyear(yearHalfYear.getKey(), yearHalfYear.getValue()));
        time2.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        DateTime planstartTime = time1.setField(DateField.HOUR_OF_DAY, 0).setField(DateField.MINUTE, 0).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
        DateTime planendTime = DateUtil.endOfDay(time2).setField(DateField.MILLISECOND, 0);//.offset(DateField.MILLISECOND, -999);
        for (Long orgId : orgIdsByPlanListNew) {
            this.resumptionService.newbuild(orgId, ResumptionType.HALFYEAR, dateTime, true, appPlan, null, null, roleIds, planstartTime, planendTime);
        }
    }

    private void saveResumptionByYear(List<Long> orgIdsByPlanListNew, AppPlan appPlan, List<Long> roleIds, DateTime dateTime) {
        DateTime time1 = new DateTime(dateTime);
        time1.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        DateTime time2 = new DateTime(DateHelper.getLastDayOfYear(DateUtil.year(dateTime)));
        time2.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        DateTime planstartTime = time1.setField(DateField.HOUR_OF_DAY, 0).setField(DateField.MINUTE, 0).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
        DateTime planendTime = DateUtil.endOfDay(time2).setField(DateField.MILLISECOND, 0);
        for (Long orgId : orgIdsByPlanListNew) {
            this.resumptionService.newbuild(orgId, ResumptionType.YEAR, dateTime, true, appPlan, null, null, roleIds, planstartTime, planendTime);
        }
    }

    private void saveResumptionByHour(List<Long> orgIdsByPlanListNew, AppPlan appPlan, List<Long> roleIds, DateTime dateTime) {
        for (final Long orgId : orgIdsByPlanListNew) {
            Ymd ymd=toYmd(dateTime,"DAY");
            ymd.setOrgId(orgId);
            ymd.setEnable(true);
            final SysWorkTime workTime = this.workTimeService.findWorkTimeByYmd(ymd).getData();
            if (workTime != null) {
                List<String[]> workTimes = new ArrayList<>();
                if (appPlan.getNotResumptionOnRest() != null && appPlan.getNotResumptionOnRest() == 1 &&
                        StringUtils.isNotEmpty(workTime.getNoonbreakStart()) && StringUtils.isNotEmpty(workTime.getNoonbreakEnd())) {
                    workTimes.add(new String[]{workTime.getOpenTime(), workTime.getNoonbreakStart()});
                    workTimes.add(new String[]{workTime.getNoonbreakEnd(), workTime.getCloseTime()});
                } else {
                    workTimes.add(new String[]{workTime.getOpenTime(), workTime.getCloseTime()});
                }
                for (int ti = 0; ti < workTimes.size(); ti++) {
                    String[] time = workTimes.get(ti);
                    String openStr = time[0];
                    String closeStr = time[1];
                    String[] openArr = openStr.split(":");
                    String[] closeArr = closeStr.split(":");
                        /*如果营业前是00：00-09：00，营业后是17：00-24：00，
                        当前每小时履职任务是10：00-16：00，少了09：00-10：00和16：00-17：00的任务，
                        建议这2个时间段也生成履职任务*/
                    int openHour = 0;
                    if (ti == 0) {
                        openHour = Integer.parseInt(openArr[0]) - 1;
                    } else {
                        openHour = Integer.parseInt(openArr[0]);
                    }

                    int openMinute = Integer.parseInt(openArr[1]);
                    int closeHour = Integer.parseInt(closeArr[0]);
                    int closeMinute = Integer.parseInt(closeArr[1]);
                    if (openMinute < closeMinute) {
                        closeHour += 1;
                    }
                    int len = closeHour - openHour;
                    if (len > 1) {
                        int i = ti == 0 ? 1 : 0;
                        for (; i < len; i++) {//为每个作息点生成履职任务
                            dateTime.setField(DateField.HOUR_OF_DAY, openHour + i);
                            dateTime.setField(DateField.MINUTE, openMinute);
                            //每个作息点的开始时间和结束时间,不能直接操作dateTime，后面的操作会覆盖前面的操作
                            DateTime time1 = new DateTime(dateTime);
                            time1.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                            DateTime time2 = new DateTime(dateTime);
                            time2.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                            DateTime planstartTime = time1.setField(DateField.HOUR_OF_DAY, openHour + i).setField(DateField.MINUTE, openMinute).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
                            DateTime planendTime = time2.setField(DateField.HOUR_OF_DAY, openHour + i + 1).setField(DateField.MINUTE, openMinute).setField(DateField.SECOND, 0).setField(DateField.MILLISECOND, 0);
                            resumptionService.newbuild(orgId, ResumptionType.HOUR, dateTime, true, appPlan, null, null, roleIds, planstartTime, planendTime);
                        }
                    }
                }


            } else {
//                RESUMPTIONLOG.error("{} 没有作息", ResumptionType.DAY.toYmd(dateTime));
            }
        }
    }

    private List<Long> getOrgIdsByPlanIds(AppPlan plan, List<Long> orgIds, List<Long> workOrgIds) {
        //获取计划关联的机构
        List<Long> orgIdsByPlans = getPlanOrgIds(plan);
        if (orgIdsByPlans.size() == 0) {
            throw new RuntimeException("计划未关联机构");
        }
        //去掉传过来的机构id中不在计划关联机构中的数据,,得到要生成任务的机构id
        List<Long> orgIdsByPlanListNew = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(orgIds)) {
            for (Long orgId : orgIds) {
                if (orgIdsByPlans.contains(orgId)) {
                    orgIdsByPlanListNew.add(orgId);
                }
            }
        } else {
            orgIdsByPlanListNew = orgIdsByPlans;
        }
        if (plan.getPlanCycle() == 0 || plan.getPlanCycle() == 6) {
            //如果是日计划或者小时计划，只生成有作息的机构的任务
            orgIdsByPlanListNew.retainAll(workOrgIds);
        }
        return orgIdsByPlanListNew;
    }

    private List<AppPlan> getAppPlanByPlanIds(List<Long> planIds) {
        List<AppPlan> appPlans = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(planIds)) {
            //获取计划
            appPlans = appPlanService.list((new QueryWrapper<AppPlan>()).lambda().in(AppPlan::getId, planIds).eq(AppPlan::getPlanStatus, "0"));
        } else {
            appPlans = appPlanService.list((new QueryWrapper<AppPlan>()).lambda().eq(AppPlan::getPlanStatus, "0"));
        }
        if (appPlans.size() == 0) {
            throw new RuntimeException("没有可用的计划");
        }
        return appPlans;
    }
}
