package com.wtkj.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.wtkj.dto.MyTaskPageDTO;
import com.wtkj.dto.ProjectTaskPageDTO;
import com.wtkj.entity.*;
import com.wtkj.mapper.ProjectMapper;
import com.wtkj.mapper.TaskMapper;
import com.wtkj.service.*;
import com.wtkj.util.Workload;
import com.wtkj.vo.MyTaskStatistics;
import com.wutong.file.feign.IFileClient;
import com.wutong.file.vo.FileVO;
import lombok.AllArgsConstructor;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.redis.cache.BladeRedis;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.system.entity.Dept;
import org.springblade.system.entity.DictBiz;
import org.springblade.system.entity.Region;
import org.springblade.system.feign.IDictBizClient;
import org.springblade.system.feign.ISysClient;
import org.springblade.system.user.entity.User;
import org.springblade.system.user.feign.IUserClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static com.wtkj.config.MagicValue.STAFF_ADMIN;
import static com.wtkj.config.MagicValue.STAFF_SECOND_ADMIN;

/**
 * @author Blizzard
 * @create at 2023-09-15 15:18
 * @describe
 */
@AllArgsConstructor
@Service
public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implements ITaskService {

	private final IAsyncService asyncService;
	private final ITaskFileService taskFileService;
	private final IFileAndFolderService fileAndFolderService;
	private final IFileClient fileClient;
	private final IUserClient userClient;
	private final IProjectStageService stageService;
	private final BladeRedis redis;
	private final ISysClient sysClient;
	private final ProjectMapper projectMapper;
	private final IDictBizClient dictBizClient;

	@Override
	public boolean submit(Task task) {
		boolean flag = false;
		Long userId = AuthUtil.getUserId();
		Long taskId = task.getId();
		Long projectId = task.getProjectId();
		Project project = projectMapper.selectById(projectId);
		if (taskId == null && project != null) {
			Long stageId = task.getStageId();
			ProjectStage stage = stageService.getById(stageId);
			if (stage != null) {
				Date startTime = stage.getStartTime();
				Date endTime = stage.getEndTime();
				if (startTime != null && endTime != null) {
					if (task.getStartTime().before(startTime) || task.getEndTime().after(endTime)) {
						throw new ServiceException(String.format("任务时间异常,不可超出当前阶段的起止时间%s-%s", DateUtil.format(startTime, "yyyy-MM-dd"), DateUtil.format(endTime, "yyyy-MM-dd")));
					}
				}
			}
			LocalDate now = LocalDate.now();
			Integer year = now.getYear();
			Integer month = now.getMonthValue();
			task.setYear(year);
			task.setMonth(month);
			task.setCompetentUnit(project.getCompetentUnit());
			flag = this.save(task);

			asyncService.createTask(task);
			asyncService.dispatchToOrg(userId, task);

		} else {
			Task byId = this.getById(taskId);
			if (byId != null) {
				Integer newStatus = task.getTaskStatus();
				Integer oldStatus = byId.getTaskStatus();
				//确认任务
				if (newStatus != null && oldStatus != null && !oldStatus.equals(4) && newStatus.equals(4)) {
					task.setConfirmUser(userId);
					task.setConfirmTime(DateUtil.now());
					task.setIsConfirmed(1);
				}
				//指定执行部门  ---> 通知主管
				if (byId.getExecuteDept() == null && task.getExecuteDept() != null) {
					asyncService.dispatchToDept(userId, task);
				}
				// 下发任务 ---> 通知执行者
				if (StringUtil.isBlank(byId.getExecuteUser()) && StringUtil.isNotBlank(task.getExecuteUser())) {
					asyncService.dispatchTask(userId, task);
				}
				//二次审核 已经变为审核状态(7)的时候通知二次审核
				if (oldStatus != null && newStatus != null && !oldStatus.equals(7) && newStatus.equals(7)) {
					asyncService.secondCheck(userId, task);
				}
				asyncService.alterTask(task, byId, userId);
			}
			flag = this.updateById(task);
		}
		return flag;
	}

	@Override
	public IPage<Task> projectTaskPage(ProjectTaskPageDTO dto, IPage<Task> page) {
		LambdaQueryWrapper<Task> lqw = new LambdaQueryWrapper<>();
		lqw.eq(Task::getProjectId, dto.getProjectId());
		lqw.eq(Task::getStageId, dto.getStageId());

		if (dto.getName() != null) {
			lqw.like(Task::getTitle, dto.getName());
		}
		if (dto.getOrgDeptId() != null) {
			lqw.eq(Task::getOrgDeptId, dto.getOrgDeptId());
		}
		if (dto.getTaskStatus() != null) {
			lqw.eq(Task::getTaskStatus, dto.getTaskStatus());
		}
		lqw.orderByDesc(Task::getCreateTime);
		return baseMapper.selectPage(page, lqw);
	}

	@Override
	public boolean uploadFile(Long taskId, String ids) {
		boolean flag = false;
		if (ids != null) {
			List<TaskFile> files = new ArrayList<>();
			List<Long> fileIds = Func.toLongList(ids);
			fileIds.forEach(id -> {
				//判断这个文件是否已经存在
				TaskFile file = taskFileService.getByBladeFileId(taskId, id);
				//不存在 才保存
				if (file == null) {
					TaskFile taskFile = new TaskFile();
					taskFile.setTaskId(taskId);
					taskFile.setBladeFileId(id);
					files.add(taskFile);
				}
			});
			asyncService.firstCheck(AuthUtil.getUserId(), this.getById(taskId));
			flag = taskFileService.saveBatch(files);
		}
		return flag;
	}

	@Override
	public boolean moveFile(Long stageId, Long parentId, String fileIds) {

		boolean flag = false;
		List<Long> ids = Func.toLongList(fileIds);
		if (!CollectionUtils.isEmpty(ids)) {
			List<FileAndFolder> files = new ArrayList<>();
			FileAndFolder folder = fileAndFolderService.getById(parentId);
			if (folder != null) {
				ids.forEach(id -> {
					R<FileVO> rpc = fileClient.findById(id);
					if (rpc.isSuccess()) {
						FileAndFolder file = new FileAndFolder();
						file.setProjectId(folder.getProjectId());
						file.setStageId(stageId);
						file.setParentId(parentId);
						file.setType(1);
						file.setTitle(rpc.getData().getOriginalFileName());
						file.setBladeFileId(id);
						files.add(file);
					}
				});
				flag = fileAndFolderService.saveBatch(files);
			}
		}
		return flag;
	}

	@Override
	public boolean deleteFile(String ids) {
		return taskFileService.removeBatchByIds(Func.toLongList(ids));
	}

	@Override
	public IPage<Task> myTaskPage(MyTaskPageDTO dto, IPage<Task> page) {

		Long userId = AuthUtil.getUserId();
		LambdaQueryWrapper<Task> lqw = new LambdaQueryWrapper<>();
		//当前年 当前月
		LocalDate currentDate = LocalDate.now();
		int currentYear = currentDate.getYear();
		int currentMonth = currentDate.getMonthValue();
		lqw.eq(Task::getYear, dto.getYear() == null ? currentYear : dto.getYear());
		lqw.eq(Task::getMonth, dto.getMonth() == null ? currentMonth : dto.getMonth());

		//1.全部 2.我创建的 3.我执行的 4.我管理的
		if (dto.getType() == 1) {
			Set<Long> ids = new HashSet<>();
			//我管理的
			if (dto.getDeptCategory().equals(3)) {
				//1.业主  ---> 项目权限表里 topDept 字段是自己的集合
				List<Task> tasks = this.getByCompetentUnit(dto.getTopDept());
				if (!CollectionUtils.isEmpty(tasks)) {
					Set<Long> taskIds = tasks.stream().map(Task::getId).collect(Collectors.toSet());
					ids.addAll(taskIds);
				}
			} else if (dto.getDeptCategory().equals(4)) {
				//2.服务商
				String role = AuthUtil.getUserRole();
				Long deptId = Func.firstLong(AuthUtil.getDeptId());
				if (role.contains(STAFF_ADMIN)) {
					// 2.1 机构管理员 ---> 任务是派遣给自己机构的
					List<Task> byOrgDeptId = this.getByDeptAndDate(dto.getTopDept(), null, null, null);
					if (!CollectionUtils.isEmpty(byOrgDeptId)) {
						Set<Long> taskIds = byOrgDeptId.stream().map(Task::getId).collect(Collectors.toSet());
						ids.addAll(taskIds);
					}
				} else if (role.contains(STAFF_SECOND_ADMIN)) {
					// 2.2 次级机构主管  ---> 任务是派遣给自己部门的
					List<Task> list = this.getByDeptAndDate(dto.getTopDept(), deptId, null, null);
					if (!CollectionUtils.isEmpty(list)) {
						Set<Long> taskIds = list.stream().map(Task::getId).collect(Collectors.toSet());
						ids.addAll(taskIds);
					}
				}
			}
			lqw.and(wq -> {
				wq.eq(Task::getCreateUser, userId);
				wq.or().like(Task::getExecuteUser, String.valueOf(userId));
				if (!CollectionUtils.isEmpty(ids)) {
					wq.or().in(Task::getId, ids);
				}
			});
		} else if (dto.getType() == 2) {
			lqw.eq(Task::getCreateUser, userId);
		} else if (dto.getType() == 3) {
			lqw.like(Task::getExecuteUser, String.valueOf(userId));
		} else if (dto.getType() == 4) {
			//我管理的
			if (dto.getDeptCategory().equals(3)) {
				//1.业主  ---> 任务主管单位是自己topDept
				List<Task> tasks = this.getByCompetentUnit(dto.getTopDept());
				if (!CollectionUtils.isEmpty(tasks)) {
					Set<Long> taskIds = tasks.stream().map(Task::getId).collect(Collectors.toSet());
					lqw.in(Task::getId, taskIds);
				}
			} else if (dto.getDeptCategory().equals(4)) {
				//2.服务商
				String role = AuthUtil.getUserRole();
				Long deptId = Func.firstLong(AuthUtil.getDeptId());
				if (role.contains(STAFF_ADMIN)) {
					// 2.1 机构管理员 ---> 任务是派遣给自己机构的
					List<Task> byOrgDeptId = this.getByDeptAndDate(dto.getTopDept(), null, null, null);
					if (!CollectionUtils.isEmpty(byOrgDeptId)) {
						Set<Long> taskIds = byOrgDeptId.stream().map(Task::getId).collect(Collectors.toSet());
						lqw.in(Task::getId, taskIds);
					}
				} else if (role.contains(STAFF_SECOND_ADMIN)) {
					// 2.2 次级机构主管  ---> 任务是派遣给自己部门的
					List<Task> list = this.getByDeptAndDate(dto.getTopDept(), deptId, null, null);
					if (!CollectionUtils.isEmpty(list)) {
						Set<Long> taskIds = list.stream().map(Task::getId).collect(Collectors.toSet());
						lqw.in(Task::getId, taskIds);
					}
				} else {
					lqw.eq(Task::getId, 0L);
				}
			}
		}
		if (dto.getType() == 1) {
			lqw.groupBy(Task::getProjectId, Task::getCreateTime);
			lqw.orderByDesc(Task::getProjectId, Task::getCreateTime);
		} else {
			lqw.orderByDesc(Task::getCreateTime);
		}
		return baseMapper.selectPage(page, lqw);
	}

	@Override
	public MyTaskStatistics taskStatistics(Long stageId, Integer year, Integer month) {
		MyTaskStatistics statistics = new MyTaskStatistics();
		Long userId = AuthUtil.getUserId();
		List<Task> tasks = null;
		if (stageId == null) {
			//个人任务统计
			tasks = this.listByUser(userId, year, month);
		} else {
			//项目下的所有任务
			tasks = this.listByStageId(stageId);
		}
		if (!CollectionUtils.isEmpty(tasks)) {
			//全部任务数
			statistics.setAll(tasks.size());
			tasks.forEach(task -> {
				//任务状态 1.待确认 2.进行中 3.已提交 4.已完成 5.已取消 6.过期 7.审查 8.二次审查
				Integer taskStatus = task.getTaskStatus();
				if (taskStatus.equals(4)) {
					//1.已完成
					statistics.setCompleted(statistics.getCompleted() + 1);
				}
				if (!taskStatus.equals(4) && !taskStatus.equals(5) && !taskStatus.equals(6)) {
					//未完成
					//6.未完成
					statistics.setNotCompleted(statistics.getNotCompleted() + 1);
				}
				Date now = DateUtil.now();
				Date endTime = task.getEndTime();
				Integer isExpire = task.getIsExpire();
				if (endTime != null) {
					//2.已逾期
					if (taskStatus.equals(6)) {
						statistics.setOverdue(statistics.getOverdue() + 1);
					}

					//3.待确认 已经提交但未确认且未逾期的任务为待确认
					if (endTime.after(now) && taskStatus.equals(3)) {
						statistics.setToConfirmed(statistics.getToConfirmed() + 1);
					}

					//4.今日到期
					String endStr = DateUtil.format(endTime, "yyyy-MM-dd");
					String nowStr = DateUtil.format(now, "yyyy-MM-dd");
					if (endStr.equals(nowStr)) {
						statistics.setTodayToExpire(statistics.getTodayToExpire() + 1);
					}

					//5.逾期完成 isExpire = 1 且taskStatus = 4
					if (isExpire.equals(1) && taskStatus.equals(4)) {
						statistics.setOverdueComplete(statistics.getOverdueComplete() + 1);
					}
				}
			});
		}
		return statistics;
	}


	@Override
	public List<Task> listByUser(Long userId, Integer year, Integer month) {
		LambdaQueryWrapper<Task> lqw = new LambdaQueryWrapper<>();
		if (year != null) {
			lqw.eq(Task::getYear, year);
		}
		if (month != null) {
			lqw.eq(Task::getMonth, month);
		}
		lqw.like(Task::getExecuteUser, String.valueOf(userId));
		lqw.orderByAsc(Task::getEndTime);
		return this.list(lqw);
	}


	@Override
	public List<Task> listByStageId(Long stageId) {
		LambdaQueryWrapper<Task> lqw = new LambdaQueryWrapper<>();
		lqw.eq(Task::getStageId, stageId);
		lqw.ne(Task::getTaskStatus, 5);
		lqw.orderByAsc(Task::getEndTime);
		return this.list(lqw);
	}

	@Override
	public List<Task> getByExecute(Long deptId, String userId) {
		return baseMapper.selectByExecute(deptId, userId);
	}


	@Override
	public List<Task> todayTodo(Long userId, String date) {
		return baseMapper.todayTo(String.valueOf(userId), date);
	}

	@Override
	public List<Task> todayExpire(Long userId, String date) {
		return baseMapper.todayExpire(String.valueOf(userId), date);
	}

	@Override
	public List<Task> getByDeptAndDate(Long topDept, Long executeDept, String user, String date) {
		return baseMapper.getByDeptAndDate(topDept, executeDept, user, date);
	}

	@Override
	public List<Task> getTodoAndExpireByUserId(Long userId, String date) {
		return baseMapper.getTodoAndExpireByUserId(String.valueOf(userId), date);
	}

	@Override
	public List<Task> getTodayTodoByOrgDeptId(Long topDept, String date) {
		return baseMapper.getTodayTodoByOrgDeptId(topDept, date);
	}

	@Override
	public List<Task> getTodoByYear(Set<Long> projectIds, String year) {
		return baseMapper.getTodoByYear(projectIds, Integer.valueOf(year));
	}

	@Override
	public List<Map<String, String>> projectTaskSummary(Long stageId) {
		List<Map<String, String>> res = new ArrayList<>();
		//项目下任务执行者的情况
		Set<Long> userIds = new HashSet<>();
		List<Task> tasks = this.listByStageId(stageId);
		if (!CollectionUtils.isEmpty(tasks)) {
			for (Task task : tasks) {
				String executeUser = task.getExecuteUser();
				if (StringUtil.isNotBlank(executeUser)) {
					List<Long> ids = Func.toLongList(executeUser);
					userIds.addAll(ids);
				}
			}
		}
		if (!CollectionUtils.isEmpty(userIds)) {
			userIds.forEach(userId -> {
				Map<String, String> map = new HashMap<>();
				R<User> userR = userClient.userInfoById(userId);
				if (userR.isSuccess()) {
					List<Task> tasks1 = this.listByUserAndProject(userId, stageId);
					if (!CollectionUtils.isEmpty(tasks1)) {
						map.put("value", String.valueOf(tasks1.size()));
						map.put("name", userR.getData().getName());
						//map.put(userR.getData().getName(), tasks1.size());
						res.add(map);
					}
				}
			});
		}
		return res;
	}

	@Override
	public List<Task> listByUserAndProject(Long userId, Long stageId) {
		LambdaQueryWrapper<Task> lqw = new LambdaQueryWrapper<>();
		lqw.eq(Task::getStageId, stageId);
		lqw.like(Task::getExecuteUser, String.valueOf(userId));
		lqw.orderByAsc(Task::getEndTime);
		return this.list(lqw);
	}

	@Override
	public LineChartDataSet projectTaskSituation(Long stageId) {
		LineChartDataSet set = new LineChartDataSet();
		List<LineChartData> list = new ArrayList<>();
		//1.阶段周期
		List<LocalDate> dateList = redis.get("dateList::" + stageId);
		if (!CollectionUtils.isEmpty(dateList)) {
			LineChartData leftLine = new LineChartData();
			leftLine.setType("line");
			leftLine.setName("leftTask");
			LineChartData completeLine = new LineChartData();
			completeLine.setType("line");
			completeLine.setName("completeTask");
			LineChartData expireLine = new LineChartData();
			expireLine.setType("line");
			expireLine.setName("expireTask");
			List<Map<String, Object>> leftData = new ArrayList<>();
			List<Map<String, Object>> completeData = new ArrayList<>();
			List<Map<String, Object>> expireData = new ArrayList<>();
			dateList.forEach(date -> {
				DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); // 设置日期格式
				String formatDate = date.format(formatter);
				Map<String, Object> leftMap = new HashMap<>();
				// 日期为date时的任务剩余量 完成量 过期量
				//1.剩余量 未完成和已取消的除外
				List<Task> leftTasks = this.getLeftByDateAndStage(stageId, formatDate);
				int leftAmount = 0;
				if (!CollectionUtils.isEmpty(leftTasks)) {
					leftAmount = leftTasks.size();
				}
				leftMap.put(formatDate, leftAmount);
				leftData.add(leftMap);

				//2.完成量 task_status = 4 的数量
				Map<String, Object> completeMap = new HashMap<>();
				List<Task> completeTasks = this.getListByDateAndStageAndStatus(stageId, formatDate, 4);
				int completeAmount = 0;
				if (!CollectionUtils.isEmpty(completeTasks)) {
					completeAmount = completeTasks.size();
				}
				completeMap.put(formatDate, completeAmount);
				completeData.add(completeMap);

				//3.过期量 task_status = 6
				Map<String, Object> expireMap = new HashMap<>();
				List<Task> expireTasks = this.getListByDateAndStageAndStatus(stageId, formatDate, 6);
				int expireAmount = 0;
				if (!CollectionUtils.isEmpty(expireTasks)) {
					expireAmount = expireTasks.size();
				}
				expireMap.put(formatDate, expireAmount);
				expireData.add(expireMap);
			});
			leftLine.setData(leftData);
			completeLine.setData(completeData);
			expireLine.setData(expireData);

			list.add(leftLine);
			list.add(completeLine);
			list.add(expireLine);
		}
		set.setLineChartDataList(list);
		return set;

	}


	@Override
	public LineChartDataSet projectTaskBurnout(Long stageId) {
		LineChartDataSet set = new LineChartDataSet();
		List<LineChartData> list = new ArrayList<>();

		//1.阶段周期
		List<LocalDate> dateList = redis.get("dateList::" + stageId);
		if (!CollectionUtils.isEmpty(dateList)) {
			int size = dateList.size();
			float avg = 0f;
			float amount = 0f;
			// 当前阶段下所有的任务
			List<Task> tasks = this.listByStageId(stageId);
			if (!CollectionUtils.isEmpty(tasks)) {
				int taskAmount = tasks.size();
				amount = taskAmount;
				//任务每天平均燃尽量
				avg = (float) taskAmount / size;
			}
			LineChartData actualLine = new LineChartData();
			actualLine.setType("line");
			actualLine.setName("actual");
			LineChartData avgLine = new LineChartData();
			avgLine.setType("line");
			avgLine.setName("avg");
			List<Map<String, Object>> actualData = new ArrayList<>();
			List<Map<String, Object>> avgData = new ArrayList<>();


			float finalAvg = avg;
			float temp = amount;
			for (LocalDate date : dateList) {
				DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); // 设置日期格式
				String formatDate = date.format(formatter);
				// 日期为date时的当日完成数 理想完成数
				//1.date 当日完成数
				Map<String, Object> actualMap = new HashMap<>();
				List<Task> actualTasks = this.getCurrentDateCompleteByStageAndDate(stageId, formatDate, null);
				int actualAmount = 0;
				if (!CollectionUtils.isEmpty(actualTasks)) {
					actualAmount = actualTasks.size();
				}
				actualMap.put(formatDate, actualAmount);
				actualData.add(actualMap);

				Map<String, Object> avgMap = new HashMap<>();
				temp = temp - finalAvg;
				avgMap.put(formatDate, temp);
				avgData.add(avgMap);
			}
			actualLine.setData(actualData);
			avgLine.setData(avgData);
			list.add(actualLine);
			list.add(avgLine);
		}
		set.setLineChartDataList(list);
		return set;
	}

	@Override
	public List<Task> getTodayToExpire(String date) {
		return baseMapper.getTodayToExpire(date);
	}

	@Override
	public List<Workload> exportList(String startDate) {
		List<Workload> result = new ArrayList<>();
		//1.时间段内已经完成的任务
		List<Task> list = baseMapper.getByMonth(startDate);
		if (!CollectionUtils.isEmpty(list)) {
			List<Workload> tempList = new ArrayList<>();
			//2.Information for all tasks
			for (Task task : list) {
				Workload workload = new Workload();
				//人员
				String executeUser = task.getExecuteUser();
				//项目信息
				Long projectId = task.getProjectId();
				//发布人
				Long createUser = task.getCreateUser();
				//科研 方案 其他
				String category = task.getCategory();
				//新写 修改
				String tags = task.getTags();
				if (executeUser != null && projectId != null && createUser != null && createUser > -1L && category != null && tags != null) {
					//发布人
					R<User> userR = userClient.userInfoById(createUser);
					if (userR.isSuccess()) {
						workload.setPubUser(userR.getData().getName());
					}
					//项目信息
					Project project = projectMapper.selectById(projectId);
					if (project != null) {
						workload.setProjectName(project.getName());
						String areaCode = project.getAreaCode();
						if (areaCode != null) {
							if (areaCode.length() == 4) {
								//市
								R<Region> region = sysClient.getRegion(areaCode);
								if (region.isSuccess()) {
									workload.setCity(region.getData().getName());
								}
							} else if (areaCode.length() == 6) {
								//县
								R<Region> region = sysClient.getRegion(areaCode);
								if (region.isSuccess()) {
									workload.setCounty(region.getData().getName());
								}
								//得到上级
								String parentCode = areaCode.substring(0, areaCode.length() - 2);
								R<Region> region1 = sysClient.getRegion(parentCode);
								if (region1.isSuccess()) {
									workload.setCity(region1.getData().getName());
								}
							}
						}

					}

					//分类 可研 方案 其他
					R<DictBiz> rpc = dictBizClient.getById(Long.valueOf(category));
					R<DictBiz> rpc1 = dictBizClient.getById(Long.valueOf(tags));
					if (rpc.isSuccess() && rpc1.isSuccess()) {
						DictBiz data = rpc.getData();
						DictBiz data1 = rpc1.getData();
						if (data1.getDictKey().equals("1")) {
							//新编
							if (data != null) {
								if (data.getDictKey().equals("2")) {
									//可研
									workload.setAdd1(1);
								} else if (data.getDictKey().equals("4")) {
									//方案
									workload.setAdd2(1);
								} else {
									//其他
									workload.setAdd(1);
								}
							}
						} else if (data1.getDictKey().equals("2")) {
							//修改
							if (data != null) {
								if (data.getDictKey().equals("2")) {
									//可研
									workload.setAlter1(1);
								} else if (data.getDictKey().equals("4")) {
									//方案
									workload.setAlter2(1);
								} else {
									//其他
									workload.setAlter(1);
								}
							}
						}
					}

					//人员
					R<User> userR1 = userClient.userInfoById(Long.valueOf(executeUser));
					if (userR1.isSuccess()) {
						workload.setUserName(userR1.getData().getName());
					}
					tempList.add(workload);
				}
			}

			//Grouping to achieve the purpose of arranging the same user groups
			if (!CollectionUtils.isEmpty(tempList)) {
				Map<String, List<Workload>> collect = tempList.stream().collect(Collectors.groupingBy(Workload::getUserName));
				for (Map.Entry<String, List<Workload>> entry : collect.entrySet()) {
					result.addAll(entry.getValue());
				}
			}

		}
		return result;
	}

	@Override
	public void export(List<Workload> list, HttpServletResponse response) throws IOException {
		try {
			WriteCellStyle headWriteCellStyle = new WriteCellStyle();
			//设置背景颜色
			headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
			//设置头字体
			WriteFont headWriteFont = new WriteFont();
			headWriteFont.setFontHeightInPoints((short) 13);
			headWriteFont.setBold(true);
			headWriteCellStyle.setWriteFont(headWriteFont);
			//设置头居中
			headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);

			//内容策略
			WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
			//设置 水平居中
			contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);

			HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);

			response.setContentType("application/vnd.ms-excel");
			response.setCharacterEncoding("utf-8");
			// 这里URLEncoder.encode可以防止中文乱码 当然和easy excel没有关系
			String fileName = URLEncoder.encode("工作量统计", "UTF-8");
			response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
			// 这里需要设置不关闭流
			EasyExcel.write(response.getOutputStream(), Workload.class)
				.registerWriteHandler(horizontalCellStyleStrategy).sheet("工作量统计")
				.doWrite(list);
		} catch (IOException e) {
			//throw new RuntimeException(e);
			// 重置response
			response.reset();
			response.setContentType("application/json");
			response.setCharacterEncoding("utf-8");
			Map<String, String> map = new HashMap<String, String>();
			map.put("status", "failure");
			map.put("message", "下载文件失败" + e.getMessage());
			response.getWriter().println(JSON.toJSONString(map));
		}
	}

	@Override
	public List<Task> getByCompetentUnit(Long deptId) {
		return baseMapper.selectByCompetentUnit(deptId);
	}

	@Override
	public List<Task> getByStatus(Integer status) {
		return baseMapper.selectByTaskStatus(status);
	}

	@Override
	public List<Dept> taskCops(Long projectId) {
		List<Dept> res = new ArrayList<>();
		//1.项目下的所有任务
		List<Task> tasks = baseMapper.getByProjectId(projectId);
		if (!CollectionUtils.isEmpty(tasks)) {
			Set<Long> deptIds = tasks.stream().map(Task::getOrgDeptId).filter(Objects::nonNull).collect(Collectors.toSet());
			if (!CollectionUtils.isEmpty(deptIds)) {
				deptIds.forEach(dept -> {
					R<Dept> rpc = sysClient.getDept(dept);
					if (rpc.isSuccess()) {
						res.add(rpc.getData());
					}
				});
			}
		}
		return res;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean delete(List<Long> ids) {
		ids.forEach(id -> {
			Task task = this.getById(id);
			if (task != null) {
				Long projectId = task.getProjectId();
				Project project = projectMapper.selectById(projectId);
				if (project != null) {
					Integer todoTask = project.getTodoTask();
					todoTask = todoTask - 1;
					project.setTodoTask(todoTask < 0 ? 0 : todoTask);
					projectMapper.updateById(project);
				}
			}
		});

		return removeByIds(ids);
	}


	private List<Task> getListByDateAndStageAndStatus(Long stageId, String formatDate, Integer taskStatus) {
		return baseMapper.selectByDateAndStageAndStatus(stageId, formatDate, taskStatus);
	}

	private List<Task> getLeftByDateAndStage(Long stageId, String date) {
		return baseMapper.selectLeftByDateAndStage(stageId, date);
	}

	private List<Task> getCurrentDateCompleteByStageAndDate(Long stageId, String formatDate, Integer taskStatus) {
		return baseMapper.selectCurrentDateCompleteByStageAndDate(stageId, formatDate, taskStatus);
	}
}