package com.tykj.dev.device.sendback.service.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.tykj.dev.config.GlobalMap;
import com.tykj.dev.config.base.DeviceLifeStatus;
import com.tykj.dev.device.file.entity.Documents;
import com.tykj.dev.device.file.entity.FileRet;
import com.tykj.dev.device.file.service.FilesUtil;
import com.tykj.dev.device.file.service.PdfService;
import com.tykj.dev.device.library.repository.DeviceLibraryDao;
import com.tykj.dev.device.library.service.DeviceLibraryService;
import com.tykj.dev.device.library.service.DeviceLogService;
import com.tykj.dev.device.library.subject.Dto.DeviceLogDto;
import com.tykj.dev.device.library.subject.domin.DeviceLibrary;
import com.tykj.dev.device.library.subject.domin.DeviceLog;
import com.tykj.dev.device.library.subject.vo.ScriptSaveVo;
import com.tykj.dev.device.packing.repository.PackingLibraryDao;
import com.tykj.dev.device.sendback.entity.domain.DeviceRepel;
import com.tykj.dev.device.sendback.entity.domain.DeviceRepelDetail;
import com.tykj.dev.device.sendback.entity.domain.RepelDeviceUnit;
import com.tykj.dev.device.sendback.entity.domain.RepelTaskStatistical;
import com.tykj.dev.device.sendback.entity.vo.*;
import com.tykj.dev.device.sendback.service.*;
import com.tykj.dev.device.task.service.TaskService;
import com.tykj.dev.device.task.subject.bto.TaskBto;
import com.tykj.dev.device.task.subject.domin.Task;
import com.tykj.dev.device.user.base.ret.MemberThat;
import com.tykj.dev.device.user.read.service.MessageService;
import com.tykj.dev.device.user.read.subject.bto.MessageBto;
import com.tykj.dev.device.user.subject.entity.Area;
import com.tykj.dev.device.user.subject.entity.SecurityUser;
import com.tykj.dev.device.user.subject.entity.Units;
import com.tykj.dev.device.user.subject.entity.User;
import com.tykj.dev.device.user.subject.service.AreaService;
import com.tykj.dev.device.user.subject.service.GroupService;
import com.tykj.dev.device.user.subject.service.UnitsService;
import com.tykj.dev.device.user.subject.service.UserService;
import com.tykj.dev.misc.base.BusinessEnum;
import com.tykj.dev.misc.base.StatusEnum;
import com.tykj.dev.misc.exception.ApiException;
import com.tykj.dev.misc.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * @author 清退业务逻辑代码提供
 * @version 1.0.0
 * @ClassName RepelBusinessServiceImpl.java
 * @Description TODO
 * @createTime 2021年01月07日 16:13:00
 */
@Service
@Slf4j
@SuppressWarnings("ALL")
public class RepelBusinessServiceImpl implements RepelBusinessService {
    @Autowired
    TaskService taskService;

    @Autowired
    DeviceLogService deviceLogService;

    @Autowired
    DeviceRepelService deviceRepelService;

    @Autowired
    DeviceRepelDetailService deviceRepelDetailService;

    @Autowired
    RepelTaskStatisticalService repelTaskStatisticalService;

    @Autowired
    GroupService groupService;

    @Autowired
    DeviceLibraryDao deviceLibraryDao;

    @Autowired
    UnitsService unitsService;

    @Autowired
    UserService userService;

    @Autowired
    AreaService areaService;

    @Autowired
    RepelDeviceUnitService repelDeviceUnitService;

    @Autowired
    PackingLibraryDao packingLibraryDao;

    @Autowired
    DeviceLibraryService deviceLibraryService;

    @Autowired
    MessageService messageService;

    @Autowired
    PdfService pdfService;

    /**
     * 发起申请后清退任务
     *
     * @param deviceRepel
     * @param userId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void initiateRepel(DeviceRepel deviceRepel, Integer userId) {
        //生成一个清退任务 省清退任务 类型为 清退统计  17  16清退
        //参照选择的范围给单位都发送 市清退任务待执行
        //如果省本身有需要清退的型号，给省自己发起一个代办任务 本级装备待清退
        //生成的任务放入统计表中 关联信息
        //把清退账单存储到数据表中
        //写入业务日志
        User user = userService.findByUser(userId);
        Units units = unitsService.findById(user.getUnitsId());
        Area area = areaService.findByid(units.getAreaId());
        List<Integer> lifeStatus = new ArrayList<>();
        lifeStatus.add(DeviceLifeStatus.IN_LIBRARY.id);
        lifeStatus.add(DeviceLifeStatus.REPEL.id);
        lifeStatus.add(DeviceLifeStatus.REPAIRING.id);
        lifeStatus.add(DeviceLifeStatus.IN_TRANSIT.id);
        lifeStatus.add(DeviceLifeStatus.USE.id);
        lifeStatus.add(DeviceLifeStatus.SEND_BACK.id);
        lifeStatus.add(DeviceLifeStatus.TO_BE_DESTROYED.id);
        lifeStatus.add(DeviceLifeStatus.TO_BE_SCRAPPED.id);
        List<String> directlUnderUnitNames = new ArrayList<>();
        AtomicBoolean directlUnderUnit = new AtomicBoolean(false);
        AtomicBoolean correspondingLevel = new AtomicBoolean(false);
        deviceRepel.setFielding(StringUtils.ListToString(deviceRepel.getFieldingIds()));
        deviceRepel.setFiles(FilesUtil.stringFileToList(deviceRepel.getFileRets()));
        deviceRepel.setTaskScope(StringUtils.ListToString(deviceRepel.getTaskScopes()));
        Map<String, Integer> unitNameMap = new HashMap<>();
        List<String> seqNumbers = DeviceSeqUtil.selectDeviceSeqs(deviceRepel.getSeqNumbers());
        if (seqNumbers.size() != 0) {
            log.info("申请任务触发清退任务");
            deviceLibraryService.findAllBySeqNumber(seqNumbers).forEach(
                    deviceLibrary -> {
                        if (!unitNameMap.containsKey(deviceLibrary.getOwnUnit())) {
                            unitNameMap.put(deviceLibrary.getOwnUnit(), 0);
                        }
                    }
            );
            //市区关系信息
            Map<Integer, List<SupervisorVo>> supervisorMap = new HashMap<>();

            //省直属 待考虑
            unitNameMap.forEach((k, v) -> {
                Units units1 = unitsService.findbyName(k);
                //区
                List<SupervisorVo> supervisorVoList = new ArrayList<>();

                if (units1.getLevel() == 3) {
                    Area area1 = areaService.findByid(units1.getAreaId());
                    Units father = unitsService.findUnitAreaId(area1.getFatherId());
                    if (supervisorMap.containsKey(father.getUnitId())) {
                        List<SupervisorVo> supervisorVoList1 = supervisorMap.get(father.getUnitId());
                        supervisorVoList1.add(new SupervisorVo(units1.getName(), units1.getUnitId()));
                        supervisorMap.put(father.getUnitId(), supervisorVoList1);
                    } else {
                        supervisorVoList.add(new SupervisorVo(units1.getName(), units1.getUnitId()));
                        supervisorMap.put(father.getUnitId(), supervisorVoList);
                    }
                } else {
                    if (supervisorMap.containsKey(units1.getUnitId())) {
                        List<SupervisorVo> supervisorVoList1 = supervisorMap.get(units1.getUnitId());
                        supervisorMap.put(units1.getUnitId(), supervisorVoList1);
                    } else {
                        supervisorVoList.add(new SupervisorVo(units1.getName(), units1.getUnitId()));
                        supervisorMap.put(units1.getUnitId(), supervisorVoList);
                    }
                }

            });
            List<Integer> unitList = new ArrayList<>();
            unitList.addAll(supervisorMap.keySet());
            deviceRepel.setTaskScope(StringUtils.ListToString(unitList));
            deviceRepel.setTaskScopes(unitList);
            deviceRepel.setEquipmentInvolvingUnit(JacksonUtil.toJSon(supervisorMap));
        }
        DeviceRepel deviceRepel1 = deviceRepelService.saveDeviceRepel(deviceRepel);
        TaskBto taskBto = statsXTask(units.getUnitId(), deviceRepel1.getId(), "清退型号为" + StringSplitUtil.stringListToString(deviceRepel.getModels().stream()
                .distinct()
                .collect(Collectors.toList())) + "设备任务", userId);
        //给本单位其他专管员阅知
//        addMessage(new MessageBto(taskBto.getId(),taskBto.getBusinessType(),user.getName()+"发起清退任务["+deviceRepel1.getTitle()+"]",gainThisUser(userId,units.getUnitId())));
        List<RepelTaskStatistical> list = new ArrayList<>();
        deviceRepel.getTaskScopes().forEach(
                unisId -> {
                    Units units1 = unitsService.findById(unisId);
                    if (unisId != units.getUnitId()) {
                        if (units1.getType() == 2) {
                            directlUnderUnit.set(true);
                            directlUnderUnitNames.add(units1.getName());
//                             directlUnderUnitDeviceIds.addAll(unitNameMap.get(units1.getName()));
                        } else if (units1.getType() == 1) {
                            Area area1 = areaService.findByid(units1.getAreaId());
                            DeviceRepelDetail deviceRepelDetail = new DeviceRepelDetail();
                            deviceRepelDetail.setRepelId(deviceRepel1.getId());
                            deviceRepelDetail.setRepelStatus(1);
                            deviceRepelDetail.setSendUnit(units1.getName());
                            deviceRepelDetail.setSendUnitId(units1.getUnitId());
                            long time = System.currentTimeMillis();
                            Integer count = deviceLibraryService.countAllRepel(deviceRepel.getFieldingIds(), unitsService.findBySubordinateUnitName(units1.getUnitId()), seqNumbers, lifeStatus);
                            if (count != 0) {
                                TaskBto taskBto1 = cityRepelTask(unisId, deviceRepelDetailService.saveDeviceRepelDetail(deviceRepelDetail).getId(), "["+units1.getName()+"]" + "型号为" + StringSplitUtil.stringListToString(deviceRepel.getModels().stream()
                                        .distinct()
                                        .collect(Collectors.toList())) + "设备", taskBto.getId(), userId);
                                list.add(new RepelTaskStatistical(deviceRepel1.getId(), taskBto.getId(), taskBto1.getId(), 0, area1.getName(), repelStatusJudgeCount(deviceRepel.getRepelStatus(), count), ""));
                            }
                        }
                    } else {
                        correspondingLevel.set(true);
                    }
                }
        );
        DeviceRepelDetail deviceRepelDetail = new DeviceRepelDetail();
        deviceRepelDetail.setRepelId(deviceRepel1.getId());
        deviceRepelDetail.setRepelStatus(1);
        deviceRepelDetail.setSendUnitId(units.getUnitId());
        deviceRepelDetail.setSendUnit(units.getName());
        deviceRepelDetail.setRepelType(2);
        Integer count = deviceLibraryService.countAllRepel(deviceRepel.getFieldingIds(), directlUnderUnitNames, seqNumbers, lifeStatus);
        if (directlUnderUnit.get() && count != 0) {
            TaskBto taskBto2 = directlyUnderTask(units.getUnitId(), deviceRepelDetailService.saveDeviceRepelDetail(deviceRepelDetail).getId(), taskBto.getId(), "[省直属相关单位]型号为" + StringSplitUtil.stringListToString(deviceRepel.getModels().stream()
                    .distinct()
                    .collect(Collectors.toList())) + "设备", userId);
            list.add(new RepelTaskStatistical(deviceRepel1.getId(), taskBto.getId(), taskBto2.getId(), 0, "省直属", repelStatusJudgeCount(deviceRepel.getRepelStatus(), count), ""));
        }
        DeviceRepelDetail deviceRepelDetail1 = new DeviceRepelDetail();
        deviceRepelDetail1.setRepelId(deviceRepel1.getId());
        deviceRepelDetail1.setRepelStatus(1);
        deviceRepelDetail1.setSendUnitId(units.getUnitId());
        deviceRepelDetail1.setSendUnit(units.getName());
        List<String> strings = new ArrayList<>();
        strings.add(units.getName());
        deviceRepelDetail1.setRepelType(3);
        count = deviceLibraryService.countAllRepel(deviceRepel.getFieldingIds(), strings, seqNumbers, lifeStatus);
        log.info("[清退] 本级装备件数{}", count);
        if (correspondingLevel.get() && count != 0) {
            TaskBto taskBto1 = oneselfTask(units.getUnitId(), deviceRepelDetailService.saveDeviceRepelDetail(deviceRepelDetail1).getId(), taskBto.getId(), "[省本级]型号为" + StringSplitUtil.stringListToString(deviceRepel.getModels().stream()
                    .distinct()
                    .collect(Collectors.toList())) + "设备", userId);
            list.add(new RepelTaskStatistical(deviceRepel1.getId(), taskBto.getId(), taskBto1.getId(), 0, "省本级", repelStatusJudgeCount(deviceRepel.getRepelStatus(), count), ""));
        }
        if (list == null || list.size() == 0) {
            taskService.moveToSpecial(taskBto, StatusEnum.SEND_BACK_1212, userId);
        }
        repelTaskStatisticalService.saveAllRepelTaskStatistical(list);
    }

    private Integer repelStatusJudgeCount(Integer repelStatus, Integer count) {
        if (repelStatus == 1) {
            return count;
        } else {
            return count;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resolveRepel(DeviceRepel deviceRepel, Integer taskId, Integer userId) {

        // 按照装备给下面区县发起  区清退任务待执行
        // 当前task推送  装备待清退
        // 生成的任务放入统计表中 关联信息
        // 修改当前任务的状态 市清退任务待区县提交
        List<Integer> lifeStatus = new ArrayList<>();
        lifeStatus.add(DeviceLifeStatus.IN_LIBRARY.id);
        lifeStatus.add(DeviceLifeStatus.REPEL.id);
        lifeStatus.add(DeviceLifeStatus.REPAIRING.id);
        lifeStatus.add(DeviceLifeStatus.IN_TRANSIT.id);
        lifeStatus.add(DeviceLifeStatus.USE.id);
        lifeStatus.add(DeviceLifeStatus.SEND_BACK.id);
        User user = userService.findByUser(userId);
        Units units = unitsService.findById(user.getUnitsId());
        Area area = areaService.findByid(units.getAreaId());
        deviceRepel.setFielding(StringUtils.ListToString(deviceRepel.getFieldingIds()));
        deviceRepel.setTaskScope(StringUtils.ListToString(deviceRepel.getTaskScopes()));
        deviceRepel.setFiles(FilesUtil.stringFileToList(deviceRepel.getFileRets()));
        //查询上级任务 判断是否为申请后清退
        TaskBto currentTask = taskService.get(taskId);
        DeviceRepelDetail deviceRepelDetail1 = deviceRepelDetailService.findDeviceRepelDetail(currentTask.getBillId());
        RepelTaskStatistical repelTaskStatistical = repelTaskStatisticalService.findRepelTaskStatistical(currentTask.getId(), deviceRepelDetail1.getRepelId());
        repelTaskStatistical.setTaskStatus(5);
        repelTaskStatisticalService.saveRepelTaskStatistical(repelTaskStatistical);
        taskService.moveToSpecial(currentTask, StatusEnum.SEND_BACK_1206);
        DeviceRepel deviceRepelCurrent = deviceRepelService.findDeviceRepel(deviceRepelDetail1.getRepelId());

        if (deviceRepelCurrent.getEquipmentInvolvingUnit() != null) {
            Map<Integer, List<SupervisorVo>> integerListMap = JacksonUtil.readValue(deviceRepelCurrent.getEquipmentInvolvingUnit(), new TypeReference<Map<Integer, List<SupervisorVo>>>() {
            });
            if (integerListMap.containsKey(units.getUnitId())) {
                deviceRepel.setTaskScopes(integerListMap.get(units.getUnitId()).stream().map(SupervisorVo::getUnitid).collect(Collectors.toList()));
            } else {
                throw new ApiException(ResponseEntity.status(500).body("[申请后清退] 为根据单位ID查询到市分解任务到单位范围:" + currentTask.getId()));
            }
        }
        DeviceRepel deviceRepel1 = deviceRepelService.saveDeviceRepel(deviceRepel);

        TaskBto taskBto = cityTotalTask(units.getUnitId(), deviceRepel1.getId(), "["+units.getName()+"]" + "型号为" + StringSplitUtil.stringListToString(deviceRepel.getModels().stream()
                .distinct()
                .collect(Collectors.toList())) + "设备统计任务", taskId, userId);
//        addMessage(new MessageBto(taskBto.getId(),taskBto.getBusinessType(),user.getName()+"转发清退任务["+deviceRepel1.getTitle()+"]",gainThisUser(userId,units.getUnitId())));

        List<RepelTaskStatistical> list = new ArrayList<>();
        deviceRepel.getTaskScopes().forEach(
                unisId -> {
                    if (unisId != units.getUnitId()) {
                        Units units1 = unitsService.findById(unisId);
                        Area area1 = areaService.findByid(units1.getAreaId());
                        DeviceRepelDetail deviceRepelDetail = new DeviceRepelDetail();
                        deviceRepelDetail.setRepelId(deviceRepel1.getId());
                        deviceRepelDetail.setRepelStatus(1);
                        deviceRepelDetail.setSendUnit(units1.getName());
                        deviceRepelDetail.setSendUnitId(units1.getUnitId());
                        Integer count = deviceLibraryService.countAllRepel(deviceRepel.getFieldingIds(), unitsService.findBySubordinateUnitName(units1.getUnitId()), DeviceSeqUtil.selectDeviceSeqs(deviceRepel.getSeqNumbers()), lifeStatus);
                        if (count != 0) {
                            TaskBto taskBto1 = countyRepelTask(unisId, deviceRepelDetailService.saveDeviceRepelDetail(deviceRepelDetail).getId(), units1.getName() + "清退型号为" + StringSplitUtil.stringListToString(deviceRepel.getModels().stream()
                                    .distinct()
                                    .collect(Collectors.toList())) + "设备", taskBto.getId(), userId);
                            list.add(new RepelTaskStatistical(deviceRepel1.getId(), taskBto.getId(), taskBto1.getId(), 0, area1.getName(), repelStatusJudgeCount(deviceRepel.getRepelStatus(), count), ""));
                        }
                    }
                }
        );
        if (list == null || list.size() == 0) {
            taskService.moveToSpecial(taskBto, StatusEnum.SEND_BACK_1212, userId);
        }
        repelTaskStatisticalService.saveAllRepelTaskStatistical(list);


    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cityInitiateRepel(DeviceRepel deviceRepel, Integer userId) {
        User user = userService.findByUser(userId);
        Units units = unitsService.findById(user.getUnitsId());
        Area area = areaService.findByid(units.getAreaId());
        Units unitsFather = unitsService.findByAreaId(units.getUnitId());
        deviceRepel.setFielding(StringUtils.ListToString(deviceRepel.getFieldingIds()));
        deviceRepel.setTaskScope(StringUtils.ListToString(deviceRepel.getTaskScopes()));
        deviceRepel.setFiles(FilesUtil.stringFileToList(deviceRepel.getFileRets()));
        DeviceRepel deviceRepel1 = deviceRepelService.saveDeviceRepel(deviceRepel);
        DeviceRepelDetail deviceRepelDetail = new DeviceRepelDetail();
        deviceRepelDetail.setRepelId(deviceRepel1.getId());
        deviceRepelDetail.setRepelStatus(1);
        TaskBto taskBto = cityInitiateTask(unitsFather.getUnitId(), deviceRepel1.getId(), deviceRepel.getTitle(), userId);
        addMessage(new MessageBto(taskBto.getId(), taskBto.getBusinessType(), user.getName() + "发起清退任务[" + deviceRepel1.getTitle() + "]", gainThisUser(userId, units.getUnitId())));

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void provinceAuditCity(Integer taskId, Integer userId, RepelAuditResult repelAuditResult) {
//        TaskBto taskBto=taskService.get(taskId);
//        TaskDisposeUtil.isNotSubmit(taskBto.getBillStatus(),StatusEnum.SEND_BACK_1211);
//        List<Integer> lifeStatus=new ArrayList<>();
//        lifeStatus.add(DeviceLifeStatus.IN_LIBRARY.id);
//        lifeStatus.add(DeviceLifeStatus.REPEL.id);
//        lifeStatus.add(DeviceLifeStatus.REPAIRING.id);
//        lifeStatus.add(DeviceLifeStatus.IN_TRANSIT.id);
//        lifeStatus.add(DeviceLifeStatus.USE.id);
//        lifeStatus.add(DeviceLifeStatus.SEND_BACK.id);
//        if (repelAuditResult.getType()==1) {
//            DeviceRepelDetail deviceRepelDetail = deviceRepelDetailService.findDeviceRepelDetailNoDev(taskBto.getBillId());
//            DeviceRepel deviceRepel = deviceRepelService.findDeviceRepel(deviceRepelDetail.getRepelId());
//            Set<ModelCount> modelCounts = new HashSet<>();
//            packingLibraryDao.findAllByIdIn(StringUtils.stringToList(deviceRepel.getFielding())).forEach(i -> {
//                modelCounts.add(new ModelCount(i.getModel(), 0));
//            });
//            String model = JacksonUtil.toJSon(modelCounts);
//            List<RepelTaskStatistical> list = new ArrayList<>();
//            StringUtils.stringToList(deviceRepel.getTaskScope()).forEach(
//                    unisId -> {
//                        if (unisId != deviceRepel.getUnitId()) {
//                            Units units1 = unitsService.findById(unisId);
//                            Area area1 = areaService.findByid(units1.getAreaId());
//                            deviceRepelDetail.setId(null);
//                            deviceRepelDetail.setSendUnit(units1.getName());
//                            deviceRepelDetail.setSendUnitId(units1.getUnitId());
//                            Integer count=deviceLibraryService.countAllRepel(deviceRepel.getFieldingIds(),unitsService.findBySubordinateUnitName(units1.getUnitId()), DeviceSeqUtil.selectDeviceSeqs(deviceRepel.getSeqNumbers()),lifeStatus);
//                            if (count!=0) {
//                                TaskBto taskBto1 = countyRepelTask(unisId, deviceRepelDetailService.saveDeviceRepelDetail(deviceRepelDetail).getId(), deviceRepel.getTitle(), taskBto.getId(),userId);
//                                list.add(new RepelTaskStatistical(deviceRepel.getId(), taskBto.getId(), taskBto1.getId(), 0, area1.getName(), repelStatusJudgeCount(deviceRepel.getRepelStatus(),count), ""));
//                            }
//                        }else {
//                            //同上 缺失
//                        }
//                    }
//            );
//            if (list==null||list.size()==0){
//                taskService.moveToSpecial(taskBto, StatusEnum.SEND_BACK_1212,userId);
//            }else {
//                repelTaskStatisticalService.saveAllRepelTaskStatistical(list);
//                taskBto.setOwnUnit(deviceRepel.getUnitId());
//                taskService.moveToSpecial(taskBto, StatusEnum.SEND_BACK_1204, -1);
//            }
//        }else {
//            taskService.moveToEnd(taskBto);
//        }

    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resolveConfirm(Integer taskId, Integer userId) {

        // 修改当前任务的状态  清退待提交装备审核
        // 修改上级任务是否代办
        // 修改账单详情信息，把装备加入
        // 修改统计表中的数据信息 状态

        User user = userService.findByUser(userId);
        TaskBto taskBto = taskService.get(taskId);
        List<StatusEnum> list = new ArrayList<>();
        list.add(StatusEnum.SEND_BACK_1205);
        list.add(StatusEnum.SEND_BACK_1203);
        list.add(StatusEnum.SEND_BACK_1202);
        list.add(StatusEnum.SEND_BACK_1201);
        list.add(StatusEnum.SEND_BACK_1206);
        TaskDisposeUtil.isNotSubmit(taskBto.getBillStatus(), list);

        DeviceRepelDetail deviceRepelDetail = deviceRepelDetailService.findDeviceRepelDetailNoDev(taskBto.getBillId());
        TaskBto parentTask = taskService.get(taskBto.getParentTaskId());
        taskService.moveToSpecial(parentTask, GlobalMap.getStatusEnumMap().get(parentTask.getBillStatus()), 0);
        taskService.moveToSpecial(taskBto, StatusEnum.SEND_BACK_1207, -1);
        RepelTaskStatistical repelTaskStatistical = repelTaskStatisticalService.findRepelTaskStatistical(taskBto.getId(), deviceRepelDetail.getRepelId());
        repelTaskStatistical.setCount(StringUtils.stringToList(deviceRepelDetail.getDeviceIds()).size());
        repelTaskStatistical.setTaskStatus(3);
        repelTaskStatisticalService.saveRepelTaskStatistical(repelTaskStatistical);
        deviceRepelDetailService.saveDeviceRepelDetail(deviceRepelDetail);
        DeviceRepel deviceRepel = deviceRepelService.findDeviceRepel(deviceRepelDetail.getRepelId());
//        addMessage(new MessageBto(taskBto.getId(),taskBto.getBusinessType(),user.getName()+"操作了["+deviceRepel.getTitle()+"]任务，选择了退回装备",gainThisUser(userId,user.getUnitsId())));
    }

    public static void main(String[] args) {
//        String a="[{\"model\":\"BM-002\",\"count\":0},{\"model\":\"BM-001\",\"count\":0},{\"model\":\"aa\",\"count\":0},{\"model\":\"bb\",\"count\":0}]";
//        List<ModelCount> modelCountList= JacksonUtil.readValue(a, new TypeReference<List<ModelCount>>() {});
//        log.info("---{}",modelCountList.size());
//        boolean flag=  repelTaskStatisticalService.findAllRepelTaskStatistical(589,286).stream().allMatch(e->e.getTaskStatus()!=1);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submitChooseDevice(Integer taskId, ResolveConfirm resolveConfirm) {
        long stime = System.currentTimeMillis();
        TaskBto taskBto = taskService.get(taskId);
        deviceLibraryService.isInStockOrWaitRetired(resolveConfirm.getDevIds());
        List<StatusEnum> list = new ArrayList<>();
        list.add(StatusEnum.SEND_BACK_1205);
        list.add(StatusEnum.SEND_BACK_1203);
        list.add(StatusEnum.SEND_BACK_1202);
        list.add(StatusEnum.SEND_BACK_1201);
        list.add(StatusEnum.SEND_BACK_1206);
        TaskDisposeUtil.isNotSubmit(taskBto.getBillStatus(), list);
        log.info("提交装备接口开始{}", taskId);
        DeviceRepelDetail deviceRepelDetail = deviceRepelDetailService.findDeviceRepelDetailNoDev(taskBto.getBillId());
        RepelTaskStatistical repelTaskStatistical = repelTaskStatisticalService.findRepelTaskStatistical(taskBto.getId(), deviceRepelDetail.getRepelId());
        repelTaskStatistical.setCount(resolveConfirm.getDevIds().size());

        //装备状态改为锁定
        if (resolveConfirm.getDevIds() != null && resolveConfirm.getDevIds().size() != 0) {
            deviceLibraryDao.upDateLockStatus(1, resolveConfirm.getDevIds());
        }
        deviceRepelDetail.setDeviceIds(StringUtils.ListToString(resolveConfirm.getDevIds()));
        if (resolveConfirm.getDes() != null && !resolveConfirm.getDes().equals("")) {
            deviceRepelDetail.setSubmitDescription(resolveConfirm.getDes());
            repelTaskStatistical.setDes(resolveConfirm.getDes());
        }
        repelTaskStatisticalService.saveRepelTaskStatistical(repelTaskStatistical);
        deviceRepelDetailService.saveDeviceRepelDetail(deviceRepelDetail);
        log.info("提交装备接口结束{}", System.currentTimeMillis() - stime);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void resolveAudit(Integer taskId, RepelAuditResult repelAuditResult) {

        // 检查上级任务是完成
        // 修改当前任务的状态 清退提交装备待出库
        // 修改上级任务是否代办
        // 修改统计表中的数据信息 状态

        TaskBto taskBto = taskService.get(taskId);
        TaskDisposeUtil.isNotSubmit(taskBto.getBillStatus(), StatusEnum.SEND_BACK_1207);
        DeviceRepelDetail deviceRepelDetail = deviceRepelDetailService.findDeviceRepelDetail(taskBto.getBillId());
        RepelTaskStatistical repelTaskStatistical = repelTaskStatisticalService.findRepelTaskStatistical(taskBto.getId(), deviceRepelDetail.getRepelId());
        repelTaskStatistical.setTaskStatus(0);

        //1 审核通过
        if (repelAuditResult.getType() == 1) {
            List<Integer> list = StringUtils.stringToList(deviceRepelDetail.getDeviceIds());
            repelTaskStatistical.setTaskStatus(5);
            if (list != null && list.size() != 0) {
                taskService.moveToSpecial(taskBto, StatusEnum.SEND_BACK_1208, 0);
            } else {
                taskBto = taskService.moveToEnd(taskBto);
                deviceRepelDetail.setRepelStatus(3);
                repelTaskStatistical.setTaskStatus(1);
//                addMessage(new MessageBto(taskBto.getId(),taskBto.getBusinessType(),"清退任务审核通过,无提交装备任务结束",findUnitId(taskBto.getOwnUnit())));
            }
        } else {
            //审核失败
            taskService.moveToSpecial(taskBto, StatusEnum.SEND_BACK_1206, 0);
            if (deviceRepelDetail.getDeviceIds() != null && !deviceRepelDetail.getDeviceIds().equals("")) {
                deviceLibraryDao.upDateLockStatus(0, StringUtils.stringToList(deviceRepelDetail.getDeviceIds()));
                deviceRepelDetail.setDeviceIds(null);
            }
        }
        repelTaskStatisticalService.saveRepelTaskStatistical(repelTaskStatistical);
        deviceRepelDetail.setAuditingFeedback(repelAuditResult.getDes());
        deviceRepelDetailService.saveDeviceRepelDetail(deviceRepelDetail);
        // 判读是否还有需要审核待task
        isCommission(taskBto, deviceRepelDetail.getRepelId());
        isEnd(taskBto, deviceRepelDetail.getRepelId());
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public DeviceRepelDetail sendBackOutCheck(Integer taskId, Integer userId, OrderOutData orderOutData) {
        User user = userService.findByUser(userId);
        Units units = unitsService.findById(user.getUnitsId());
        TaskBto taskBto = taskService.get(taskId);
        List<StatusEnum> statusEnums = new ArrayList<>();
        statusEnums.add(StatusEnum.SEND_BACK_1205);
        statusEnums.add(StatusEnum.SEND_BACK_1206);
        statusEnums.add(StatusEnum.SEND_BACK_1208);
        statusEnums.add(StatusEnum.SEND_BACK_1219);
        TaskDisposeUtil.isNotSubmit(taskBto.getBillStatus(), statusEnums);
        DeviceRepelDetail deviceRepelDetail = deviceRepelDetailService.findDeviceRepelDetail(taskBto.getBillId());
        DeviceRepelDetail orderOutDataRepelDetail = orderOutData.toTrainDetailsVo();
        orderOutDataRepelDetail.setId(deviceRepelDetail.getId());
        orderOutDataRepelDetail.setRepelId(deviceRepelDetail.getRepelId());
        orderOutDataRepelDetail.setDeviceIds(deviceRepelDetail.getDeviceIds());
        orderOutDataRepelDetail.setCreateTime(deviceRepelDetail.getCreateTime());
        orderOutDataRepelDetail.setCreateUserId(deviceRepelDetail.getCreateUserId());
        orderOutDataRepelDetail.setRightSignatureId(UUID.randomUUID().toString());
        orderOutDataRepelDetail.setNum("NO:第" + LocalDateTime.now().getYear() + "QT" + taskBto.getBillId());
        orderOutDataRepelDetail.setReplyFiles(FilesUtil.stringFileToList(orderOutData.getReplyFileList()));
        orderOutDataRepelDetail.setSendFiles(FilesUtil.stringFileToList(orderOutData.getSendFileList()));
        orderOutDataRepelDetail.setScriptJson(JacksonUtil.toJSon(orderOutData.getScriptSaveVos()));
        orderOutDataRepelDetail.setScripts(orderOutData.getScriptSaveVos());
        orderOutDataRepelDetail.setReplyFiles(FilesUtil.stringFileToList(orderOutData.getReplyFileList()));
        orderOutDataRepelDetail.setApplyFiles(FilesUtil.stringFileToList(orderOutData.getApplyFileList()));
        deviceRepelDetailService.saveDeviceRepelDetail(orderOutDataRepelDetail);
        deviceLibraryDao.upDateLeftStatus(DeviceLifeStatus.SEND_BACK_IN.id, StringUtils.stringToList(orderOutDataRepelDetail.getDeviceIds()));
        taskBto.setCreateUserId(userId);
        taskBto.setOwnUnit(orderOutData.getReceiveUnitId());
        taskService.moveToSpecial(taskBto, StatusEnum.SEND_BACK_1209, 0);
        DeviceRepel deviceRepel = deviceRepelService.findDeviceRepel(deviceRepelDetail.getRepelId());
        waitingReceiptsTask(orderOutData.getSendUnitId(), deviceRepelDetail.getId(), taskBto.getId(), taskBto.getTitle(), userId);
        addMessage(new MessageBto(taskBto.getId(), taskBto.getBusinessType(), "清退设备出库完成", gainThisUser(userId, user.getUnitsId())));
        devLogAdd(findInvoleDevice(deviceRepelDetail.getDeviceIds()), deviceRepelDetail.getSendUnit() + "装备清退出库" + "，等待接收", userId, taskBto.getId());
        orderOutDataRepelDetail.setDeviceLibraryEntities(findInvoleDevice(deviceRepelDetail.getDeviceIds()));
        //把一些字段填写到对象中，保存入库
        //把任务状态修改为 清退提交装备待接收
        return orderOutDataRepelDetail;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void sealOfAudit(Integer taskId, Integer userId, OrderOutData orderOutData) {
        TaskBto taskBto = taskService.get(taskId);
        MemberThat memberThat = userService.findById(orderOutData.getSendUserbId());
        List<StatusEnum> statusEnums = new ArrayList<>();
        statusEnums.add(StatusEnum.SEND_BACK_1205);
        statusEnums.add(StatusEnum.SEND_BACK_1206);
        statusEnums.add(StatusEnum.SEND_BACK_1208);
        TaskDisposeUtil.isNotSubmit(taskBto.getBillStatus(), statusEnums);
        DeviceRepelDetail deviceRepelDetail = deviceRepelDetailService.findDeviceRepelDetail(taskBto.getBillId());
        DeviceRepelDetail orderOutDataRepelDetail = orderOutData.toTrainDetailsVo();
        orderOutDataRepelDetail.setId(deviceRepelDetail.getId());
        orderOutDataRepelDetail.setRepelId(deviceRepelDetail.getRepelId());
        orderOutDataRepelDetail.setCreateTime(deviceRepelDetail.getCreateTime());
        orderOutDataRepelDetail.setCreateUserId(deviceRepelDetail.getCreateUserId());
        orderOutDataRepelDetail.setDeviceIds(deviceRepelDetail.getDeviceIds());
        orderOutDataRepelDetail.setRightSignatureId(UUID.randomUUID().toString());
        orderOutDataRepelDetail.setNum("NO:第" + LocalDateTime.now().getYear() + "QT" + taskBto.getBillId());
        orderOutDataRepelDetail.setReplyFiles(FilesUtil.stringFileToList(orderOutData.getReplyFileList()));
        orderOutDataRepelDetail.setSendFiles(FilesUtil.stringFileToList(orderOutData.getSendFileList()));
        orderOutDataRepelDetail.setScriptJson(JacksonUtil.toJSon(orderOutData.getScriptSaveVos()));
        orderOutDataRepelDetail.setScripts(orderOutData.getScriptSaveVos());
        orderOutDataRepelDetail.setReplyFiles(FilesUtil.stringFileToList(orderOutData.getReplyFileList()));
        orderOutDataRepelDetail.setApplyFiles(FilesUtil.stringFileToList(orderOutData.getApplyFileList()));
        deviceRepelDetailService.saveDeviceRepelDetail(orderOutDataRepelDetail);
        taskService.moveToSpecial(taskBto, StatusEnum.SEND_BACK_1217, orderOutData.getSendUserbId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void sendSealOfAudit(Integer taskId, Integer userId, StorageDeviceRepel storageDeviceRepel) {
        TaskBto taskBto = taskService.get(taskId);
        List<StatusEnum> enumList = new ArrayList<>();
        enumList.add(StatusEnum.SEND_BACK_1209);
        enumList.add(StatusEnum.SEND_BACK_1213);
        enumList.add(StatusEnum.SEND_BACK_1215);
        TaskDisposeUtil.isNotSubmit(taskBto.getBillStatus(), enumList);
        DeviceRepelDetail deviceRepelDetail = deviceRepelDetailService.findDeviceRepelDetail(taskBto.getBillId());
        if (storageDeviceRepel.getUserBName() != null) {
            deviceRepelDetail.setReceiveUserB(storageDeviceRepel.getUserBName());
        }
        if (storageDeviceRepel.getUserB() != null) {
            deviceRepelDetail.setReceiveUserbId(storageDeviceRepel.getUserB());
        }
        if (storageDeviceRepel.getUserAName() != null) {
            deviceRepelDetail.setReceiveUserA(storageDeviceRepel.getUserAName());
        }
        if (storageDeviceRepel.getUserA() != null) {
            deviceRepelDetail.setReceiveUseraId(storageDeviceRepel.getUserA());
        }
        deviceRepelDetailService.saveDeviceRepelDetail(deviceRepelDetail);
        taskService.moveToSpecial(taskBto, StatusEnum.SEND_BACK_1220, storageDeviceRepel.getUserB());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void outSealOfAuditEnd(Integer taskId, Integer reviewTheResults) {
        TaskBto taskBto = taskService.get(taskId);
        if (reviewTheResults == 0) {
            taskService.moveToSpecial(taskBto, StatusEnum.SEND_BACK_1219, 0);
        } else {
            DeviceRepelDetail deviceRepelDetail = deviceRepelDetailService.findDeviceRepelDetail(taskBto.getBillId());
            deviceRepelDetail.setSenderUserB(null);
            deviceRepelDetail.setSendUserbId(null);
            deviceRepelDetailService.saveDeviceRepelDetail(deviceRepelDetail);
            taskService.moveToSpecial(taskBto, StatusEnum.SEND_BACK_1208, deviceRepelDetail.getSendUseraId());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void sendSealOfAuditEnd(Integer taskId, Integer reviewTheResults) {
        TaskBto taskBto = taskService.get(taskId);
        if (reviewTheResults == 0) {
            taskService.moveToSpecial(taskBto, StatusEnum.SEND_BACK_1218, 0);
        } else {
            DeviceRepelDetail deviceRepelDetail = deviceRepelDetailService.findDeviceRepelDetail(taskBto.getBillId());
            deviceRepelDetail.setReceiveUserbId(null);
            deviceRepelDetail.setReceiveUserB(null);
            deviceRepelDetailService.saveDeviceRepelDetail(deviceRepelDetail);
            taskService.moveToSpecial(taskBto, StatusEnum.SEND_BACK_1209, deviceRepelDetail.getReceiveUseraId());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void storageDeviceRepel(Integer taskId, StorageDeviceRepel storageDeviceRepel) {
        //判断是否上传单据
        //是 直接入库 任务完结
        //否 状态改为入库待补充文件
        //修改统计表中的数据信息 状态
        User user = userService.findByUser(storageDeviceRepel.getUserId());
        Units units = unitsService.findById(user.getUnitsId());
        List<RepelDeviceUnit> list = new ArrayList<>();
        TaskBto taskBto = taskService.get(taskId);
        DeviceRepelDetail deviceRepelDetail = deviceRepelDetailService.findDeviceRepelDetail(taskBto.getBillId());
        DeviceRepel deviceRepel = deviceRepelService.findDeviceRepel(deviceRepelDetail.getRepelId());
        if (storageDeviceRepel.getUserBName() != null) {
            deviceRepelDetail.setReceiveUserB(storageDeviceRepel.getUserBName());
        }
        if (storageDeviceRepel.getUserB() != null) {
            deviceRepelDetail.setReceiveUserbId(storageDeviceRepel.getUserB());
        }
        if (storageDeviceRepel.getUserA() != null) {
            deviceRepelDetail.setReceiveUseraId(storageDeviceRepel.getUserA());
        }
        if (storageDeviceRepel.getUserAName() != null) {
            deviceRepelDetail.setReceiveUserA(storageDeviceRepel.getUserAName());
        }
        if (storageDeviceRepel.getSenderId() != null) {
            deviceRepelDetail.setSendUserbId(storageDeviceRepel.getSenderId());
        }
        if (storageDeviceRepel.getSenderName() != null) {
            deviceRepelDetail.setSenderUserB(storageDeviceRepel.getSenderName());
        }
        //获取相关单位的id集合
        List<Integer> unitIds = new ArrayList<>();
        unitIds.add(deviceRepelDetail.getSendUnitId());
        unitIds.add(deviceRepelDetail.getReceiveUnitId());

        //判断是否为入库单据待补充 还是直接入库。
        RepelTaskStatistical repelTaskStatistical = repelTaskStatisticalService.findRepelTaskStatistical(taskBto.getId(), deviceRepelDetail.getRepelId());
        if (storageDeviceRepel.getFileRets() != null && storageDeviceRepel.getFileRets().size() != 0) {
            List<StatusEnum> enumList = new ArrayList<>();
            enumList.add(StatusEnum.SEND_BACK_1209);
            enumList.add(StatusEnum.SEND_BACK_1213);
            enumList.add(StatusEnum.SEND_BACK_1215);
            enumList.add(StatusEnum.SEND_BACK_1218);
            TaskDisposeUtil.isNotSubmit(taskBto.getBillStatus(), enumList);
            deviceRepelDetail.setBillFile(FilesUtil.stringFileToList(storageDeviceRepel.getFileRets()));
            deviceRepelDetail.setRepelStatus(2);
            repelTaskStatistical.setTaskStatus(1);

            if (units.getLevel() == 1) {
                deviceLibraryDao.upDateLeftStatusAndUnitNameAndLockStatus(filterTypeReturnLeftStatus(deviceRepel.getType()), deviceRepelDetail.getReceiveUnit(), 0, StringUtils.stringToList(deviceRepelDetail.getDeviceIds()));
            } else {
                deviceLibraryDao.upDateLeftStatusAndUnitNameAndLockStatus(DeviceLifeStatus.IN_LIBRARY.id, deviceRepelDetail.getReceiveUnit(), 0, StringUtils.stringToList(deviceRepelDetail.getDeviceIds()));
            }
            List<DeviceLibrary> libraries = findInvoleDevice(deviceRepelDetail.getDeviceIds());
            libraries.forEach(
                    deviceLibrary -> {
                        list.add(new RepelDeviceUnit(deviceLibrary.getId(), deviceRepelDetail.getSendUnitId()));
                    });
            //添加根据type修改装备状态
            repelDeviceUnitService.saveAllRepelDeviceUnit(list);
            taskService.moveToEnd(taskBto);
            taskService.moveToEnd(taskService.findBillTypeAndFatherId(BusinessEnum.SEND_BACK.id, taskId));
            taskService.moveToArchive(taskService.findBillTypeAndFatherId(BusinessEnum.SEND_BACK.id, taskId));
            devLogAdd(findInvoleDevice(deviceRepelDetail.getDeviceIds()), "签收" + deviceRepelDetail.getSendUnit() + "清退的设备", storageDeviceRepel.getUserId(), taskBto.getId());
            addMessage(new MessageBto(taskBto.getId(), taskBto.getBusinessType(), "签收" + deviceRepelDetail.getSendUnit() + "清退的设备", findUnitIds(user.getUserId(), unitIds)));
        } else {
            if (storageDeviceRepel.getIsIgnore() == null) {
                List<StatusEnum> enumList = new ArrayList<>();
                enumList.add(StatusEnum.SEND_BACK_1209);
                enumList.add(StatusEnum.SEND_BACK_1218);
                //判断当前状态是否为SEND_BACK_1209 清退装备等待入库
                TaskDisposeUtil.isNotSubmit(taskBto.getBillStatus(), enumList);
                repelTaskStatistical.setTaskStatus(4);
                taskService.moveToSpecial(taskBto, StatusEnum.SEND_BACK_1215, 0);
            } else {
                repelTaskStatistical.setTaskStatus(1);

                if (units.getLevel() == 1) {
                    deviceLibraryDao.upDateLeftStatusAndUnitNameAndLockStatus(filterTypeReturnLeftStatus(deviceRepel.getType()), deviceRepelDetail.getReceiveUnit(), 0, StringUtils.stringToList(deviceRepelDetail.getDeviceIds()));
                } else {
                    deviceLibraryDao.upDateLeftStatusAndUnitNameAndLockStatus(DeviceLifeStatus.SEND_BACK.id, deviceRepelDetail.getReceiveUnit(), 0, StringUtils.stringToList(deviceRepelDetail.getDeviceIds()));
                }
                taskService.moveToEnd(taskBto);
                taskService.moveToEnd(taskService.findBillTypeAndFatherId(BusinessEnum.SEND_BACK.id, taskId));
                taskService.moveToArchive(taskService.findBillTypeAndFatherId(BusinessEnum.SEND_BACK.id, taskId));
                devLogAdd(findInvoleDevice(deviceRepelDetail.getDeviceIds()), "签收" + deviceRepelDetail.getSendUnit() + "清退的设备", storageDeviceRepel.getUserId(), taskBto.getId());
                Documents documents = deviceRepelDetail.toDoc();
                documents.setSrcA(storageDeviceRepel.getSrcA());
                documents.setSrcB(storageDeviceRepel.getSrcB());
                documents.setScriptSaveVos(JacksonUtil.readValue(deviceRepelDetail.getScriptJson(), new TypeReference<List<ScriptSaveVo>>() {
                }));
                List<DeviceLibrary> libraries = findInvoleDevice(deviceRepelDetail.getDeviceIds());
                libraries.forEach(
                        deviceLibrary -> {
                            list.add(new RepelDeviceUnit(deviceLibrary.getId(), deviceRepelDetail.getSendUnitId()));
                        }
                );
                //添加根据type修改装备状态
                repelDeviceUnitService.saveAllRepelDeviceUnit(list);
                FileRet fileRet = pdfService.billPdf(documents);
                deviceRepelDetail.setOutboundFile(JacksonUtil.toJSon(fileRet));
                deviceRepelDetail.setSendFiles(JacksonUtil.toJSon(fileRet));
                addMessage(new MessageBto(taskBto.getId(), taskBto.getBusinessType(), "签收" + deviceRepelDetail.getSendUnit() + "清退的设备", findUnitIds(user.getUserId(), unitIds)));
            }
        }
        deviceRepelDetail.setReceiveTime(new Date());
        repelTaskStatisticalService.saveRepelTaskStatistical(repelTaskStatistical);
        deviceRepelDetailService.saveDeviceRepelDetail(deviceRepelDetail);
        isEnd(taskBto, deviceRepelDetail.getRepelId());

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void oneselfRepel(Integer taskId, StorageDeviceRepel storageDeviceRepel, Integer userId) {

        //完结当前任务
        //修改统计表中的数据信息 状态
        //把装备的状态都修改为待清退。

        User user = userService.findByUser(userId);
        Units units = unitsService.findById(user.getUnitsId());
        List<RepelDeviceUnit> list = new ArrayList<>();
        TaskBto taskBto = taskService.get(taskId);
        List<StatusEnum> enumList = new ArrayList<>();
        enumList.add(StatusEnum.SEND_BACK_1213);
        enumList.add(StatusEnum.SEND_BACK_1203);
        TaskDisposeUtil.isNotSubmit(taskBto.getBillStatus(), enumList);

        DeviceRepelDetail deviceRepelDetail = deviceRepelDetailService.findDeviceRepelDetail(taskBto.getBillId());
        deviceRepelDetail.setBillFile(FilesUtil.stringFileToList(storageDeviceRepel.getFileRets()));
        deviceRepelDetail.setRepelStatus(2);
        taskService.moveToEnd(taskBto);
        DeviceRepel deviceRepel = deviceRepelService.findDeviceRepel(deviceRepelDetail.getRepelId());
        if (storageDeviceRepel.getDeviceIds() != null && storageDeviceRepel.getDeviceIds().size() != 0) {
            StringBuffer ids = new StringBuffer();
            List<DeviceLibrary> libraries = deviceLibraryDao.getDeviceLibraryEntitiesByIdIn(storageDeviceRepel.getDeviceIds());
            libraries.forEach(
                    deviceLibrary -> {
                        ids.append(",").append(deviceLibrary.getId());
                    }
            );
            log.info("更新数据装备以及所属单位-{}", libraries.size());
            long time = System.currentTimeMillis();
            if (units.getLevel() == 2) {
                deviceLibraryDao.upDateLeftStatusAndUnitNameAndLockStatus(DeviceLifeStatus.SEND_BACK.id, deviceRepelDetail.getSendUnit(), 0, StringUtils.stringToList(deviceRepelDetail.getDeviceIds()));
            } else {
                deviceLibraryDao.upDateLeftStatusAndUnitNameAndLockStatus(filterTypeReturnLeftStatus(deviceRepel.getType()), deviceRepelDetail.getSendUnit(), 0, StringUtils.stringToList(deviceRepelDetail.getDeviceIds()));
                log.info("更新数据装备以及所属单位{}", System.currentTimeMillis() - time);
            }
            devLogAdd(libraries, "省本级清退，把装备转变为待清退", userId, taskId);

        }
        RepelTaskStatistical repelTaskStatistical = repelTaskStatisticalService.findRepelTaskStatistical(taskBto.getId(), deviceRepelDetail.getRepelId());
        repelTaskStatistical.setTaskStatus(1);
        repelTaskStatisticalService.saveRepelTaskStatistical(repelTaskStatistical);
        deviceRepelDetailService.saveDeviceRepelDetail(deviceRepelDetail);
        isEnd(taskBto, deviceRepelDetail.getRepelId());
//        addMessage(new MessageBto(taskBto.getId(),taskBto.getBusinessType(),"完成["+deviceRepel.getTitle()+"]本级清退任务",gainThisUser(user.getUserId(),user.getUnitsId())));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void provinceDirectlyUnder(Integer taskId, SecurityUser securityUser) {
        TaskBto taskBto = taskService.get(taskId);
        TaskDisposeUtil.isNotSubmit(taskBto.getBillStatus(), StatusEnum.SEND_BACK_1202);
        DeviceRepelDetail deviceRepelDetail = deviceRepelDetailService.findDeviceRepelDetail(taskBto.getBillId());
        DeviceRepel deviceRepel = deviceRepelService.findDeviceRepel(deviceRepelDetail.getRepelId());
        Map<String, List<Integer>> map = new HashMap<>();
        List<DeviceLibrary> libraries = deviceLibraryDao.getDeviceLibraryEntitiesByIdIn(StringUtils.stringToList(deviceRepelDetail.getDeviceIds()));

        libraries.forEach(
                deviceLibrary -> {
                    if (map.containsKey(deviceLibrary.getOwnUnit())) {
                        List<Integer> list = map.get(deviceLibrary.getOwnUnit());
                        list.add(deviceLibrary.getId());
                        map.put(deviceLibrary.getOwnUnit(), list);
                    } else {
                        List<Integer> list = new ArrayList<>();
                        list.add(deviceLibrary.getId());
                        map.put(deviceLibrary.getOwnUnit(), list);
                    }
                }
        );
        deviceRepelDetail.setDirectlyUnderDevices(JacksonUtil.toJSon(map));
        deviceRepelDetailService.saveDeviceRepelDetail(deviceRepelDetail);
        devLogAdd(libraries, "省直属清退，把装备转变为待清退", securityUser.getCurrentUserInfo().getUserId(), taskBto.getId());
        deviceLibraryDao.upDateLeftStatusAndLockStatus(filterTypeReturnLeftStatus(deviceRepel.getType()), 0, StringUtils.stringToList(deviceRepelDetail.getDeviceIds()));
        taskService.moveToSpecial(taskBto, StatusEnum.SEND_BACK_1213, 0);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void provinceRepel(Integer taskId) {
        taskService.moveToEnd(taskService.get(taskId));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cityRepelEnd(Integer taskId) {
        TaskBto taskBto = taskService.get(taskId);
        List<StatusEnum> enumList = new ArrayList<>();
        enumList.add(StatusEnum.SEND_BACK_1200);
        enumList.add(StatusEnum.SEND_BACK_1212);
        enumList.add(StatusEnum.SEND_BACK_1204);
        TaskDisposeUtil.isNotSubmit(taskBto.getBillStatus(), enumList);
        taskService.moveToEnd(taskService.get(taskId));
        DeviceRepel deviceRepel = deviceRepelService.findDeviceRepel(taskBto.getBillId());
        deviceRepel.setStatus(1);
        deviceRepelService.saveDeviceRepel(deviceRepel);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void receipts(StorageDeviceRepel storageDeviceRepel) {
        User user = userService.findByUser(storageDeviceRepel.getUserId());
        Units units = unitsService.findById(user.getUnitsId());
        TaskBto taskBto = taskService.get(storageDeviceRepel.getTaskId());
        TaskDisposeUtil.isNotSubmit(taskBto.getBillStatus(), StatusEnum.SEND_BACK_1214);
        taskService.moveToEnd(taskBto);
        taskService.moveToArchive(taskBto);
        DeviceRepelDetail deviceRepelDetail = deviceRepelDetailService.findDeviceRepelDetail(taskBto.getBillId());
        DeviceRepel deviceRepel = deviceRepelService.findDeviceRepel(deviceRepelDetail.getRepelId());
        if (storageDeviceRepel.getSenderName() != null) {
            deviceRepelDetail.setSenderUserB(storageDeviceRepel.getSenderName());
        }
        if (storageDeviceRepel.getSenderId() != null) {
            deviceRepelDetail.setSendUserbId(storageDeviceRepel.getSenderId());
        }
        deviceRepelDetail.setOutboundFile(FilesUtil.stringFileToList(storageDeviceRepel.getOutFiles()));

        if (storageDeviceRepel.getUserBName() != null) {
            deviceRepelDetail.setReceiveUserB(storageDeviceRepel.getUserBName());
        }
        if (storageDeviceRepel.getUserB() != null) {
            deviceRepelDetail.setReceiveUserbId(storageDeviceRepel.getUserB());
        }
        if (storageDeviceRepel.getUserA() != null) {
            deviceRepelDetail.setReceiveUseraId(storageDeviceRepel.getUserA());
        }
        if (storageDeviceRepel.getUserAName() != null) {
            deviceRepelDetail.setReceiveUserA(storageDeviceRepel.getUserAName());
        }
        if (units.getLevel() == 3) {
            deviceLibraryDao.upDateLeftStatusAndUnitNameAndLockStatus(DeviceLifeStatus.IN_LIBRARY.id, deviceRepelDetail.getReceiveUnit(), 0, StringUtils.stringToList(deviceRepelDetail.getDeviceIds()));
        } else {
            deviceLibraryDao.upDateLeftStatusAndUnitNameAndLockStatus(filterTypeReturnLeftStatus(deviceRepel.getType()), deviceRepelDetail.getReceiveUnit(), 0, StringUtils.stringToList(deviceRepelDetail.getDeviceIds()));
        }
        deviceRepelDetail.setRepelStatus(2);
        TaskBto fatherTask = taskService.get(taskBto.getParentTaskId());
        taskService.moveToEnd(fatherTask);
        deviceRepelDetail.setReceiveTime(new Date());
        DeviceRepelDetail deviceRepelDetailFather = deviceRepelDetailService.findDeviceRepelDetail(fatherTask.getBillId());
        RepelTaskStatistical repelTaskStatistical = repelTaskStatisticalService.findRepelTaskStatistical(fatherTask.getId(), deviceRepelDetailFather.getRepelId());
        repelTaskStatistical.setTaskStatus(1);
        repelTaskStatisticalService.saveRepelTaskStatistical(repelTaskStatistical);
        isEnd(fatherTask, deviceRepelDetailFather.getRepelId());
        deviceRepelDetailService.saveDeviceRepelDetail(deviceRepelDetail);
        List<Integer> unitIds = new ArrayList<>();
        unitIds.add(deviceRepelDetail.getSendUnitId());
        unitIds.add(deviceRepelDetail.getReceiveUnitId());
        addMessage(new MessageBto(taskBto.getId(), taskBto.getBusinessType(), "装备清退任务,出库方上传了回执单据任务结束", findUnitIds(storageDeviceRepel.getUserId(), unitIds)));
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addSendBUser(StorageDeviceRepel storageDeviceRepel) {
        TaskBto taskBto = taskService.get(storageDeviceRepel.getTaskId());
        TaskDisposeUtil.isNotSubmit(taskBto.getBillStatus(), StatusEnum.SEND_BACK_1214);
        DeviceRepelDetail deviceRepelDetail = deviceRepelDetailService.findDeviceRepelDetail(taskBto.getBillId());
        deviceRepelDetail.setSenderUserB(storageDeviceRepel.getUserBName());
        deviceRepelDetail.setSendUserbId(storageDeviceRepel.getUserB());
        addMessage(new MessageBto(taskBto.getId(), taskBto.getBusinessType(), "选择了你为签发人请阅知", new ArrayList<>(storageDeviceRepel.getUserB())));
        deviceRepelDetailService.saveDeviceRepelDetail(deviceRepelDetail);
    }


    @Override
    public void directlyRetired(List<Integer> ids) {
        //更新所选装备的生命状态
        //给同级专管员推送阅知
        //装备在待退役中展示
        //任务完结
        deviceLibraryDao.upDateLeftStatus(DeviceLifeStatus.REPEL.id, ids);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void AllRepelNotDeviceSubmit(SecurityUser securityUser, Integer taskId) {

        TaskBto taskBto = taskService.get(taskId);
        List<StatusEnum> enumList = new ArrayList<>();
        enumList.add(StatusEnum.SEND_BACK_1205);
        enumList.add(StatusEnum.SEND_BACK_1203);
        enumList.add(StatusEnum.SEND_BACK_1206);
        enumList.add(StatusEnum.SEND_BACK_1208);
        TaskDisposeUtil.isNotSubmit(taskBto.getBillStatus(), enumList);
        DeviceRepelDetail deviceRepelDetail = deviceRepelDetailService.findDeviceRepelDetail(taskBto.getBillId());
        deviceRepelDetail.setRepelStatus(3);
        taskService.moveToEnd(taskBto);
        RepelTaskStatistical repelTaskStatistical = repelTaskStatisticalService.findRepelTaskStatistical(taskBto.getId(), deviceRepelDetail.getRepelId());
        repelTaskStatistical.setTaskStatus(1);
        repelTaskStatistical.setCount(0);
        repelTaskStatisticalService.saveRepelTaskStatistical(repelTaskStatistical);
        deviceRepelDetailService.saveDeviceRepelDetail(deviceRepelDetail);
        isEnd(taskBto, deviceRepelDetail.getRepelId());
//        addMessage(new MessageBto(taskBto.getId(),taskBto.getBusinessType(),"本单位无装备提交，完成了清退任务",gainThisUser(securityUser.getCurrentUserInfo().getUserId(),securityUser.getCurrentUserInfo().getUnitsId())));


    }

    @Override
    public void withdraw(Integer taskId) {
        TaskBto taskBto = taskService.get(taskId);
        Units units = unitsService.findById(taskBto.getOwnUnit());
        TaskBto fatherTaskBto = taskService.get(taskBto.getParentTaskId());
        Task task = taskBto.toDo();
        task.setDeleteTag(1);
        taskService.deleteById(task);
        DeviceRepelDetail deviceRepelDetail = deviceRepelDetailService.findDeviceRepelDetailNoDev(taskBto.getBillId());
        deviceLibraryDao.upDateLeftStatus(DeviceLifeStatus.IN_LIBRARY.id, StringUtils.stringToList(deviceRepelDetail.getDeviceIds()));
        fatherTaskBto.setOwnUnit(units.getUnitId());
        if (units.getLevel() == 3) {
            taskService.moveToSpecial(fatherTaskBto, StatusEnum.SEND_BACK_1205, 0);
        } else {
            taskService.moveToSpecial(fatherTaskBto, StatusEnum.SEND_BACK_1206, 0);

        }
    }

    @Override
    public List<TaskBto>  repelWithdraw(Integer taskId) {
        //首先查询总任务，把清退任务都查询出来
        //SEND_BACK_1209 SEND_BACK_1215 SEND_BACK_1218 SEND_BACK_1220
//        TaskBto taskBto = taskService.get(taskId);
//        DeviceRepel deviceRepel=deviceRepelService.findDeviceRepel(taskBto.getBillId());
        //市级清退16查询
        List<Integer> statusList=new ArrayList<>();
        statusList.add(StatusEnum.SEND_BACK_1209.id);
        statusList.add(StatusEnum.SEND_BACK_1215.id);
        statusList.add(StatusEnum.SEND_BACK_1218.id);
        statusList.add(StatusEnum.SEND_BACK_1220.id);
        List<TaskBto> taskBtoList = taskService.findAllBillTypeAndFatherId(BusinessEnum.SEND_BACK.id,taskId);
        List<Integer>  ids=taskBtoList.stream().map(TaskBto::getId).collect(Collectors.toList());
        //市级清退统计任务集合
        List<TaskBto> statisticalList = taskService.findAllBillTypeAndFatherIdIn(BusinessEnum.SEND_BACK_STATISTICAL.id,ids);
        ids= statisticalList.stream().map(TaskBto::getId).collect(Collectors.toList());
        taskBtoList.addAll( taskService.findAllBillTypeAndFatherIdIn(BusinessEnum.SEND_BACK.id,ids));
        boolean flag = taskBtoList.stream().allMatch(taskBto -> !statusList.contains(taskBto.getBillStatus()));
//        log.info("test ：{}",flag);
        if (flag){
            //可以使用
        }else {
            //不可以撤回
        }
        //判断是否存在为哪些状态为不能清退
        //不能清退都则返回否 告诉前端本次存在不能撤回都情况
        //可以撤回 需要把所有都相关任务封存
        return taskBtoList;
    }



    /**
     * service私有方式
     * 只限本service使用 提供装备修改的leftStatus的装备类型
     * 主要用于清退到省的时候
     * 主任务的type为0时 在库 为1时 待退役 为2 待报废 为3 待销毁
     */
    private Integer filterTypeReturnLeftStatus(Integer type) {
        switch (type) {
            case 0:
                return DeviceLifeStatus.IN_LIBRARY.id;
            case 1:
                return DeviceLifeStatus.REPEL.id;
            case 2:
                return DeviceLifeStatus.TO_BE_SCRAPPED.id;
            case 3:
                return DeviceLifeStatus.TO_BE_DESTROYED.id;
        }
        return 0;
    }


    /**
     * 生成区清退任务
     *
     * @param unitId        执行单位id
     * @param repelDetailId 账单id
     * @param title         标题
     * @param parentTaskId  上级任务ID
     * @return TaskBto
     */
    private TaskBto countyRepelTask(Integer unitId, Integer repelDetailId, String title, Integer parentTaskId, Integer userId) {
        //省清退任务待市提交
        List<Integer> list = new ArrayList<>();
        list.add(userId);
        list.add(0);
        return taskService.start(new TaskBto(StatusEnum.SEND_BACK_1205.id, title, parentTaskId, ".", repelDetailId, BusinessEnum.SEND_BACK.id, unitId, 1, "", list));
    }

    /**
     * 市发起清退
     *
     * @param unitId
     * @param repelDetailId
     * @param title
     * @return
     */
    private TaskBto cityInitiateTask(Integer unitId, Integer repelDetailId, String title, Integer userId) {
        //省清退任务待市提交
        List<Integer> list = new ArrayList<>();
        list.add(userId);
        list.add(0);
        return taskService.start(new TaskBto(StatusEnum.SEND_BACK_1211.id, title, null, ".", repelDetailId, BusinessEnum.SEND_BACK_STATISTICAL.id, unitId, 0, "", list));
    }

    /**
     * 市的清退统计任务任务 17
     *
     * @param unitId
     * @param repelDetailId
     * @param title
     * @return
     */
    private TaskBto cityTotalTask(Integer unitId, Integer repelDetailId, String title, Integer parentId, Integer userId) {
        List<Integer> list = new ArrayList<>();
        list.add(userId);
        list.add(-1);
        return taskService.start(new TaskBto(StatusEnum.SEND_BACK_1204.id, title, parentId, ".", repelDetailId, BusinessEnum.SEND_BACK_STATISTICAL.id, unitId, 1, "shi", list));
    }

    /**
     * 省的清退总任务 17
     *
     * @param unitId
     * @param repelDetailId
     * @param title
     * @return
     */
    private TaskBto statsXTask(Integer unitId, Integer repelDetailId, String title, Integer userId) {
        //省清退任务待市提交
        List<Integer> list = new ArrayList<>();
        list.add(userId);
        list.add(-1);
        return taskService.start(new TaskBto(StatusEnum.SEND_BACK_1200.id, title, null, ".", repelDetailId, BusinessEnum.SEND_BACK_STATISTICAL.id, unitId, 1, "", list));
    }

    /**
     * 省对市发起的清退 市清退任务待执行 16
     *
     * @param unitId        执行单位id
     * @param repelDetailId 账单id 详情
     * @param title         标题
     * @return task对象
     */
    private TaskBto cityRepelTask(Integer unitId, Integer repelDetailId, String title, Integer parentTaskId, Integer userId) {
        List<Integer> list = new ArrayList<>();
        list.add(userId);
        list.add(0);
        return taskService.start(new TaskBto(StatusEnum.SEND_BACK_1201.id, title, parentTaskId, ".", repelDetailId, BusinessEnum.SEND_BACK.id, unitId, 1, "", list));
    }


    /**
     * 清退出库等待上传回执单
     *
     * @param unitId
     * @param repelDetailId
     * @param parentTaskId
     * @return
     */
    private TaskBto waitingReceiptsTask(Integer unitId, Integer repelDetailId, Integer parentTaskId, String title, Integer userId) {
        List<Integer> list = new ArrayList<>();
        list.add(userId);
        list.add(0);
        return taskService.start(new TaskBto(StatusEnum.SEND_BACK_1214.id, title, parentTaskId, ".", repelDetailId, BusinessEnum.SEND_BACK.id, unitId, 1, "", list));
    }


    /**
     * 省直属单位任务 省自己完成 16
     *
     * @param unitId        执行单位
     * @param repelDetailId 账单详情id
     * @param parentTaskId  上级taskid
     * @return TaskBto
     */
    private TaskBto directlyUnderTask(Integer unitId, Integer repelDetailId, Integer parentTaskId, String title, Integer userId) {
        List<Integer> list = new ArrayList<>();
        list.add(userId);
        list.add(0);
        return taskService.start(new TaskBto(StatusEnum.SEND_BACK_1202.id, title, parentTaskId, ".", repelDetailId, BusinessEnum.SEND_BACK.id, unitId, 1, "DirectlyUnder", list));
    }

    /**
     * 省本级任务 16
     *
     * @param unitId
     * @param repelDetailId
     * @param parentTaskId
     * @return
     */
    private TaskBto oneselfTask(Integer unitId, Integer repelDetailId, Integer parentTaskId, String title, Integer userId) {
        List<Integer> list = new ArrayList<>();
        list.add(userId);
        list.add(0);
        return taskService.start(new TaskBto(StatusEnum.SEND_BACK_1203.id, title, parentTaskId, ".", repelDetailId, BusinessEnum.SEND_BACK.id, unitId, 1, "", list));
    }

    /**
     * 市本级任务 16
     *
     * @param unitId
     * @param repelDetailId
     * @param parentTaskId
     * @return
     */
    private TaskBto cityDeclaredTask(Integer unitId, Integer repelDetailId, Integer parentTaskId, String title, Integer userId) {
        List<Integer> list = new ArrayList<>();
        list.add(userId);
        list.add(0);
        return taskService.start(new TaskBto(StatusEnum.SEND_BACK_1216.id, title + "市本级清退任务", parentTaskId, ".", repelDetailId, BusinessEnum.SEND_BACK.id, unitId, 1, "", list));
    }


    /**
     * 省出库中办 16
     *
     * @param unitId
     * @param repelDetailId
     * @param parentTaskId
     * @return
     */
    private TaskBto sendOutSuperior(Integer unitId, Integer repelDetailId, Integer parentTaskId, Integer userId) {
        List<Integer> list = new ArrayList<>();
        list.add(userId);
        list.add(0);
        return taskService.start(new TaskBto(StatusEnum.SEND_BACK_1210.id, "省退役国家装备任务", parentTaskId, ".", repelDetailId, BusinessEnum.SEND_BACK.id, unitId, 1, "country", list));
    }

    private List<DeviceLibrary> findInvoleDevice(String involeDevice) {
        List<String> idStringList = Arrays.asList(involeDevice.split(","));
        List<String> idListString = idStringList.stream().filter(list2 -> !list2.equals("")).collect(Collectors.toList());
        List<Integer> devIds = idListString.stream().map(Integer::parseInt).collect(Collectors.toList());
        return deviceLibraryDao.getDeviceLibraryEntitiesByIdIn(devIds);
    }

    /**
     * 判读是否留在代办
     */
    private void isCommission(TaskBto taskBto, Integer repelId) {
        boolean flag = repelTaskStatisticalService.findAllRepelTaskStatistical(taskBto.getParentTaskId(), repelId).stream().allMatch(e -> e.getTaskStatus() != 3);
        if (flag) {
            TaskBto parentTask = taskService.get(taskBto.getParentTaskId());
            taskService.moveToSpecial(parentTask, GlobalMap.getStatusEnumMap().get(parentTask.getBillStatus()), -1);
        }
    }

    /**
     * 判读是否可以办结任务
     */
    private void isEnd(TaskBto taskBto, Integer repelId) {
        boolean flag = repelTaskStatisticalService.findAllRepelTaskStatistical(taskBto.getParentTaskId(), repelId).stream().allMatch(e -> e.getTaskStatus() == 1);
        if (flag) {
            TaskBto parentTask = taskService.get(taskBto.getParentTaskId());
            if (parentTask.getBillStatus() != StatusEnum.END.id) {
                taskService.moveToSpecial(parentTask, StatusEnum.SEND_BACK_1212, 0);
            }
        }
    }

    /**
     * 异步添加装备日志
     *
     * @param deviceLibraries
     * @param remark
     * @param userId
     */
    public void devLogAdd(List<DeviceLibrary> deviceLibraries, String remark, Integer userId, Integer taskId) {
        List<DeviceLog> logDtos = new ArrayList<>();
        deviceLibraries.forEach(
                deviceLibrary -> {
                    logDtos.add(new DeviceLogDto(deviceLibrary.getId(), remark, null, userId, taskId).toDo());

                }
        );
        CompletableFuture.runAsync(() -> {
            deviceLogService.saveAllLog(logDtos);
        });

    }

    /**
     * 添加阅读
     *
     * @param messageBto
     */
    private void addMessage(MessageBto messageBto) {
        messageService.add(messageBto);
    }

    /**
     * 根据单位id查询用户 去除用户id
     *
     * @param userId
     * @param unitId
     * @return
     */
    private List<Integer> gainThisUser(Integer userId, Integer unitId) {
        return userService.findAllByUnite(unitId).stream().filter(user -> !user.getUserId().equals(userId)).map(User::getUserId).collect(Collectors.toList());
    }

    /**
     * 根据单位id查询用户id集合
     *
     * @param unitId
     * @return
     */
    private List<Integer> findUnitId(Integer unitId) {
        return userService.findAllByUnite(unitId).stream().map(User::getUserId).collect(Collectors.toList());
    }

    /**
     * 根据单位id查询用户id集合
     *
     * @param unitId
     * @return
     */
    private List<Integer> findUnitIds(Integer userId, List<Integer> unitIds) {
        return userService.findUnitsIdInUsers(unitIds).stream().filter(user -> user.getUserId() != userId).map(User::getUserId).collect(Collectors.toList());
    }
}
