/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.security.trans.task.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.security.common.Constant;
import org.security.common.util.DeadlineUtil;
import org.security.flow.core.constant.ProcessConstant;
import org.security.flow.core.entity.BladeFlow;
import org.security.flow.core.entity.BladeFlowDef;
import org.security.flow.core.feign.IFlowClient;
import org.security.flow.core.utils.FlowUtil;
import org.security.ht.vo.common.UploadVO;
import org.security.system.feign.ISysClient;
import org.security.trans.app.vo.BacklogVO;
import org.security.ht.entity.basic.Department;
import org.security.trans.assessment.entity.Assessment;
import org.security.trans.basic.service.IDepartmentService;
import org.security.trans.common.service.IFileService;
import org.security.trans.dailyDuties.entity.Inspection;
import org.security.trans.dailyDuties.entity.InspectionLine;
import org.security.trans.dailyDuties.service.IInspectionService;
import org.security.trans.dataStatistics.dto.EduAndDrillDataDTO;
import org.security.trans.dataStatistics.vo.EduAndDrillDataVO;
import org.security.trans.prevent.dto.PreventMaterialDTO;
import org.security.trans.prevent.entity.PreventMaterial;
import org.security.trans.prevent.service.IPreventMaterialService;
import org.security.trans.securityCommandCenter.entity.SccAlarmPush;
import org.security.trans.securityCommandCenter.entity.SccUnlocaleCheck;
import org.security.trans.securityCommandCenter.entity.SccUnlocaleCheckLine;
import org.security.trans.task.dto.TaskDTO;
import org.security.trans.task.dto.TaskHandinDTO;
import org.security.trans.task.entity.Task;
import org.security.trans.task.entity.TaskHandin;
import org.security.trans.task.mapper.TaskHandinMapper;
import org.security.trans.task.service.ITaskHandinService;
import org.security.trans.task.service.ITaskService;
import org.security.trans.task.vo.TaskHandinVO;
import org.security.trans.task.vo.TaskTodoVO;
import org.security.trans.taskCheck.task.dto.TaskHandinCheckDTO;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.support.Kv;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.Func;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static org.security.common.Constant.*;

/**
 * 任务-任务提报 服务实现类
 *
 * @author BladeX
 * @since 2022-03-14
 */
@Service
@Slf4j
@AllArgsConstructor
public class TaskHandinServiceImpl extends ServiceImpl<TaskHandinMapper, TaskHandin> implements ITaskHandinService {

	private final IDepartmentService departmentService;

	private final ITaskService taskService;

	private final IInspectionService inspectionService;

	private final IPreventMaterialService preventMaterialService;

	private final IFileService fileService;

	private final IFlowClient flowClient;

	private final ISysClient sysClient;

	@Override
	public IPage<TaskHandinVO> selectTaskHandinPage(IPage<TaskHandinVO> page, TaskHandinDTO taskHandinDTO) {
		String user = String.valueOf(AuthUtil.getUserId());
		log.info("=======当前登录人userID：{}======", user);
		List<TaskHandin> taskHandinList = baseMapper.selectTaskHandinPage(page, taskHandinDTO);
		List<TaskHandinVO> taskHandinVOList = new ArrayList<>();
		taskHandinList.forEach(tsh -> {
			TaskHandinVO taskHandinVO = Func.copy(tsh, TaskHandinVO.class);
			assert taskHandinVO != null;
			//	若关联任务，赋值任务名称
			if (Func.isNotBlank(tsh.getTaskId())) {
				Task task = taskService.getOne(new QueryWrapper<Task>().lambda().eq(Task::getId, tsh.getTaskId()));
				taskHandinVO.setTaskName(task.getName());
			}
			taskHandinVOList.add(taskHandinVO);
		});
		return page.setRecords(taskHandinVOList);
	}

	@Override
	public TaskHandinVO getDetail(BigDecimal id) {
		TaskHandin detail = super.getById(id);
		TaskHandinVO taskHandinVO = new TaskHandinVO();
		BeanUtils.copyProperties(detail, taskHandinVO);
		if (Func.isNotBlank(detail.getTaskId())) {
			Task task = taskService.getOne(new QueryWrapper<Task>().lambda().eq(Task::getId, detail.getTaskId()));
			taskHandinVO.setTaskName(task.getName());
		}
		taskHandinVO.setFileList(fileService.getAttachments(detail.getId(), detail.getGroupName()));
		return taskHandinVO;
	}

	@Override
	public R saveTaskHandin(TaskHandinDTO taskHandinDTO) {
		TaskHandin taskHandin = BeanUtil.copyProperties(taskHandinDTO, TaskHandin.class);
		if (Func.isNull(taskHandin.getDeptId()) || Func.isEmpty(taskHandin.getDeptId())) {
			taskHandin.setDeptId(String.valueOf(AuthUtil.getDeptId()));
		}
		if (Func.isNull(taskHandin.getUserId()) || Func.isEmpty(taskHandin.getUserId())) {
			taskHandin.setUserId(String.valueOf(AuthUtil.getUserId()));
		}
		super.saveOrUpdate(taskHandin);
		List<UploadVO> fileList = taskHandinDTO.getFileList();
		if (Objects.nonNull(fileList) && !fileList.isEmpty()) {
			fileService.saveAttachments(fileList, taskHandin.getId());
		}
		return R.data(taskHandin);
	}

	@Override
	public R handin(TaskHandinDTO taskHandinDTO) throws ParseException {
		R<TaskHandin> res = saveTaskHandin(taskHandinDTO);
		if (!res.isSuccess()) {
			throw new ServiceException("保存失败！");
		}
		TaskHandin taskHandin = res.getData();
		//		查询对应流程模型定义
		R<BladeFlowDef> definitionRes = flowClient.getLatestProcessDefinitionByKey("edu".equals(taskHandin.getModule()) ? ProcessConstant.TASK_HANDIN_EDU_KEY : ProcessConstant.TASK_HANDIN_DRILL_KEY);
		if (definitionRes.isSuccess()) {
			taskHandin.setProcessDefinitionId(definitionRes.getData().getId());
		} else {
			return R.fail(400, "流程模型未定义");
		}
		R<Integer> deptCategory = sysClient.getDeptCategory(Long.valueOf(AuthUtil.getUser().getDeptId()));
		if (!deptCategory.isSuccess()) {
			throw new ServiceException("查询部门类型失败，请检查后再试！");
		}
		String businessTable = FlowUtil.getBusinessTable(TaskHandin.class);
		Kv variables = Kv.create()
			.set("deptCategory", deptCategory.getData())
			.set(ProcessConstant.BUSINESS_ID_KEY, taskHandin.getId())
			.set(ProcessConstant.START_PROC_USER_ID, AuthUtil.getUserId());
		if (1 == deptCategory.getData()) {
			variables.set(ProcessConstant.PASS_KEY, true);
		}
		R<BladeFlow> result = flowClient.startProcessInstanceById(taskHandin.getProcessDefinitionId(), FlowUtil.getBusinessKey(businessTable, String.valueOf(taskHandin.getId())), variables);
		if (result.isSuccess()) {
			log.debug("流程已启动,流程ID:" + result.getData().getProcessInstanceId());
			TaskHandin afterStartHandin = this.getById(taskHandin.getId());
			// 返回流程id写入taskHandin
			afterStartHandin.setProcessInstanceId(result.getData().getProcessInstanceId());
			afterStartHandin.setSubmitTime(new Date());
			Date deadline = afterStartHandin.getDeadline();
			if (!Func.isNull(deadline) && Func.isNotEmpty(deadline)) {
				afterStartHandin.setStatus(deadline.after(new Date()) ? TASK_HANDIN_STATE_SUBMIT : TASK_HANDIN_STATE_OVERTIME_SUBMIT);//业务状态
			} else {
				afterStartHandin.setStatus(TASK_HANDIN_STATE_SUBMIT);
			}
			afterStartHandin.setState(HANDIN_STATE_AUDIT);//审批中
			this.updateById(afterStartHandin);
			return R.success("提交成功");
		} else {
			return R.fail(400, "开启流程失败");
		}
	}


	@Override
	@Transactional(rollbackFor = Exception.class)
	public R publishTask(TaskDTO task){
//		若是日常任务，根据业务类型查询是否存在已发布的同类型任务，若存在则返回提示信息
		if (TASK_FLAG_USUAL.equals(task.getFlag())) {
			TaskDTO taskDTO = new TaskDTO();
			taskDTO.setModule(task.getModule());
			taskDTO.setState(TASK_STATE_PUBLISH);
			taskDTO.setFlag(task.getFlag());
			taskDTO.setBusinessType(task.getBusinessType());
			List<Task> tList = baseMapper.selectTaskPage(taskDTO);
			if (!Func.isNull(tList) && tList.size() > 0) {
				return R.fail(400, "已存在该业务类型的日常任务，请勿重复发布！");
			}
		}
		if (Func.isNull(task.getNum()) || Func.isBlank(task.getNum())) {
			//任务编号
			task.setNum(Constant.TASK_PREFIX + (new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())));
		}
		if (Func.isNull(task.getDeptId()) || Func.isBlank(task.getDeptId())) {
			task.setDeptId(String.valueOf(AuthUtil.getDeptId()));
		}
		taskService.saveOrUpdate(task);
		log.info("=======task:{}=====", task);
		//创建对应类型、对应机构的任务
		String deptIds = task.getDeptIds();
		List<String> list = Arrays.asList(deptIds.split(","));
		List<String> depList = new ArrayList<String>(list);
		String deadline = DeadlineUtil.getDDLByFreq(task.getFrequency(), task.getEndDate());
//		根据所属模块、业务类型等判断应创建的任务是什么entity
		if (Func.isNotBlank(task.getModule()) && ("daily").equals(task.getModule())) {
			//若是检查整改模块 创建‘检查整改’表记录
			setInspection(task, depList, deadline);
		} else if (Func.isNotBlank(task.getModule()) && ("prevent").equals(task.getModule())) {
			//若是案件防控模块 创建‘案件材料报送’表记录
			setPrevent(task, depList, deadline);
		} else {//其他类业务 创建‘任务提报’表记录
			setTaskHandin(task, depList, deadline);
		}
		//修改任务状态
		task.setState(Constant.TASK_STATE_PUBLISH);
		taskService.updateById(task);
		return R.success("提交成功");
	}

	private void setTaskHandin(TaskDTO task, List<String> depList, String deadline) {
		depList.forEach(d -> {
			Department dEntity = departmentService.getById(d);
			TaskHandin taskHandin = new TaskHandin();
			taskHandin.setTaskId(task.getId());
			taskHandin.setDeptId(d);
			taskHandin.setDeptName(dEntity.getDeptName());
			taskHandin.setModule(task.getModule());
			taskHandin.setBusinessType(task.getBusinessType());
			taskHandin.setDeadline(Func.isNotEmpty(deadline) ? DateUtil.parse(deadline, DateUtil.PATTERN_DATE) : null);
			taskHandin.setFlag(task.getFlag());
			taskHandin.setState(HANDIN_STATE_DRAFT);
			taskHandin.setStatus(TASK_HANDIN_STATE_DRAFT);
			taskHandin.setRoleId(task.getRoleId());
			taskHandin.setUserId(this.getUserIds(task.getRoleId(), d));
			this.save(taskHandin);
		});
	}

	private void setInspection(TaskDTO task, List<String> depList, String deadline) {
		depList.forEach(d -> {
			Inspection inspection = new Inspection();
			inspection.setTaskId(task.getId());//关联任务id
			inspection.setDeptId(INSPECTION_TYPE_IN.equals(task.getCheckType()) ? task.getInspectDep() : d);//任务提报机构 若是内部检查，由检查机构进行提报；其他直接取d
			inspection.setDeptName(inspectionService.getDeptData(inspection.getDeptId()));//赋值机构名称
			inspection.setType(task.getFlag());//任务类型 usual-日常类 unusual-专项类
			inspection.setCheckType(task.getCheckType());//检查类型 1-自检自查 2-内部检查 3-外部检查
			inspection.setInspectedDep(d);//被检查机构，默认取提报机构
			inspection.setInspectDep(INSPECTION_TYPE_SELF.equals(task.getCheckType()) ? d : task.getInspectDep());//检查机构,如果是自检自查，就取被检查机构
			inspection.setState(HANDIN_STATE_DRAFT);//流程状态，默认为 未提交审批
			inspection.setStatus(PROBLEM_STATE_DRAFT);//业务状态，默认为 待检查
			inspection.setRoleId(task.getRoleId());//提报角色
			inspection.setUserId(this.getUserIds(task.getRoleId(), inspection.getDeptId()));//提报用户
			inspection.setBusinessType(task.getBusinessType());//业务类型
			inspection.setDeadline(Func.isNotEmpty(deadline) ? DateUtil.parse(deadline, DateUtil.PATTERN_DATE) : null);//提报期限
			inspection.setModule("daily");//所属模块 检查整改-daily
			inspectionService.save(inspection);
		});
	}

	//	案件防控-案件材料报送对象
	private void setPrevent(TaskDTO task, List<String> depList, String deadline) {
		depList.forEach(d -> {
			PreventMaterialDTO pm = new PreventMaterialDTO();
			pm.setTaskId(task.getId());//关联任务id
			pm.setDeptId(d);//任务提报机构
			pm.setState(HANDIN_STATE_DRAFT);//流程状态，默认为 0-待提报
			pm.setStatus(TASK_HANDIN_STATE_DRAFT);//业务状态 0-待提报
			pm.setRoleId(task.getRoleId());//提报角色
			pm.setUserId(this.getUserIds(task.getRoleId(), d));//提报用户
			pm.setDeadline(Func.isNotEmpty(deadline) ? DateUtil.parse(deadline, DateUtil.PATTERN_DATE) : null);//提报期限
			pm.setType(task.getBusinessType());//业务类型
			preventMaterialService.saveMaterial(pm);
		});
	}

	private String getUserIds(String roleId, String deptId) {
		String userId = "";
		if (!"".equals(roleId) && !"".equals(deptId)) {
			List<String> userList = baseMapper.getByRoleAndDept(roleId, deptId);
			if (Func.isNotEmpty(userList)) {
				userId = StringUtils.join(userList, ',');
			}
		}
		return userId;
	}

	@Override
	public TaskHandin getTaskHandin(TaskHandinCheckDTO taskHandinCheckDTO) {
		QueryWrapper<TaskHandin> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq(StringUtils.isNotBlank(taskHandinCheckDTO.getTaskId()), "TASK_ID", taskHandinCheckDTO.getTaskId());
		queryWrapper.eq(StringUtils.isNotBlank(taskHandinCheckDTO.getDeptId()), "DEPT_ID", taskHandinCheckDTO.getDeptId());
		queryWrapper.le(Func.isNotEmpty(taskHandinCheckDTO.getCreatEndDate()), "created_time", taskHandinCheckDTO.getCreatEndDate());
		queryWrapper.ge(Func.isNotEmpty(taskHandinCheckDTO.getCreatStartDate()), "created_time", taskHandinCheckDTO.getCreatStartDate());
//		queryWrapper.eq(StringUtils.isNotBlank(taskHandinCheckDTO.getStatus()), "STATE", taskHandinCheckDTO.getStatus());
		return baseMapper.selectOne(queryWrapper);
	}

	@Override
	public List<TaskHandin> getTaskList(String status) {
		QueryWrapper<TaskHandin> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("STATUS", status);
		return baseMapper.selectList(queryWrapper);
	}

	@Override
	public List<TaskTodoVO> selectTaskTodo() {
		log.info("---------------首页待办查询开始---------------");
		String roleId = String.valueOf(AuthUtil.getUser().getRoleId());
		List<String> list = Arrays.asList(roleId.split(","));
		String userId = String.valueOf(AuthUtil.getUserId());
		List<TaskTodoVO> taskTodoVOList = new ArrayList<>();
		//应急演练和教育培训待办
		getTaskHandinTodo(userId, taskTodoVOList);
		//检查待办
		getInspectionTodo(userId, taskTodoVOList);
		//整改待办
		getInspectionLineTodo(userId, taskTodoVOList);
		//考核评价待办
		getAssessmentTodo(userId, taskTodoVOList);
		//案件防控待办
		getPreventTodo(userId, taskTodoVOList);
		//安保指挥中心非现场检查整改通知书待办
		getUnLocalCheckTodo(userId, taskTodoVOList);
		//安保指挥中心警情处理待办
		getAlarmPushTodo(list, AuthUtil.getDeptId(), taskTodoVOList);
		//安保指挥中心非现场检查整改-持续整改待办
		getUnLocalCheckContinedTodo(userId, taskTodoVOList);
		log.info("---------------首页待办查询结束---------------");
		log.info("首页待办列表数据:[{}]", taskTodoVOList.toString());
		List<TaskTodoVO> collect = taskTodoVOList.stream().sorted(Comparator.comparing(TaskTodoVO::getUpdateTime, Comparator.nullsLast(Comparator.reverseOrder()))).collect(Collectors.toList());
		log.info("排序后待办数据为:[{}]", collect);
		return collect;
	}

	/**
	 * 安保指挥中心非现场检查整改-持续整改待办
	 */
	private void getUnLocalCheckContinedTodo(String userId, List<TaskTodoVO> taskTodoVOList) {
		log.info("-----------------获取安保指挥中心非现场检查整改-持续整改待办开始-----------------");
		List<SccUnlocaleCheckLine> SccUnlocaleCheckLineList = baseMapper.selectUnLocalCheckContinued(userId);
		if (Func.isNotEmpty(SccUnlocaleCheckLineList)) {
			log.info("安保指挥中心非现场检查整改-持续整改待办[{}]", SccUnlocaleCheckLineList);
			SccUnlocaleCheckLineList.forEach(item -> {
				TaskTodoVO tt = new TaskTodoVO();
				tt.setEntityName("unLocalCheckContinued");
				tt.setId(item.getId());
				tt.setModule("unLocalCheckContinued");
				tt.setBusinessType("非现场检查整改-持续整改");
				tt.setTaskName(Func.isNotEmpty(item.getProblemsDescribe()) ? item.getProblemsDescribe() : "无相关任务");
				tt.setFlag(null);
				tt.setDeptId(item.getDeptId());
				tt.setState(item.getState());
				tt.setDeadline(Func.isNotEmpty(item.getRectificationDeadline()) ? item.getRectificationDeadline() : null);
				tt.setUpdateTime(item.getUpdatedTime());
				taskTodoVOList.add(tt);
			});
		}
		log.info("-----------------获取安保指挥中心非现场检查整改-持续整改待办结束-----------------");
	}

	/**
	 * 应急演练和教育培训待办
	 */
	private void getTaskHandinTodo(String userId, List<TaskTodoVO> taskTodoVOList) {
		log.info("-----------------获取应急演练和教育培训待办开始-----------------");
		List<TaskHandin> taskHandinList = baseMapper.selectTaskHandinTodo(userId);
		if (Func.isNotEmpty(taskHandinList)) {
			log.info("应急演练和教育培训待办[{}]", taskHandinList);
			taskHandinList.forEach(th -> {
				TaskTodoVO tt = new TaskTodoVO();
				tt.setEntityName("taskHandin");
				tt.setId(th.getId());
				tt.setTaskName(Func.isNotEmpty(taskService.getDetail(th.getTaskId())) ? taskService.getDetail(th.getTaskId()).getName() : "无关联任务");
				tt.setModule(th.getModule());
				tt.setBusinessType(th.getBusinessType());
				tt.setFlag(th.getFlag());
				tt.setDeptId(th.getDeptId());
				tt.setState(th.getState());
				tt.setRoleId(th.getRoleId());
				tt.setUserId(th.getUserId());
				tt.setDeadline(Func.isNotEmpty(th.getDeadline()) ? th.getDeadline() : null);
				tt.setUpdateTime(th.getUpdatedTime());
				taskTodoVOList.add(tt);
			});
		}
		log.info("-----------------获取应急演练和教育培训待办开始-----------------");
	}

	/**
	 * 检查待办
	 */
	private void getInspectionTodo(String userId, List<TaskTodoVO> taskTodoVOList) {
		log.info("-----------------获取现场检查待办开始-----------------");
		List<Inspection> inspectionList = baseMapper.selectInspectionTodo(userId);
		if (Func.isNotEmpty(inspectionList)) {
			log.info("现场检查待办[{}]", inspectionList);
			inspectionList.forEach(item -> {
				TaskTodoVO tt = new TaskTodoVO();
				tt.setEntityName("inspection");
				tt.setId(item.getId());
				tt.setTaskName(Func.isNotEmpty(taskService.getDetail(item.getTaskId())) ? taskService.getDetail(item.getTaskId()).getName() : "无关联任务");
				tt.setModule("inspection");
				tt.setBusinessType(item.getBusinessType());
				tt.setFlag(item.getType());
				tt.setDeptId(item.getDeptId());
				tt.setDepartment(item.getInspectDep());
				tt.setState(item.getState());
				tt.setRoleId(item.getRoleId());
				tt.setUserId(item.getUserId());
				tt.setDeadline(Func.isNotEmpty(item.getDeadline()) ? item.getDeadline() : null);
				tt.setUpdateTime(item.getUpdatedTime());
				taskTodoVOList.add(tt);
			});
		}
		log.info("-----------------获取现场检查待办结束-----------------");
	}

	/**
	 * 整改待办
	 */
	private void getInspectionLineTodo(String userId, List<TaskTodoVO> taskTodoVOList) {
		log.info("-----------------获取现场检查整改待办开始-----------------");
		List<InspectionLine> inspectionLineList = baseMapper.selectInspectionLineTodo(userId);
		if (Func.isNotEmpty(inspectionLineList)) {
			log.info("现场检查整改待办[{}]", inspectionLineList);
			inspectionLineList.forEach(item -> {
				TaskTodoVO tt = new TaskTodoVO();
				tt.setBusinessType("现场检查整改");
				tt.setTaskName(Func.isNotEmpty(item.getContent()) ? item.getContent() : "无关联任务");
				tt.setEntityName("inspectionLine");
				tt.setId(item.getId());
				tt.setModule("inspectionLine");
				tt.setDeptId(item.getDeptId());
				tt.setState(item.getState());//审批状态
				tt.setRoleId(item.getRoleId());
				tt.setUserId(item.getUserId());
				tt.setDeadline(Func.isNotEmpty(item.getRectifyDeadline()) ? item.getRectifyDeadline() : null);
				tt.setUpdateTime(item.getUpdatedTime());
				taskTodoVOList.add(tt);
			});
		}
		log.info("-----------------获取现场检查整改待办结束-----------------");
	}

	/**
	 * 考核评价待办
	 */
	private void getAssessmentTodo(String userId, List<TaskTodoVO> taskTodoVOList) {
		log.info("-----------------获取考核评价待办开始-----------------");
		List<Assessment> aList = baseMapper.selectAssessmentTodo(userId);
		if (Func.isNotEmpty(aList)) {
			log.info("考核评价待办[{}]", aList);
			aList.forEach(item -> {
				TaskTodoVO tt = new TaskTodoVO();
				tt.setEntityName("assessment");
				tt.setId(item.getId());
				tt.setTaskName(Func.isNotEmpty(item.getEvaluationName()) ? item.getEvaluationName() : "无关联任务");
				tt.setModule("assessment");
				tt.setBusinessType("相关方考核");
				tt.setDeptId(item.getDeptId());
				tt.setState(item.getState());
				tt.setRoleId(item.getRoleId());
				tt.setUserId(item.getUserId());
				tt.setDeadline(null);
				tt.setUpdateTime(item.getUpdatedTime());
				taskTodoVOList.add(tt);
			});
		}
		log.info("-----------------获取考核评价待办结束-----------------");
	}

	/**
	 * 案件防控待办
	 */
	private void getPreventTodo(String userId, List<TaskTodoVO> taskTodoVOList) {
		log.info("-----------------获取案件防控待办开始-----------------");
		List<PreventMaterial> pList = baseMapper.selectPreventTodo(userId);
		if (Func.isNotEmpty(pList)) {
			log.info("案件防控待办[{}]", pList);
			pList.forEach(item -> {
				TaskTodoVO tt = new TaskTodoVO();
				tt.setEntityName("prevent");
				tt.setId(item.getId());
				tt.setTaskName(Func.isNotEmpty(item.getTaskId()) ? taskService.getDetail(item.getTaskId()).getName() : "无关联任务");
				tt.setModule("prevent");
				tt.setBusinessType(item.getType());
				tt.setDeptId(item.getDeptId());
				tt.setState(item.getState());
				tt.setRoleId(item.getRoleId());
				tt.setUserId(item.getUserId());
				tt.setDeadline(Func.isNotEmpty(item.getDeadline()) ? item.getDeadline() : null);
				tt.setUpdateTime(item.getUpdatedTime());
				taskTodoVOList.add(tt);
			});
		}
		log.info("-----------------获取案件防控待办结束-----------------");
	}

	/**
	 * 获取非现场检查整改通知书待办
	 * 非现场检查整改通知书业务状态 0-暂存;1-待整改，2-按时整改，3-超时整改，4-超时未整改,5-持续整改，6-待安全员确认
	 * 需要查出status为1和4的，并对应todo的state改为0和1
	 */
	private void getUnLocalCheckTodo(String userId, List<TaskTodoVO> taskTodoVOList) {
		log.info("-----------------获取安保指挥中心非现场检查整改通知书待办开始-----------------");
		List<SccUnlocaleCheck> sccUnlocaleChecksList = baseMapper.selectSccUnlocaleCheckTodo(userId);
		if (Func.isNotEmpty(sccUnlocaleChecksList)) {
			log.info("安保指挥中心非现场检查整改通知书待办[{}]", sccUnlocaleChecksList);
			sccUnlocaleChecksList.forEach(item -> {
				TaskTodoVO tt = new TaskTodoVO();
				tt.setEntityName("SccUnlocaleCheck");
				tt.setId(item.getId());
				tt.setModule("SccUnlocaleCheck");
				tt.setBusinessType("非现场检查整改通知书待办");
				tt.setTaskName(Func.isNotEmpty(item.getDocumentNo()) ? item.getDocumentNo() : "无关联任务");
				tt.setDeptId(item.getDeptId());
				tt.setState(item.getState());
				tt.setDeadline(Func.isNotEmpty(item.getRectificationDeadline()) ? item.getRectificationDeadline() : null);
				tt.setUpdateTime(item.getUpdatedTime());
				taskTodoVOList.add(tt);
			});
		}
		log.info("-----------------获取安保指挥中心非现场检查整改通知书待办结束-----------------");
	}

	/**
	 * 获取警情处理待办
	 */
	private void getAlarmPushTodo(List<String> list, String deptId, List<TaskTodoVO> taskTodoVOList) {
		log.info("-----------------获取安保指挥中心警情处理待办开始-----------------");
		list.forEach(roleId -> {
			List<SccAlarmPush> sccAlarmPushesList = baseMapper.selectSccAlarmPushTodo(roleId, deptId);
			if (Func.isNotEmpty(sccAlarmPushesList)) {
				log.info("安保指挥中心警情处理待办[{}]", sccAlarmPushesList);
				sccAlarmPushesList.forEach(item -> {
					TaskTodoVO tt = new TaskTodoVO();
					tt.setEntityName("SccAlarmPush");
					tt.setId(item.getId());
					tt.setModule("SccAlarmPush");
					tt.setBusinessType("警情处理待办");
					tt.setTaskName(Func.isNotEmpty(item.getEventDescription()) ? item.getEventDescription() : "无关联任务");
					tt.setDeptId(item.getDeptId());
					tt.setState(item.getState());
					tt.setDeadline(null);
					tt.setUpdateTime(item.getUpdatedTime());
					taskTodoVOList.add(tt);
				});
			}
		});
		log.info("-----------------获取安保指挥中心警情处理待办结束-----------------");
	}

	@Override
	public Boolean updateTaskHandin(TaskHandin taskHandin) {
		taskHandin.setSubmitType(SUBMIT_TYPE_ZERO);
		return this.updateById(taskHandin);
	}

	@Override
	public List<BacklogVO> getAppBacklog(BladeUser user, String moduleType) {
		return baseMapper.getAppBacklog(String.valueOf(user.getUserId()), HANDIN_STATE_DRAFT, moduleType);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public R endTaskByIds(TaskDTO task) {
		task.setState(Constant.TASK_STATE_END);
		//终止检查整改任务
		endInspection(task);
		//终止教育培训任务或应急演练培训任务
		endTaskIn(task);
		//案件防控任务终止
		endPrevent(task);
		return taskService.saveTask(task);
	}

	@Override
	public String getDeptName(String deptId) {
		return baseMapper.getDeptName(deptId);
	}

	@Override
	public List<EduAndDrillDataVO> getAimStatisticsData(EduAndDrillDataDTO eduAndDrillDataDTO, List<String> aimDepts, String aimModule) {
		return baseMapper.getAimStatisticsData(eduAndDrillDataDTO,aimDepts,aimModule);
	}

	/**
	 * 案件防控任务终止
	 */
	private void endPrevent(TaskDTO task) {
		if ("prevent".equals(task.getModule())) {
			List<PreventMaterial> preventList = preventMaterialService.list(new QueryWrapper<PreventMaterial>().lambda().eq(Func.isNotEmpty(task.getId()), PreventMaterial::getTaskId, task.getId()));
			if (Func.isNotEmpty(preventList)) {
				preventList.forEach(item -> {
					item.setStatus(TASK_STOP);
				});
				preventMaterialService.saveOrUpdateBatch(preventList);
			}
		}
	}

	/**
	 * 终止检查整改任务
	 */
	private void endInspection(TaskDTO task) {
		if ("daily".equals(task.getModule())) {
			List<Inspection> inspectionList = inspectionService.list(new QueryWrapper<Inspection>().lambda().eq(Func.isNotEmpty(task.getId()), Inspection::getTaskId, task.getId()));
			if (Func.isNotEmpty(inspectionList)) {
				inspectionList.forEach(item -> {
					item.setStatus(Constant.TASK_STOP_INSPECTION);
				});
				inspectionService.saveOrUpdateBatch(inspectionList);
			}
		}
	}

	/**
	 * 终止教育培训任务或应急演练培训任务
	 */
	private void endTaskIn(TaskDTO task) {
		if ("edu".equals(task.getModule()) || "drill".equals(task.getModule())) {
			List<TaskHandin> taskInList = this.list(new QueryWrapper<TaskHandin>().lambda().eq(Func.isNotEmpty(task.getId()), TaskHandin::getTaskId, task.getId()).eq(Func.isNotEmpty(task.getModule()), TaskHandin::getModule, task.getModule()));
			if (Func.isNotEmpty(taskInList)) {
				taskInList.forEach(item -> {
					item.setStatus(Constant.TASK_STOP);
				});
				this.saveOrUpdateBatch(taskInList);
			}
		}
	}
}
