package com.zd.laboratory.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.zd.common.core.domain.R;
import com.zd.common.core.domain.per.PerPrefix;
import com.zd.common.core.exception.ServiceException;
import com.zd.common.core.utils.DateUtils;
import com.zd.common.core.utils.SecurityUtils;
import com.zd.common.core.utils.StringUtils;
import com.zd.common.datascope.annotation.DataScope;
import com.zd.common.security.utils.SaveUtil;
import com.zd.laboratory.domain.LabGradeManageRule;
import com.zd.laboratory.domain.LabGradeManageRuleUser;
import com.zd.laboratory.domain.LabMessageDynamic;
import com.zd.laboratory.domain.vo.LabManageWorkChartVo;
import com.zd.laboratory.mapper.*;
import com.zd.laboratory.mqtt.constants.MqttConstants;
import com.zd.laboratory.mqtt.entiy.MessageBody;
import com.zd.laboratory.mqtt.service.impl.CommonSend;
import com.zd.laboratory.service.ILabGradeManageRecordService;
import com.zd.laboratory.service.ILabSubjectService;
import com.zd.laboratory.utils.word.WordUtils;
import com.zd.system.api.RemoteDeptService;
import com.zd.system.api.domain.SysDept;
import com.zd.system.api.laboratory.domain.LabGradeManageRecord;
import com.zd.system.api.laboratory.domain.LabGradeManageRecordDetail;
import com.zd.system.api.laboratory.domain.LabMessageUser;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 管控执行记录Service业务层处理
 *
 * @author liubo
 * @date 2022-02-10
 */
@Service
public class LabGradeManageRecordServiceImpl implements ILabGradeManageRecordService {
    private static final Logger logger = LoggerFactory.getLogger(LabGradeManageRecordServiceImpl.class);
    @Autowired
    private LabGradeManageRecordMapper labGradeManageRecordMapper;
    @Autowired
    private LabGradeManageRecordDetailMapper labGradeManageRecordDetailMapper;
    @Autowired
    private LabGradeManageRuleMapper labGradeManageRuleMapper;
    @Autowired
    private LabGradeManageRuleUserMapper labGradeManageRuleUserMapper;
    @Autowired
    private LabGradeManageMapper labGradeManageMapper;
    @Autowired
    private LabSubjectAccessRecordMapper labSubjectAccessRecordMapper;
    @Autowired
    private LabSubjectMapper labSubjectMapper;
    @Autowired
    private ILabSubjectService labSubjectService;
    @Autowired
    private CommonSend commonSend;
    @Autowired
    private RemoteDeptService remoteDeptService;
    @Autowired
    private LabSecurityApplyMapper labSecurityApplyMapper;
    @Autowired
    private LabMessageDynamicMapper labMessageDynamicMapper;
    @Autowired
    private LabMessageUserMapper labMessageUserMapper;

    private String dateFormat = "M月d日";

    /**
     * 查询管控执行记录
     *
     * @param id 管控执行记录主键
     * @return 管控执行记录
     */
    @Override
    public LabGradeManageRecord selectLabGradeManageRecordById(Long id) {
        LabGradeManageRecord labGradeManageRecord = labGradeManageRecordMapper.selectLabGradeManageRecordById(id);

        labGradeManageRecord.setDetail(labGradeManageRecordDetailMapper.selectLabGradeManageRecordDetailByRecordId(id));
        // 列出规则制定的所有人员- 沙士比鸭
        if(labGradeManageRecord.getStatus() == 0){
            LabGradeManageRuleUser ruleUser = labGradeManageRuleUserMapper.selectLabGradeManageRuleUserById(labGradeManageRecord.getRuleUserId());
            if(StringUtils.isNull(ruleUser)){
                throw new ServiceException("管控工作已失效或被删除！",504);
            }
            List<Long> subIds = labGradeManageMapper.selectSubIdsByManageId(ruleUser.getGradeManageId());

            List<Long> users = new ArrayList<>();
            if(ruleUser.getType() == 3){
                users.addAll( Arrays.asList(ruleUser.getUserIds() .split(",")).stream().map(s -> (Long.parseLong(s.trim()))).collect(Collectors.toList()));
            }else if(ruleUser.getType() == 1){
                List<Map<String, Long>> datas = labSubjectMapper.selectLabAdminByIds(subIds);
                datas.forEach(d -> {
                    users.add(d.get("adminId"));
                });
            }else if(ruleUser.getType() == 2){
                List<Map<String, Long>> datas = labSubjectAccessRecordMapper.selectJoinUsers(subIds, ruleUser.getUpdateTime());
                datas.forEach(d -> {
                    users.add(d.get("userId"));
                });
            }else if(ruleUser.getType() == 4){
                List<Map<String, Long>> datas = labSecurityApplyMapper.selectApplyListBySubIds(subIds);
                datas.forEach(d -> {
                    users.add(d.get("userId"));
                });
            }
            if(users.size() > 0){
                labGradeManageRecord.setAllUserName(labGradeManageRuleUserMapper.selectUserNameByUserIds(users));
            }
        }

        return labGradeManageRecord;
    }

    /**
     * 查询管控执行记录列表
     *
     * @param labGradeManageRecord 管控执行记录
     * @return 管控执行记录
     */
    @Override
    @DataScope(deptAlias = "d" , userAlias = "u" , permi = PerPrefix.LABORATORY_GRADEMANAGERECORD)
    public List<LabGradeManageRecord> selectLabGradeManageRecordList(LabGradeManageRecord labGradeManageRecord) {
        return labGradeManageRecordMapper.selectLabGradeManageRecordList(labGradeManageRecord);
    }

    /**
     * 新增管控执行记录
     *
     * @param labGradeManageRecord 管控执行记录
     * @return 结果
     */
    @Override
    public LabGradeManageRecord insertLabGradeManageRecord(LabGradeManageRecord labGradeManageRecord) {
        //设置其他公共字段
        SaveUtil.setCommonAttr(labGradeManageRecord);

        // 管控规则ID
        labGradeManageRecord.getRuleId();
        LabGradeManageRule rule = labGradeManageRuleMapper.selectLabGradeManageRuledById(labGradeManageRecord.getRuleId());
        // 管控规则名称
        labGradeManageRecord.setRuleName(rule.getName());
        // 规则截止执行时间  需要冗余存储
        labGradeManageRecord.getEndDate();
        // 管控规则执行ID
        labGradeManageRecord.getRuleUserId();
        // 实验室ID
        labGradeManageRecord.getSubId();


        // 执行人身份暂不冗余存储
        labGradeManageRecord.setJoinUserId(SecurityUtils.getUserId());
        labGradeManageRecordMapper.insertLabGradeManageRecord(labGradeManageRecord);

        LabGradeManageRecordDetail labGradeManageRecordDetail = labGradeManageRecord.getDetail();
        SaveUtil.setCommonAttr(labGradeManageRecordDetail);
        labGradeManageRecordDetail.setManageRecordId(labGradeManageRecord.getId());

        labGradeManageRecordDetailMapper.insertLabGradeManageRecordDetail(labGradeManageRecordDetail);

        // 判断此人有没有已过期未完成的，没有则通知全部完成
        LabGradeManageRecord record = new LabGradeManageRecord();
        record.setJoinUserId(SecurityUtils.getUserId());
        record.setStatus(0);
        if(labGradeManageRecordMapper.selectLabGradeManageRecordList(record).size() == 0){
            // 1 新工作通知， 2 已过期工作通知， 21 关闭已过期通知
            commonSend.send(MqttConstants.LAB_MANAGE_WORK+SecurityUtils.getUserId(), new MessageBody("您已过期的管控工作已全部完成。", 21));
        }

        return labGradeManageRecord;
    }

    /**
     * 修改管控执行记录
     *
     * @param labGradeManageRecord 管控执行记录
     * @return 结果
     */
    @Override
    public int updateLabGradeManageRecord(LabGradeManageRecord labGradeManageRecord) {
        labGradeManageRecord.setUpdateTime(DateUtils.getNowDate());
        labGradeManageRecord.setUpdateBy(SecurityUtils.getUsername());
        return labGradeManageRecordMapper.updateLabGradeManageRecord(labGradeManageRecord);
    }

    /**
     * 批量删除管控执行记录
     *
     * @param ids 需要删除的管控执行记录主键
     * @return 结果
     */
    @Override
    public int deleteLabGradeManageRecordByIds(Long[] ids) {
        return labGradeManageRecordMapper.deleteLabGradeManageRecordByIds(ids);
    }

    /**
     * 删除管控执行记录信息
     *
     * @param id 管控执行记录主键
     * @return 结果
     */
    @Override
    public int deleteLabGradeManageRecordById(Long id) {
        return labGradeManageRecordMapper.deleteLabGradeManageRecordById(id);
    }

    /**
     * 定时任务分级管控工作过期记录 - 并排列下次工作计划
     */
    @Override
    @Transactional
    @Async("labExecutor") // 涉及执行流程比较繁琐
    public void workArrange() {

        List<LabGradeManageRuleUser> manageRuleUserList = labGradeManageRuleUserMapper.selectExpiredList();

        List<Long> ruleIds = manageRuleUserList.stream().map(LabGradeManageRuleUser::getGradeManageRuleId).collect(Collectors.toList());

        if(CollectionUtils.isNotEmpty(ruleIds)){

            List<LabGradeManageRecord> insertRecordList = new ArrayList<>();

            LabGradeManageRecord queryRecord;
            int executedCount = 0;
            for (LabGradeManageRuleUser ruleUser : manageRuleUserList) {

                queryRecord = new LabGradeManageRecord();
                queryRecord.setRuleId(ruleUser.getGradeManageRuleId());
                queryRecord.setRuleUserId(ruleUser.getId());
                queryRecord.setCycleCount(ruleUser.getCycleCount());

                // 2.7 获取实验室方式变动- 此处要修改
                //LabGradeManage manage = labGradeManageMapper.selectLabGradeManageById(ruleUser.getGradeManageId());
                List<Long> subIds = labGradeManageMapper.selectSubIdsByManageId(ruleUser.getGradeManageId());
                if(subIds.size() == 0){
                    continue;
                }
                for (Long subId : subIds) {
                    if(ruleUser.getIsAll() == 0){
                        queryRecord.setSubId(subId);
                        // 单人执行，有一个人执行，则其他人都不生成过期数据
                        executedCount = labGradeManageRecordMapper.selectCountByUserRecord(queryRecord);
                        if(executedCount > 0){
                            continue;
                        }
                    }
                }

                //List<Long> users = new ArrayList<>();

//                String userPosition = null;
                if(ruleUser.getType() == 3){
                    List<Long> users = Arrays.asList(ruleUser.getUserIds() .split(",")).stream().map(s -> (Long.parseLong(s.trim()))).collect(Collectors.toList());

                    // 多个实验室则需要生成多条工作 - 过期未执行记录
                    for (Long subId : subIds) {
                        queryRecord.setSubId(subId);
                        for (Long userId : users) {
//                            queryRecord.setJoinUserId(userId);
//                            executedCount = labGradeManageRecordMapper.selectCountByUserRecord(queryRecord);
//                            if(executedCount > 0){
//                                continue;
//                            }

                            putUserData(ruleUser, subId, userId, insertRecordList, "选择人员");

//                            LabGradeManageRecord labGradeManageRecord = new LabGradeManageRecord();
//                            labGradeManageRecord.setCreateTime(DateUtils.getNowDate());
//                            labGradeManageRecord.setUserId(-1L);
//                            labGradeManageRecord.setCreateBy("-1");
//                            labGradeManageRecord.setRuleId(ruleUser.getGradeManageRuleId());
//                            labGradeManageRecord.setRuleUserId(ruleUser.getId());
//                            labGradeManageRecord.setJoinUserId(userId);
//                            labGradeManageRecord.setSubId(subId);
//                            // 未执行
//                            labGradeManageRecord.setStatus(0);
//                            labGradeManageRecord.setUserPosition(userPosition);
//                            labGradeManageRecord.setCycleCount(ruleUser.getCycleCount());
//                            labGradeManageRecord.setRuleType(ruleUser.getRuleType());
//                            labGradeManageRecord.setRuleName(ruleUser.getRuleName());
//                            labGradeManageRecord.setEndDate(ruleUser.getEndDate());
//
//                            insertRecordList.add(labGradeManageRecord);
                        }
                    }
                }else if(ruleUser.getType() == 1){
                    // 查询实验室负责人
                    // users = labSubjectMapper.selectAdminIds(subIds);
                    List<Map<String, Long>> datas = labSubjectMapper.selectLabAdminByIds(subIds);
                    subIds.forEach(s -> {
                        datas.forEach(d -> {
                            // adminId, id as subId
                            if(s.equals(d.get("subId")) && d.get("adminId") != null){
                                putUserData(ruleUser, d.get("subId"), d.get("adminId"), insertRecordList, "实验室负责人");
//                                LabGradeManageRecord labGradeManageRecord = new LabGradeManageRecord();
//                                labGradeManageRecord.setCreateTime(DateUtils.getNowDate());
//                                labGradeManageRecord.setUserId(-1L);
//                                labGradeManageRecord.setCreateBy("-1");
//                                labGradeManageRecord.setRuleId(ruleUser.getGradeManageRuleId());
//                                labGradeManageRecord.setRuleUserId(ruleUser.getId());
//                                labGradeManageRecord.setJoinUserId(d.get("adminId"));
//                                labGradeManageRecord.setSubId(s);
//                                // 未执行
//                                labGradeManageRecord.setStatus(0);
//                                labGradeManageRecord.setUserPosition("实验室负责人");
//                                labGradeManageRecord.setCycleCount(c);
//                                labGradeManageRecord.setRuleType(ruleUser.getRuleType());
//                                labGradeManageRecord.setRuleName(ruleUser.getRuleName());
//                                labGradeManageRecord.setEndDate(ruleUser.getEndDate());
//
//                                insertRecordList.add(labGradeManageRecord);
                            }
                        });
                    });
                }else if(ruleUser.getType() == 2){
                    // 当天进入实验室人员
                    List<Map<String, Long>> datas = labSubjectAccessRecordMapper.selectJoinUsers(subIds, ruleUser.getUpdateTime());
                    subIds.forEach(s -> {
                        datas.forEach(d -> {
                            //  userId, subject_id as subId
                            if(s.equals(d.get("subId")) && d.get("userId") != null){
                                putUserData(ruleUser,d.get("subId"), d.get("userId"), insertRecordList, "当天进入实验室人员");
//                                LabGradeManageRecord labGradeManageRecord = new LabGradeManageRecord();
//                                labGradeManageRecord.setCreateTime(DateUtils.getNowDate());
//                                labGradeManageRecord.setUserId(-1L);
//                                labGradeManageRecord.setCreateBy("-1");
//                                labGradeManageRecord.setRuleId(ruleUser.getGradeManageRuleId());
//                                labGradeManageRecord.setRuleUserId(ruleUser.getId());
//                                labGradeManageRecord.setJoinUserId(d.get("userId"));
//                                labGradeManageRecord.setSubId(s);
//                                // 未执行
//                                labGradeManageRecord.setStatus(0);
//                                labGradeManageRecord.setUserPosition("当天进入实验室人员");
//                                labGradeManageRecord.setCycleCount(c);
//                                labGradeManageRecord.setRuleType(ruleUser.getRuleType());
//                                labGradeManageRecord.setRuleName(ruleUser.getRuleName());
//                                labGradeManageRecord.setEndDate(ruleUser.getEndDate());
//
//                                insertRecordList.add(labGradeManageRecord);
                            }
                        });
                    });
                }else if(ruleUser.getType() == 4){
                    // 实验室准入人员
                    List<Map<String, Long>> datas = labSecurityApplyMapper.selectApplyListBySubIds(subIds);
                    subIds.forEach(s -> {
                        datas.forEach(d -> {
                            //  userId, subject_id as subId
                            if(s.equals(d.get("subId")) && d.get("userId") != null){
                                putUserData(ruleUser, d.get("subId"), d.get("userId"), insertRecordList, "实验室准入人员");
//                                LabGradeManageRecord labGradeManageRecord = new LabGradeManageRecord();
//                                labGradeManageRecord.setCreateTime(DateUtils.getNowDate());
//                                labGradeManageRecord.setUserId(-1L);
//                                labGradeManageRecord.setCreateBy("-1");
//                                labGradeManageRecord.setRuleId(ruleUser.getGradeManageRuleId());
//                                labGradeManageRecord.setRuleUserId(ruleUser.getId());
//                                labGradeManageRecord.setJoinUserId(d.get("userId"));
//                                labGradeManageRecord.setSubId(s);
//                                // 未执行
//                                labGradeManageRecord.setStatus(0);
//                                labGradeManageRecord.setUserPosition("实验室准入人员");
//                                labGradeManageRecord.setCycleCount(c);
//                                labGradeManageRecord.setRuleType(ruleUser.getRuleType());
//                                labGradeManageRecord.setRuleName(ruleUser.getRuleName());
//                                labGradeManageRecord.setEndDate(ruleUser.getEndDate());
//
//                                insertRecordList.add(labGradeManageRecord);
                            }
                        });
                    });
                }else {
                    logger.error("workArrange: 分级管控周期工作编排数据异常, {}", JSONUtil.toJsonStr(ruleUser));
                    continue;
                }

                /*List<LabGradeManageRecord> recordList = labGradeManageRecordMapper.selectByRuleIds(ruleIds);
                for (LabGradeManageRecord record : recordList) {
                    // 还需要知道工作执行到哪个周期了
                    if(ruleUser.getGradeManageRuleId().equals(record.getRuleId())
                            && users.contains(record.getJoinUserId())
                            && cycleCount == record.getCycleCount()){
                        users.remove(record.getJoinUserId());
                    }
                }*/
            }

            if(insertRecordList.size() > 0){
                // 批量存储
                labGradeManageRecordMapper.insertBatch(insertRecordList);
            }


            /*List<LabGradeManageRecord> expiredList = labGradeManageRecordMapper.selectExpired();
            if(expiredList.size() > 0){
                Map<Long, List<LabGradeManageRecord>> map = expiredList.stream().collect(Collectors.groupingBy(LabGradeManageRecord::getJoinUserId));

                map.forEach((k,v) -> {
                    commonSend.send(MqttConstants.LAB_MANAGE_WORK+k, new MessageBody("您有" + v.size() + "条管控工作过期未完成，请尽快完成。", 2));
                });
            }*/

            //即将过期提醒 - 前十个小时(更改为工作产生进行通知：见 @link insertLabGradeManageRuled)

            // 周期结束 变更为下个周期
            // 记录周期执行次数
            labGradeManageRuleUserMapper.updateByCycle(manageRuleUserList.stream().map(LabGradeManageRuleUser::getId).collect(Collectors.toList()));
        }
    }

    private void putUserData(LabGradeManageRuleUser ruleUser, @NotNull Long subId, @NotNull Long userId,
                             List<LabGradeManageRecord> insertRecordList, String userPosition){
        LabGradeManageRecord queryRecord = new LabGradeManageRecord();
        queryRecord.setRuleId(ruleUser.getGradeManageRuleId());
        queryRecord.setRuleUserId(ruleUser.getId());
        queryRecord.setCycleCount(ruleUser.getCycleCount());
        queryRecord.setSubId(subId);
        queryRecord.setJoinUserId(userId);
        if(labGradeManageRecordMapper.selectCountByUserRecord(queryRecord) > 0){
            return;
        }
        LabGradeManageRecord labGradeManageRecord = new LabGradeManageRecord();
        labGradeManageRecord.setCreateTime(DateUtils.getNowDate());
        labGradeManageRecord.setUserId(-1L);
        labGradeManageRecord.setCreateBy("-1");
        labGradeManageRecord.setRuleId(ruleUser.getGradeManageRuleId());
        labGradeManageRecord.setRuleUserId(ruleUser.getId());
        labGradeManageRecord.setJoinUserId(userId);
        labGradeManageRecord.setSubId(subId);
        // 未执行
        labGradeManageRecord.setStatus(0);
        labGradeManageRecord.setUserPosition(userPosition);
        labGradeManageRecord.setCycleCount(ruleUser.getCycleCount());
        labGradeManageRecord.setRuleType(ruleUser.getRuleType());
        labGradeManageRecord.setRuleName(ruleUser.getRuleName());
        labGradeManageRecord.setEndDate(ruleUser.getEndDate());

        insertRecordList.add(labGradeManageRecord);
    }


    /**
     * 1.逾期第二天早8点通知执行人和规则制定人
     */
    @Override
    @Transactional
    public void workOverdue() {
        LabGradeManageRecord labGradeManageRecord = new LabGradeManageRecord();
        labGradeManageRecord.setStatus(0);
        labGradeManageRecord.setStartTime(DateUtil.offsetDay(DateUtil.date(), -1));
        labGradeManageRecord.setEndTime(DateUtil.offsetDay(DateUtil.date(), -1));
        List<LabGradeManageRecord> manageRecords = labGradeManageRecordMapper.selectLabGradeManageRecordList(labGradeManageRecord);

        List<LabMessageUser> messageUsers = new ArrayList<>();
        manageRecords.forEach(record -> {

            LabMessageDynamic labMessageDynamic = new LabMessageDynamic();
            labMessageDynamic.setSendRange(3);
            labMessageDynamic.setMessClass(4);
            labMessageDynamic.setCreateTime(DateUtils.getNowDate());
            labMessageDynamic.setContent(record.getRuleName());
            labMessageDynamic.setDynamicId(record.getId());
            labMessageDynamic.setRemark("分级管控逾期通知");
            labMessageDynamicMapper.insertLabMessageDynamic(labMessageDynamic);

            // 通知到执行人
            LabMessageUser labMessageUser = new LabMessageUser();
            labMessageUser.setJoinUserId(record.getJoinUserId());
            labMessageUser.setCreateTime(DateUtils.getNowDate());
            labMessageUser.setIsRead(false);
            labMessageUser.setMessageId(labMessageDynamic.getId());
            messageUsers.add(labMessageUser);

            // 通知到制定人
            labMessageUser = new LabMessageUser();
            labMessageUser.setJoinUserId(record.getManageUserId());
            labMessageUser.setCreateTime(DateUtils.getNowDate());
            labMessageUser.setIsRead(false);
            labMessageUser.setMessageId(labMessageDynamic.getId());
            messageUsers.add(labMessageUser);
        });

        if(manageRecords.size() > 0){
            labMessageUserMapper.insertLabMessageUserBatch(messageUsers);
        }else {
            throw new ServiceException("消息通知未匹配到关联人员，事务回滚");
        }
    }

    /**
     * 1.执行通知：天，下午7点
     */
    @Override
    @Transactional
    public void workExecuteByDay(String cycle) {
        LabGradeManageRuleUser labGradeManageRuleUser = new LabGradeManageRuleUser();
        labGradeManageRuleUser.setCycle(cycle);
        List<LabGradeManageRuleUser> ruleUsers = labGradeManageRuleUserMapper.selectWorkExecuteByDay(labGradeManageRuleUser);

        List<LabMessageUser> messageUsers = new ArrayList<>();
        for (LabGradeManageRuleUser ruleUser : ruleUsers) {
            LabMessageDynamic labMessageDynamic = new LabMessageDynamic();
            labMessageDynamic.setSendRange(3);
            labMessageDynamic.setMessClass(5);
            labMessageDynamic.setCreateTime(DateUtils.getNowDate());
            labMessageDynamic.setContent(ruleUser.getRuleName());
            labMessageDynamic.setDynamicId(ruleUser.getId());
            labMessageDynamic.setRemark("分级管控执行通知");

            labMessageDynamicMapper.insertLabMessageDynamic(labMessageDynamic);

            // 保存参数，用作消息调整处理调用
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("ruleId", ruleUser.getGradeManageRuleId());
            jsonObject.put("ruleUserId", ruleUser.getId());
            jsonObject.put("isUpload", ruleUser.getIsUpload());
            jsonObject.put("endDate", ruleUser.getEndDate());

            // 查询哪些人需要通知
            List<Long> subIds = labGradeManageMapper.selectSubIdsByManageId(ruleUser.getGradeManageId());
            if(ruleUser.getType() == 3){
                List<Long> users = Arrays.asList(ruleUser.getUserIds() .split(",")).stream().map(s -> (Long.parseLong(s.trim()))).collect(Collectors.toList());

                subIds.forEach(s -> {
                    users.forEach(u -> {
                        int count = labGradeManageRecordMapper.selectExecutionsByUserId(u, 2, s, ruleUser.getId());
                        if(count == 0){
                            LabMessageUser labMessageUser = new LabMessageUser();
                            labMessageUser.setJoinUserId(u);
                            labMessageUser.setCreateTime(DateUtils.getNowDate());
                            labMessageUser.setIsRead(false);
                            labMessageUser.setMessageId(labMessageDynamic.getId());

                            jsonObject.put("subId", s);
                            labMessageUser.setMeaasgeContext(jsonObject.toJSONString());
                            messageUsers.add(labMessageUser);
                        }
                    });
                });
            }else if(ruleUser.getType() == 1){
                // 查询实验室负责人
                List<Map<String, Long>> datas = labSubjectMapper.selectLabAdminByIds(subIds);
                subIds.forEach(s -> {
                    datas.forEach(d -> {
                        if(s.equals(d.get("subId")) && d.get("adminId") != null){
                            int count = labGradeManageRecordMapper.selectExecutionsByUserId(d.get("adminId"), 2, d.get("subId"), ruleUser.getId());
                            if(count == 0){
                                LabMessageUser labMessageUser = new LabMessageUser();
                                labMessageUser.setJoinUserId(d.get("adminId"));
                                labMessageUser.setCreateTime(DateUtils.getNowDate());
                                labMessageUser.setIsRead(false);
                                jsonObject.put("subId", s);
                                labMessageUser.setMeaasgeContext(jsonObject.toJSONString());
                                labMessageUser.setMessageId(labMessageDynamic.getId());
                                messageUsers.add(labMessageUser);
                            }
                        }
                    });
                });
            }else if(ruleUser.getType() == 2){
                // 当天进入实验室人员
                List<Map<String, Long>> datas = labSubjectAccessRecordMapper.selectJoinUsers(subIds, ruleUser.getUpdateTime());
                subIds.forEach(s -> {
                    datas.forEach(d -> {
                        if(s.equals(d.get("subId")) && d.get("userId") != null){
                            int count = labGradeManageRecordMapper.selectExecutionsByUserId(d.get("userId"), 2, s, ruleUser.getId());
                            if(count == 0){
                                LabMessageUser labMessageUser = new LabMessageUser();
                                labMessageUser.setJoinUserId(d.get("userId"));
                                labMessageUser.setCreateTime(DateUtils.getNowDate());
                                labMessageUser.setIsRead(false);
                                jsonObject.put("subId", s);
                                labMessageUser.setMeaasgeContext(jsonObject.toJSONString());
                                labMessageUser.setMessageId(labMessageDynamic.getId());
                                messageUsers.add(labMessageUser);
                            }
                        }
                    });
                });
            }else if(ruleUser.getType() == 4){
                // 实验室准入人员
                List<Map<String, Long>> datas = labSecurityApplyMapper.selectApplyListBySubIds(subIds);
                subIds.forEach(s -> {
                    datas.forEach(d -> {
                        if(s.equals(d.get("subId")) && d.get("userId") != null){
                            int count = labGradeManageRecordMapper.selectExecutionsByUserId(d.get("userId"), 2, s, ruleUser.getId());
                            if(count == 0){
                                LabMessageUser labMessageUser = new LabMessageUser();
                                labMessageUser.setJoinUserId(d.get("userId"));
                                labMessageUser.setCreateTime(DateUtils.getNowDate());
                                labMessageUser.setIsRead(false);
                                jsonObject.put("subId", s);
                                labMessageUser.setMeaasgeContext(jsonObject.toJSONString());
                                labMessageUser.setMessageId(labMessageDynamic.getId());
                                messageUsers.add(labMessageUser);
                            }
                        }
                    });
                });
            }
        }

        if(messageUsers.size() > 0){
            labMessageUserMapper.insertLabMessageUserBatch(messageUsers);
        }else {
            throw new ServiceException("消息通知未匹配到关联人员，事务回滚");
        }
    }

    /**
     *  分级管控通知类型（执行人-可跳转处理）
     *  2.执行通知：周，每周五早8点
     *  3.执行周期：月，提前三天早8点
     *  4.执行周期：年，季度，半年，提前一周早8点，提前三天早8点 各一次
     */
    @Override
    public void workExecute() {

        if(DateUtil.dayOfWeek(DateUtil.date()) == 6){
            workExecuteByDay("一周");
        }

        if(DateUtil.dayOfMonth(DateUtil.endOfMonth(DateUtil.date())) - DateUtil.dayOfMonth(DateUtil.date()) == 2){
            workExecuteByDay("一月");
        }

        if(DateUtil.month(DateUtil.endOfQuarter(DateUtil.date())) == DateUtil.month(DateUtil.date()) && (
                DateUtil.dayOfMonth(DateUtil.endOfMonth(DateUtil.date())) - DateUtil.dayOfMonth(DateUtil.date()) == 2 ||
                DateUtil.dayOfMonth(DateUtil.endOfMonth(DateUtil.date())) - DateUtil.dayOfMonth(DateUtil.date()) == 6
        )){
            workExecuteByDay("季度");
        }

        if((DateUtil.thisMonth() == 6 || DateUtil.thisMonth() == 12) && (
                DateUtil.dayOfMonth(DateUtil.endOfMonth(DateUtil.date())) - DateUtil.dayOfMonth(DateUtil.date()) == 2 ||
                DateUtil.dayOfMonth(DateUtil.endOfMonth(DateUtil.date())) - DateUtil.dayOfMonth(DateUtil.date()) == 6
        )){
            workExecuteByDay("半年");
        }

        if(DateUtil.thisMonth() == 12 && (
                DateUtil.dayOfMonth(DateUtil.endOfMonth(DateUtil.date())) - DateUtil.dayOfMonth(DateUtil.date()) == 2 ||
                DateUtil.dayOfMonth(DateUtil.endOfMonth(DateUtil.date())) - DateUtil.dayOfMonth(DateUtil.date()) == 6
        )){
            workExecuteByDay("一年");
        }

    }

    /**
     * 当天进入实验室人员管控工作消息通知
     */
    @Override
    public void sendManageMsgBySiginUser(Long userId, Long subId) {

        try {
            logger.info("进入实验室人员进行消息通知执行..." + subId + " : "+ userId);
            List<LabGradeManageRuleUser> manageRuleUserList = labGradeManageRuleUserMapper.selectType2ByAdminSubId(subId);
            if(manageRuleUserList.size() > 0){
                commonSend.send(MqttConstants.LAB_MANAGE_WORK+userId, new MessageBody("您当前有" + manageRuleUserList.size() + "条管控工作需完成，请点击查看详情。", 1));
                logger.info("已执行发送...");
            }
        }catch (Exception e){
            logger.error("进入实验室人员管控工作通知异常，{}", e.getMessage());
        }
    }

    /**
     * 分级管控统计 大屏首页本周数据2.4需求
     */
    @Override
    public Map<String, Object> queryManageWorkInfo(LabManageWorkChartVo labManageWorkChartVo) {
        labManageWorkChartVo.setStartTime(DateUtil.beginOfWeek(DateUtils.getNowDate()));
        labManageWorkChartVo.setEndTime( DateUtil.offsetDay(labManageWorkChartVo.getStartTime(), 4));

        labManageWorkChartVo.setTitle(
                DateUtil.format(labManageWorkChartVo.getStartTime(), dateFormat) + "至" + DateUtil.format(labManageWorkChartVo.getEndTime(), dateFormat) +
                "分级管控工作");
        Map<String, Object> map = new HashMap<>();
        map.put("title", labManageWorkChartVo.getTitle());

        List<LabManageWorkChartVo> list;

        if(labManageWorkChartVo.getType() == 1){
            list = new ArrayList<>();
            R r = remoteDeptService.getDeptList(new SysDept());
            List<SysDept> deptList = (List<SysDept>) r.getData();

            LabManageWorkChartVo workChartVo ;
            if(deptList.size() > 0){
                for (SysDept dept : deptList) {
                    if(labManageWorkChartVo.getDeptId() == null || (labManageWorkChartVo.getDeptId() != null && dept.getDeptId().equals(labManageWorkChartVo.getDeptId()))){
                        workChartVo = new LabManageWorkChartVo();

                        workChartVo.setDeptId(dept.getDeptId());
                        workChartVo.setDeptName(dept.getDeptName());

                        // 选择人员的工作统计
                        workChartVo.setPlanNum(labGradeManageRecordMapper.selectPlanNumByDeptId(dept.getDeptId()));

                        workChartVo.setFinishedNum(labGradeManageRecordMapper.selectFinishedNum(dept.getDeptId()));

                        workChartVo.setRateNum(workChartVo.getPlanNum() == 0 ? 0 :
                                (int) (BigDecimal.valueOf(workChartVo.getFinishedNum() * 100).divide(BigDecimal.valueOf(workChartVo.getPlanNum()), BigDecimal.ROUND_DOWN).doubleValue()));

                        list.add(workChartVo);
                    }
                }
            }
        }else {
            list = labGradeManageRecordMapper.queryManageWorkChartDetailsType2(labManageWorkChartVo);
            for (LabManageWorkChartVo workChartVo : list) {

                labManageWorkChartVo.setSubId(workChartVo.getSubId());
                // 选择人员的工作统计
                workChartVo.setPlanNum(labGradeManageRecordMapper.selectPlanNum(labManageWorkChartVo));

                workChartVo.setFinishedNum(labGradeManageRecordMapper.selectFinishedNumBySubId(labManageWorkChartVo));

                workChartVo.setRateNum(workChartVo.getPlanNum() == 0 ? 0 :
                        (int) (BigDecimal.valueOf(workChartVo.getFinishedNum() * 100).divide(BigDecimal.valueOf(workChartVo.getPlanNum()), BigDecimal.ROUND_DOWN).doubleValue()));
            }

            list = list.stream().sorted(Comparator.comparing(LabManageWorkChartVo::getPlanNum).reversed()).collect(Collectors.toList());
        }

        map.put("list", list);

        return map;
    }

    /**
     * 分级管控统计 柱状图2.4需求
     * @return
     */
    @Override
    @DataScope(deptAlias = "s")
    public List<List<Object>> queryManageWorkCharts(LabManageWorkChartVo labManageWorkChartVo) {
        labManageWorkChartVo.setStartTime(DateUtil.beginOfWeek(DateUtils.getNowDate()));
        labManageWorkChartVo.setEndTime(DateUtil.offsetDay(labManageWorkChartVo.getStartTime(), 4));


        List<LabManageWorkChartVo> list = new ArrayList<>();
        LabManageWorkChartVo chart = new LabManageWorkChartVo();
        chart.setCurrentDate(labManageWorkChartVo.getStartTime());
        list.add(chart);

        chart = new LabManageWorkChartVo();
        chart.setCurrentDate(DateUtil.offsetDay(labManageWorkChartVo.getStartTime(), 1));
        list.add(chart);

        chart = new LabManageWorkChartVo();
        chart.setCurrentDate(DateUtil.offsetDay(labManageWorkChartVo.getStartTime(), 2));
        list.add(chart);

        chart = new LabManageWorkChartVo();
        chart.setCurrentDate(DateUtil.offsetDay(labManageWorkChartVo.getStartTime(), 3));
        list.add(chart);

        chart = new LabManageWorkChartVo();
        chart.setCurrentDate(DateUtil.offsetDay(labManageWorkChartVo.getStartTime(), 4));
        list.add(chart);


        List<LabManageWorkChartVo> dates = labGradeManageRecordMapper.queryManageWorkCharts(labManageWorkChartVo);

        Date now = DateUtils.getNowDate();
        for (int i = 0; i < list.size(); i++) {
            chart = list.get(i);

            chart.setParams(labManageWorkChartVo.getParams());

            chart.setCurrentDateStr( DateUtil.format(chart.getCurrentDate(), dateFormat));
            chart.setOfWeek("星期" + WordUtils.CN_NUM[(DateUtil.dayOfWeek(chart.getCurrentDate()) -2)]);


            int compare = DateUtil.compare(chart.getCurrentDate(), now);
            for (LabManageWorkChartVo date : dates) {
                if(i == 0){
                    if(date.getCurrentDate().equals(chart.getCurrentDate())){
                        if("一天".equals(date.getCycle())){
                            chart.setPlanNum(date.getPlanNum());
                        }
                        break;
                    }

                }else if(i == 1){
                    if(date.getCurrentDate().equals(chart.getCurrentDate())){
                        if("一天".equals(date.getCycle())){
                            chart.setPlanNum(date.getPlanNum() + list.get(i-1).getPlanNum());
                        }
                        break;
                    }
                }else if(i == 2){
                    if(date.getCurrentDate().equals(chart.getCurrentDate())){
                        if("一天".equals(date.getCycle())){
                            chart.setPlanNum(date.getPlanNum() + list.get(i-1).getPlanNum());
                        }
                        break;
                    }
                }else if(i == 3){
                    if("一天".equals(date.getCycle()) && date.getCurrentDate().equals(chart.getCurrentDate())){
                        chart.setPlanNum(date.getPlanNum() + list.get(i-1).getPlanNum());
                    }
                    break;
                }else if(i == 4){
                    if(date.getCurrentDate().equals(chart.getCurrentDate())){
                        if("一天".equals(date.getCycle())){
                            chart.setPlanNum(date.getPlanNum() + list.get(i-1).getPlanNum());
                        }
                        break;
                    }
                    if("一周".equals(date.getCycle())){
                        chart.setPlanNum(date.getPlanNum() + chart.getPlanNum());
                    }
                }
            }

            // 如果今天大于这天， 查询的计划数量永远是0 需要查询记录中已执行和未执行的总和
            if(compare < 0){
                chart.setPlanNum(chart.getPlanNum() + labGradeManageRecordMapper.selectAllWorkCountByDate(chart));
            }

            chart.setFinishedNum(labGradeManageRecordMapper.selectFinishedByDate(chart));

            chart.setRateNum(chart.getPlanNum() == 0 ? 0 :
                    (int) (BigDecimal.valueOf(chart.getFinishedNum() * 100).divide(BigDecimal.valueOf(chart.getPlanNum()), BigDecimal.ROUND_DOWN).doubleValue()));
        }

        List<List<Object>> datas = new ArrayList<>();
        List<Object> data ;
        for (LabManageWorkChartVo workChartVo : list) {
            data = new ArrayList<>();
            data.add(workChartVo.getOfWeek()+" - " + workChartVo.getCurrentDateStr());
            data.add(workChartVo.getPlanNum());
            data.add(workChartVo.getFinishedNum());

            datas.add(data);
        }
        return datas;
    }

    /**
     * 分级管控统计 详情页列表2.4需求
     * @return
     */
    @Override
    public List<LabManageWorkChartVo> queryManageWorkChartDetails(LabManageWorkChartVo labManageWorkChartVo) {

        List<LabManageWorkChartVo> list = new ArrayList<>();
        if(labManageWorkChartVo.getType() == 1){
            R r = remoteDeptService.getDeptList(new SysDept());
            List<SysDept> deptList = (List<SysDept>) r.getData();

            LabManageWorkChartVo workChartVo ;
            if(deptList.size() > 0){
                for (SysDept dept : deptList) {
                    if(labManageWorkChartVo.getDeptId() == null || (labManageWorkChartVo.getDeptId() != null && dept.getDeptId().equals(labManageWorkChartVo.getDeptId()))){
                        workChartVo = new LabManageWorkChartVo();

                        workChartVo.setDeptId(dept.getDeptId());
                        workChartVo.setDeptName(dept.getDeptName());

                        // 选择人员的工作统计
                        workChartVo.setPlanNum(labGradeManageRecordMapper.selectPlanNumByDeptId(dept.getDeptId()));

                        workChartVo.setFinishedNum(labGradeManageRecordMapper.selectFinishedNum(dept.getDeptId()));

                        workChartVo.setRateNum(workChartVo.getPlanNum() == 0 ? 0 :
                                (int) (BigDecimal.valueOf(workChartVo.getFinishedNum() * 100).divide(BigDecimal.valueOf(workChartVo.getPlanNum()), BigDecimal.ROUND_DOWN).doubleValue()));

                        list.add(workChartVo);
                    }
                }
            }
        }else {
            list = labGradeManageRecordMapper.queryManageWorkChartDetailsType2(labManageWorkChartVo);

            for (LabManageWorkChartVo workChartVo : list) {

                // 选择人员的工作统计
                workChartVo.setPlanNum(labGradeManageRecordMapper.selectPlanNum(workChartVo));

                workChartVo.setFinishedNum(labGradeManageRecordMapper.selectFinishedNumBySubId(workChartVo));

                workChartVo.setRateNum(workChartVo.getPlanNum() == 0 ? 0 :
                        (int) (BigDecimal.valueOf(workChartVo.getFinishedNum() * 100).divide(BigDecimal.valueOf(workChartVo.getPlanNum()), BigDecimal.ROUND_DOWN).doubleValue()));
            }
        }

        return list;
    }

}
