package com.yeejoin.amos.boot.module.jg.biz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.biz.common.bo.ReginParams;
import com.yeejoin.amos.boot.biz.common.entity.DataDictionary;
import com.yeejoin.amos.boot.biz.common.service.IDataDictionaryService;
import com.yeejoin.amos.boot.biz.common.service.impl.DataDictionaryServiceImpl;
import com.yeejoin.amos.boot.biz.common.utils.DateUtils;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.boot.module.jg.api.dto.JgMaintainNoticeDto;
import com.yeejoin.amos.boot.module.jg.api.dto.TaskMessageDto;
import com.yeejoin.amos.boot.module.jg.api.dto.TaskModelDto;
import com.yeejoin.amos.boot.module.jg.api.dto.WorkflowResultDto;
import com.yeejoin.amos.boot.module.jg.api.entity.JgMaintainNotice;
import com.yeejoin.amos.boot.module.jg.api.entity.JgMaintainNoticeEq;
import com.yeejoin.amos.boot.module.jg.api.enums.BusinessTypeEnum;
import com.yeejoin.amos.boot.module.jg.api.mapper.JgMaintainNoticeEqMapper;
import com.yeejoin.amos.boot.module.jg.api.mapper.JgMaintainNoticeMapper;
import com.yeejoin.amos.boot.module.jg.api.service.IJgInstallationNoticeService;
import com.yeejoin.amos.boot.module.jg.api.service.IJgMaintainNoticeService;
import com.yeejoin.amos.boot.module.jg.biz.feign.TzsServiceFeignClient;
import com.yeejoin.amos.boot.module.jg.biz.service.IIdxBizJgRegisterInfoService;
import com.yeejoin.amos.boot.module.jg.biz.utils.ImageUtils;
import com.yeejoin.amos.boot.module.jg.biz.utils.WordTemplateUtils;
import com.yeejoin.amos.boot.module.ymt.api.entity.RegistrationInfo;
import com.yeejoin.amos.boot.module.ymt.api.entity.TzBaseUnitLicence;
import com.yeejoin.amos.boot.module.ymt.api.enums.ApplicationFormTypeEnum;
import com.yeejoin.amos.boot.module.ymt.api.enums.FlowStatusEnum;
import com.yeejoin.amos.boot.module.ymt.api.mapper.*;
import com.yeejoin.amos.feign.systemctl.model.TaskV2Model;
import com.yeejoin.amos.feign.workflow.Workflow;
import com.yeejoin.amos.feign.workflow.model.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import java.text.ParseException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 服务实现类
 *
 * @author system_generator
 * @date 2023-12-12
 */
@Service
public class JgMaintainNoticeServiceImpl extends BaseService<JgMaintainNoticeDto, JgMaintainNotice, JgMaintainNoticeMapper> implements IJgMaintainNoticeService {

    private static final String SUBMIT_TYPE_FLOW = "1";
    private static final String PROCESS_DEFINITION_KEY = "maintainNotice";
    private static final String TABLE_PAGE_ID = "maintainInfo";

    @Autowired
    IJgInstallationNoticeService iJgInstallationNoticeService;

    @Autowired
    EquipmentCategoryMapper equipmentCategoryMapper;
    @Autowired
    JgMaintainNoticeEqMapper jgMaintainNoticeEqMapper;
    @Autowired
    private JgMaintainNoticeMapper jgMaintainNoticeMapper;

    @Autowired
    TzsServiceFeignClient tzsServiceFeignClient;
    @Autowired
    RegistrationInfoMapper tzsJgRegistrationInfoMapper;

    @Autowired
    OtherInfoMapper tzsJgOtherInfoMapper;

    @Autowired
    SupervisoryCodeInfoMapper supervisoryCodeInfoMapper;

    @Autowired
    IDataDictionaryService dataDictionaryService;

    @Autowired
    RedisUtils redisUtils;

    @Autowired
    DataDictionaryServiceImpl iDataDictionaryService;

    @Autowired
    private TzBaseUnitLicenceMapper baseUnitLicenceMapper;

    @Autowired
    private CommonServiceImpl commonService;

    @Autowired
    private CmWorkflowServiceImpl cmWorkflowService;

    @Autowired
    IIdxBizJgRegisterInfoService idxBizJgRegisterInfoService;


    /**
     * 根据sequenceNbr查询
     *
     * @param sequenceNbr 主键
     * @return 维修告知
     */
    @Override
    public Map<String, Map<String, Object>> queryBySequenceNbr(Long sequenceNbr) {
        // 维修告知信息
        JgMaintainNotice notice = jgMaintainNoticeMapper.selectById(sequenceNbr);
        if (Objects.isNull(notice))
            return null;
        Map<String, Object> maintainInfo = BeanUtil.beanToMap(notice);
        maintainInfo.put("powerOfAttorneyList", JSON.parseArray(notice.getPowerOfAttorney()));
        maintainInfo.put("constructionContractList", JSON.parseArray(notice.getConstructionContract()));
        maintainInfo.put("province", notice.getProvince() + "_" + notice.getProvinceName());
        maintainInfo.put("city", ObjectUtils.isEmpty(notice.getCity()) ? null : notice.getCity() + "_" + notice.getCityName());
        maintainInfo.put("constructionManagerId", ObjectUtils.isEmpty(notice.getConstructionManagerId()) ? null : notice.getConstructionManagerId() + "_" + notice.getConstructionManager());
        maintainInfo.put("county", ObjectUtils.isEmpty(notice.getCounty()) ? null : notice.getCounty() + "_" + notice.getCountyName());
        maintainInfo.put("fullAddress", notice.getProvinceName() + notice.getCityName() + notice.getCounty() + notice.getStreetName() + notice.getAddress());
        maintainInfo.put("useUnitCreditCode", ObjectUtils.isEmpty(notice.getUseUnitCreditCode()) ? null : notice.getUseUnitCreditCode() + "_" + notice.getUseUnitName());
        maintainInfo.put("receiveOrgCode", notice.getReceiveCompanyCode() + "_" + notice.getReceiveOrgName());
        if (!ValidationUtil.isEmpty(notice.getInspectionUnitCreditCode()) && !ValidationUtil.isEmpty(notice.getInspectionUnitName())) {
            maintainInfo.put("inspectUnitId", notice.getInspectionUnitCreditCode() + "_" + notice.getInspectionUnitName());
        }
        if (!ValidationUtil.isEmpty(notice.getStreet()) && !ValidationUtil.isEmpty(notice.getStreetName())) {
            maintainInfo.put("street", notice.getStreet() + "_" + notice.getStreetName());
        }
        String[] fields = {"productPhoto", "designDoc", "designStandard", "factoryStandard", "productQualityYieldProve",
                "insUseMaintainExplain", "inspectReport", "proxyStatementAttachment", "installContractAttachment"};
        // 设备信息 "equCategory",  "equDefine",  "equRegisterCode",  "produceCountry",  "produceLicenseNum",
        JgMaintainNoticeEq jgMaintainNoticeEq = jgMaintainNoticeEqMapper.selectOne(new LambdaQueryWrapper<JgMaintainNoticeEq>().eq(JgMaintainNoticeEq::getEquipTransferId, sequenceNbr));
        Map<String, Object> map = idxBizJgRegisterInfoService.getDetailFieldCamelCaseByRecord(jgMaintainNoticeEq.getEquId());
        map.put("uuseUnitCreditCode",map.get("useUnitCreditCode"));
        map.remove("useUnitCreditCode");
        map.remove("address");
        map.remove("sequenceNbr");

        for (String s : fields) {
            if (maintainInfo.containsKey(s) && !ObjectUtils.isEmpty(map.get(s)))
                maintainInfo.put(s, JSON.parseArray(maintainInfo.get(s).toString()));
            if (map.containsKey(s) && !ObjectUtils.isEmpty(map.get(s)))
                map.put(s, JSON.parseArray(map.get(s).toString()));
        }
        maintainInfo.putAll(map);
        return new HashMap<String, Map<String, Object>>() {{
            put(TABLE_PAGE_ID, maintainInfo);
        }};
    }

    /**
     * 更新维修告知
     *
     * @param noticeDto 维修告知
     */
    @SuppressWarnings({"rawtypes", "Duplicates"})
    @Transactional
    public JgMaintainNoticeDto updateMaintainNotice(String submitType, JgMaintainNoticeDto noticeDto, String op) {
        if (Objects.isNull(noticeDto) || StringUtils.isEmpty(submitType))
            throw new IllegalArgumentException("参数不能为空");
        // 字段转换
        this.convertField(noticeDto);
        JgMaintainNotice notice = jgMaintainNoticeMapper.selectById(noticeDto.getSequenceNbr());
        //  submitType=1为流程提交否则仅为保存业务数据
        if (SUBMIT_TYPE_FLOW.equals(submitType)) {
            ProcessTaskDTO processTaskDTO = new ProcessTaskDTO();
            WorkflowResultDto workflowResultDto = new WorkflowResultDto();
            // 如果没有实例ID，说明是启动并执行一步
            // 直接调用工作流 启动并执行API  -  可以拿到两个节点的信息，用于填充业务字段
            // 如果有实例ID，为撤回或者驳回后重新提交
            if (!StringUtils.hasText(noticeDto.getInstanceId())) {
                // 发起流程
                ActWorkflowBatchDTO actWorkflowBatchDTO = new ActWorkflowBatchDTO();
                List<ActWorkflowStartDTO> list = new ArrayList<>();
                ActWorkflowStartDTO dto = new ActWorkflowStartDTO();
                dto.setProcessDefinitionKey(PROCESS_DEFINITION_KEY);
                dto.setBusinessKey(String.valueOf(noticeDto.getSequenceNbr()));
                dto.setCompleteFirstTask(Boolean.TRUE);
                //下一节点执行人单位（下节点接收机构code）
                dto.setNextExecuteUserCompanyCode(notice.getReceiveCompanyCode());
                list.add(dto);
                actWorkflowBatchDTO.setProcess(list);
                processTaskDTO = cmWorkflowService.startBatch(actWorkflowBatchDTO).get(0);
                // 提取节点等信息
                workflowResultDto = commonService.buildWorkFlowInfo(Collections.singletonList(processTaskDTO)).get(0);
                BeanUtils.copyProperties(noticeDto, notice);
                if (!ObjectUtils.isEmpty(notice.getInstanceStatus())) {
                    notice.setInstanceStatus(notice.getInstanceStatus() + "," + workflowResultDto.getNextExecutorRoleIds());
                } else {
                    notice.setInstanceStatus(workflowResultDto.getNextExecutorRoleIds());
                }
                notice.setNextExecuteUserIds(workflowResultDto.getNextExecutorUserIds());
                notice.setPromoter(RequestContext.getExeUserId());
                notice.setNextExecuteIds(String.join(",", workflowResultDto.getNextExecutorRoleIds()));
                notice.setNoticeStatus(String.valueOf(FlowStatusEnum.TO_BE_PROCESSED.getCode()));
                notice.setInstanceId(workflowResultDto.getInstanceId());
                notice.setNextTaskId(workflowResultDto.getNextTaskId());
                jgMaintainNoticeMapper.updateById(notice);
                // 如果为保存并提交，则创建代办
                buildTask(Collections.singletonList(notice), Collections.singletonList(workflowResultDto), Boolean.TRUE);
            } else {
                // 只调用执行API，返回下个节点信息，用于填充业务字段
                //组装信息
                TaskResultDTO dto = new TaskResultDTO();
                dto.setResultCode("approvalStatus");
                dto.setTaskId(notice.getNextTaskId());
                HashMap<String, Object> commMap = new HashMap<>();
                if (notice.getNoticeStatus().equals("6614") || notice.getNoticeStatus().equals("6615")) {
                    commMap.put("approvalStatus", "提交");
                } else {
                    commMap.put("approvalStatus", op);
                }
                //下一节点执行人单位（下节点接收机构code）
                dto.setNextExecuteUserCompanyCode(notice.getReceiveCompanyCode());
                dto.setVariable(commMap);
                processTaskDTO = cmWorkflowService.completeOrReject(notice.getNextTaskId(), dto, op);
                // 提取节点等信息
                workflowResultDto = commonService.buildWorkFlowInfo(Collections.singletonList(processTaskDTO)).get(0);
                BeanUtils.copyProperties(noticeDto, notice);
                if (!ObjectUtils.isEmpty(notice.getInstanceStatus())) {
                    notice.setInstanceStatus(notice.getInstanceStatus() + "," + workflowResultDto.getNextExecutorRoleIds());
                } else {
                    notice.setInstanceStatus(workflowResultDto.getNextExecutorRoleIds());
                }
                notice.setNextExecuteUserIds(workflowResultDto.getNextExecutorUserIds());
                notice.setPromoter(RequestContext.getExeUserId());
                notice.setNextExecuteIds(String.join(",", workflowResultDto.getNextExecutorRoleIds()));
                notice.setNoticeStatus(String.valueOf(FlowStatusEnum.TO_BE_PROCESSED.getCode()));
                notice.setNextTaskId(workflowResultDto.getNextTaskId());
                jgMaintainNoticeMapper.updateById(notice);
                // 上个代办改为已办
                HashMap<String, Object> map = new HashMap<>();
                map.put("taskStatus", FlowStatusEnum.TO_BE_PROCESSED.getCode());
                map.put("taskStatusLabel", FlowStatusEnum.TO_BE_PROCESSED.getName());
                map.put("relationId", notice.getInstanceId());
                map.put("flowStatus", FlowStatusEnum.TO_BE_PROCESSED.getCode());
                map.put("flowStatusLabel", FlowStatusEnum.TO_BE_PROCESSED.getName());
                TaskV2Model taskV2Model = commonService.updateTaskModel(map);
                if (ObjectUtils.isEmpty(taskV2Model)) {
                    // 如果为保存并提交，则创建代办
                    buildTask(Collections.singletonList(notice), Collections.singletonList(workflowResultDto), Boolean.FALSE);
                } else {
                    TaskModelDto taskModelDto = new TaskModelDto();
                    BeanUtils.copyProperties(taskV2Model, taskModelDto);
                    // 创建新的代办
                    TaskMessageDto taskMessageDto = new TaskMessageDto();
                    BeanUtils.copyProperties(notice, taskMessageDto);
                    taskModelDto.setModel(taskMessageDto);
                    taskModelDto.setTaskName(workflowResultDto.getNextTaskName());
                    taskModelDto.setExecuteUserIds(workflowResultDto.getNextExecutorUserIds());
                    taskModelDto.setFlowStatus(FlowStatusEnum.TO_BE_PROCESSED.getCode());
                    taskModelDto.setFlowStatusLabel(FlowStatusEnum.TO_BE_PROCESSED.getName());
                    taskModelDto.setFlowCode(notice.getNextTaskId());
                    taskModelDto.setNextExecuteUser(workflowResultDto.getNextExecutorRoleIds());
                    commonService.buildTaskModel(Collections.singletonList(taskModelDto));
                }
            }
        } else {
            JgMaintainNotice bean = new JgMaintainNotice();
            BeanUtils.copyProperties(noticeDto, bean);
            jgMaintainNoticeMapper.updateById(bean);
        }
        return noticeDto;
    }


    /**
     * 分页查询
     *
     * @param page  分页对象
     * @param model 查询参数
     * @return 维修告知列表
     */
    @Override
    public Page<JgMaintainNoticeDto> queryForJgMaintainNoticePage(Page<JgMaintainNotice> page, JgMaintainNoticeDto model, ReginParams reginParams) {
        String orgCode = reginParams.getCompany().getCompanyCode();
        String type = reginParams.getCompany().getLevel();
        String userId = reginParams.getUserModel().getUserId();
        List<DataDictionary> dictionaries = dataDictionaryService.getByType("WXLX");
        Page<JgMaintainNotice> noticePage = jgMaintainNoticeMapper.queryForPage(page, model, type, orgCode,userId);
        Page<JgMaintainNoticeDto> noticeDtoPage = new Page<>();
        BeanUtils.copyProperties(noticePage, noticeDtoPage, "records");
        List<JgMaintainNoticeDto> records = noticePage.getRecords().stream().map(notice -> {
            JgMaintainNoticeDto noticeDto = new JgMaintainNoticeDto();
            BeanUtils.copyProperties(notice, noticeDto);
            if (Objects.nonNull(notice.getNoticeStatus())) {
                String noticeStatusDesc = FlowStatusEnum.getNameByType(Long.valueOf(notice.getNoticeStatus()));
                noticeDto.setNoticeStatusDesc(noticeStatusDesc);
            }
            if (Objects.nonNull(notice.getMaintainType())) {
                noticeDto.setMaintainTypeDesc(dictionaries.stream().filter(d -> notice.getMaintainType().equals(d.getCode())).map(DataDictionary::getName).collect(Collectors.joining()));
            }
            return noticeDto;
        }).collect(java.util.stream.Collectors.toList());
        noticeDtoPage.setRecords(records);
        return noticeDtoPage;
    }

    /**
     * 列表查询 示例
     */
    public List<JgMaintainNoticeDto> queryForJgMaintainNoticeList() {
        return this.queryForList("", false);
    }

    /**
     * 批量删除
     *
     * @param sequenceNbrs 主键
     * @return 是否删除成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteForBatch(Long[] sequenceNbrs) {
        if (Objects.isNull(sequenceNbrs) || sequenceNbrs.length == 0) {
            return false;
        }
        Collection<JgMaintainNotice> jgMaintainNotices = this.listByIds(Arrays.asList(sequenceNbrs));
        jgMaintainNotices.forEach(notice -> {
            if (StringUtils.hasText(notice.getInspectionUnitCreditCode())) {
                throw new IllegalStateException("所选数据已存在流程，不能删除！");
            }
            notice.setIsDelete(true);
        });
        return this.updateBatchById(jgMaintainNotices);
    }

    /**
     * 打印维修告知单
     *
     * @param sequenceNbr 主键
     * @return pdf文件路径
     */
    @Override
    public String generateMaintainNoticeReport(Long sequenceNbr) {
        if (Objects.isNull(sequenceNbr)) {
            throw new IllegalArgumentException("参数不能为空");
        }
        JgMaintainNotice JgMaintainNotice = this.getById(sequenceNbr);
        List<Map<String, Object>> informationList = jgMaintainNoticeMapper.queryEquipInformation(sequenceNbr);
        if (Objects.isNull(JgMaintainNotice) || CollectionUtils.isEmpty(informationList)) {
            throw new IllegalArgumentException("维修告知单不存在");
        }
        Map<String, Object> installation = informationList.get(0);
        String useCode = String.valueOf(installation.get("useCode"));
        LambdaQueryWrapper<TzBaseUnitLicence> wrapper = new LambdaQueryWrapper<>();
        // 因模板许可证编号配置最多支持三个，再多样式混乱，目前返回三个
        wrapper.eq(TzBaseUnitLicence::getUnitCode, useCode).last("limit 3");
        List<TzBaseUnitLicence> list = baseUnitLicenceMapper.selectList(wrapper);
        ArrayList<String> installLicenseNoList = new ArrayList<>();
        ArrayList<String> installLicenseExpirationDateList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(tzBaseUnitLicence -> {
                installLicenseNoList.add(tzBaseUnitLicence.getCertNo());
                installLicenseExpirationDateList.add(DateUtils.convertDateToString(tzBaseUnitLicence.getExpiryDate(), DateUtils.DATE_PATTERN));
            });
        }
        Function<String, String> getValue = key -> installation.getOrDefault(key, "").toString();
        // 组装模板变量
        Map<String, Object> placeholders = new HashMap<>();
        placeholders.put("sequenceNbr", getValue.apply("sequenceNbr"));
        placeholders.put("installUnitName", getValue.apply("installUnitName"));
        placeholders.put("applyNo", getValue.apply("applyNo"));
        placeholders.put("productName", getValue.apply("productName"));
        placeholders.put("equipType", getValue.apply("equType"));
        placeholders.put("equipCode", getValue.apply("equRegisterCode"));
        placeholders.put("produceCode", getValue.apply("produceCode"));
        placeholders.put("produceUnitName", getValue.apply("produceUnitName"));
        placeholders.put("produceLicenseNum", getValue.apply("produceLicenseNum"));
        placeholders.put("fullAddress", getValue.apply("provinceName") + getValue.apply("cityName") +
                getValue.apply("countyName") + getValue.apply("streetName") + getValue.apply("address"));
        placeholders.put("installStartDate", getValue.apply("installStartDate"));
        placeholders.put("installType", "维修告知");
        placeholders.put("installLicenseNo", "");
        placeholders.put("installLicenseExpirationDate", "");
        placeholders.put("installLeaderName", getValue.apply("installLeaderName"));// 施工负责人
        placeholders.put("installLeaderPhone", getValue.apply("installLeaderPhone"));// 施工负责人手机
        placeholders.put("installUnitAddress", getValue.apply("provinceName") + getValue.apply("cityName") +
                getValue.apply("countyName") + getValue.apply("streetName") + getValue.apply("address")); // TODO: 施工单位地址
        placeholders.put("useUnitName", getValue.apply("useUnitName"));
        placeholders.put("useUnitLeaderName", getValue.apply("safetyManager"));
        placeholders.put("useUnitLeaderPhone", getValue.apply("safetyManagerPhone"));
        placeholders.put("useUnitLeaderAddress", getValue.apply("useUnitProvinceName") + getValue.apply("useUnitCityName") +
                getValue.apply("useUnitCountyName") + getValue.apply("streetName") + getValue.apply("useUnitAddress"));
        // 生成二维码
        String qrCode = ImageUtils.generateQRCode(getValue.apply("applyNo"), 300, 300);
        placeholders.put("qrCode", qrCode);
        placeholders.put("installLicenseNoList", installLicenseNoList);//许可证编号
        placeholders.put("installLicenseExpirationDateList", installLicenseExpirationDateList);//许可证有效期
        String tempFileName = "安装告知单_" + System.currentTimeMillis() + "_temp";
        String url = WordTemplateUtils.templateToPdf(tempFileName, "installation-notification-report.ftl", placeholders);
        // 更新到数据库
        JgMaintainNotice.setNoticeReportUrl(url);
        this.updateById(JgMaintainNotice);
        return url;
    }

    @Override
    public boolean deleteBySequenceNbr(Long[] sequenceNbr) {
        this.baseMapper.deleteById(sequenceNbr);
        LambdaQueryWrapper<JgMaintainNoticeEq> lambda = new QueryWrapper<JgMaintainNoticeEq>().lambda();
        lambda.eq(JgMaintainNoticeEq::getEquipTransferId, sequenceNbr);
        jgMaintainNoticeEqMapper.delete(lambda);
        // 删除暂存时生成的待办
        commonService.deleteTaskModel(sequenceNbr + "");
        return true;
    }

    @Override
    @SuppressWarnings({"Duplicates", "rawtypes"})
    @Transactional(rollbackFor = Exception.class)
    public List<JgMaintainNotice> saveNotice(String submitType, Map<String, Object> jgMaintainNoticeDtoMap, ReginParams reginParams) {

        JgMaintainNoticeDto model = JSON.parseObject(JSONObject.toJSONString(jgMaintainNoticeDtoMap.get(TABLE_PAGE_ID)), JgMaintainNoticeDto.class);

        // 字段转换
        convertField(model);
        // 获取告知设备列表
        List<Map<String, Object>> deviceList = model.getDeviceList();
        if (CollectionUtils.isEmpty(deviceList)) {
            throw new BadRequest("请选择设备");
        }
        // 获取告知单号
        ResponseModel<List<String>> applyNoResult = tzsServiceFeignClient.applicationFormCode(ApplicationFormTypeEnum.WXGZ.getCode(), deviceList.size());

        if (CollectionUtils.isEmpty(applyNoResult.getResult())) {
            log.error(" 获取告知单号失败");
            throw new RuntimeException();
        }
        List<String> applyNoList = applyNoResult.getResult();

        List<WorkflowResultDto> workflowResultDtoList = workFlowInfo(submitType, deviceList, model.getReceiveCompanyCode());

        List<JgMaintainNotice> list = new ArrayList<>();
        List<JgMaintainNoticeEq> equipList = new ArrayList<>();
        deviceList.forEach(obj -> {
            JgMaintainNoticeEq jgRelationEquip = new JgMaintainNoticeEq();
            JgMaintainNotice dto = new JgMaintainNotice();
            BeanUtils.copyProperties(model, dto);
            int i = deviceList.indexOf(obj);
            String applyNo = applyNoList.get(i);
            dto.setApplyNo(applyNo);
            dto.setNoticeDate(new Date());
            dto.setEquCategory(String.valueOf(obj.get("EQU_CATEGORY")));
            dto.setEquListCode(String.valueOf(obj.get("EQU_LIST_CODE")));
            dto.setCreateUserCompanyName(reginParams.getCompany().getCompanyName());
            if (SUBMIT_TYPE_FLOW.equals(submitType)) {
                dto.setNextExecuteIds(workflowResultDtoList.get(i).getNextExecutorRoleIds());
                dto.setInstanceStatus(workflowResultDtoList.get(i).getNextExecutorRoleIds() + "," + workflowResultDtoList.get(i).getExecutorRoleIds());
                dto.setPromoter(reginParams.getUserModel().getUserId());
                dto.setNextExecuteUserIds(workflowResultDtoList.get(i).getNextExecutorUserIds());
                dto.setNextTaskId(workflowResultDtoList.get(i).getNextTaskId());
                dto.setInstanceId(workflowResultDtoList.get(i).getInstanceId());
                dto.setNoticeStatus(String.valueOf(FlowStatusEnum.TO_BE_PROCESSED.getCode()));
            } else {
                dto.setNextExecuteUserIds(reginParams.getUserModel().getUserId());
                dto.setNoticeStatus(String.valueOf(FlowStatusEnum.TO_BE_SUBMITTED.getCode()));
            }
            dto.setEquList(String.valueOf(obj.get("EQU_LIST")));
            dto.setSupervisoryCode(String.valueOf(obj.get("SUPERVISORY_CODE")));
            dto.setInstallUnitName(reginParams.getCompany().getCompanyName());
            dto.setInstallUnitCreditCode(reginParams.getCompany().getCompanyCode());

            jgRelationEquip.setEquId(String.valueOf(obj.get("SEQUENCE_NBR")));
            jgRelationEquip.setEquipTransferId(applyNo);

            dto.setCreateUserName(reginParams.getUserModel().getRealName());
            dto.setCreateUserId(reginParams.getUserModel().getUserId());
            DataDictionary dictionary = iDataDictionaryService.getByCode(dto.getMaintainType(),"WXLX");
            dto.setMaintainTypeDesc(dictionary.getName());
            dto.setFullAddress(dto.getProvinceName() + dto.getCityName() + dto.getCountyName() + dto.getStreetName() + dto.getAddress());
            list.add(dto);
            equipList.add(jgRelationEquip);
        });
        jgMaintainNoticeMapper.insertBatchSomeColumn(list);
        if (SUBMIT_TYPE_FLOW.equals(submitType)) {
            buildTask(list, workflowResultDtoList, Boolean.TRUE);
        } else {
            // 暂存任务
            buildTaskDraft(list);
        }

        List<JgMaintainNoticeEq> jgRelationEquipList = equipList.stream().map(jgRelationEquip -> {
            List<JgMaintainNotice> collect = list.stream().filter(JgMaintainNotice -> jgRelationEquip.getEquipTransferId().equals(JgMaintainNotice.getApplyNo())).collect(Collectors.toList());
            Long sequenceNbr = collect.get(0).getSequenceNbr();
            return jgRelationEquip.setEquipTransferId(String.valueOf(sequenceNbr));
        }).collect(Collectors.toList());
        jgMaintainNoticeEqMapper.insertBatchSomeColumn(jgRelationEquipList);
        return list;
    }

    /**
     * 暂存任务生成待办
     *
     * @param list 业务信息
     */
    private void buildTaskDraft(List<JgMaintainNotice> list) {
        List<TaskModelDto> modelDtos = new ArrayList<>();
        list.forEach(obj -> {
            TaskModelDto dto = new TaskModelDto();
            //行数据
            TaskMessageDto taskMessageDto = new TaskMessageDto();
            BeanUtils.copyProperties(obj, taskMessageDto);
            taskMessageDto.setNextTaskId(obj.getNextTaskId());
            dto.setModel(taskMessageDto);
            //摘要 按原有规则组装
            dto.setTaskContent(String.format("来自%s【%s】的业务办理，【申请单号：%s】", obj.getEquList(), obj.getSupervisoryCode(), obj.getApplyNo()));
            //申请单号
            dto.setTaskCode(obj.getApplyNo());
            //业务类型枚举code值
            dto.setTaskType(BusinessTypeEnum.JG_MAINTENANCE_NOTIFICATION.getCode());
            ////业务主键
            dto.setRelationId(obj.getSequenceNbr() + "");
            modelDtos.add(dto);
        });
        commonService.buildTaskModel(modelDtos);
    }

    /**
     * 插入代办
     */
    private void buildTask(List<JgMaintainNotice> list, List<WorkflowResultDto> workflowResultList, Boolean bool) {
        List<TaskModelDto> taskModelDtoList = new ArrayList<>();
        WorkflowResultDto workflowResultDto = workflowResultList.get(0);
        list.forEach(item -> {
            TaskModelDto taskModelDto = new TaskModelDto();
            taskModelDto.setFlowCreateDate(item.getCreateDate());
            taskModelDto.setTaskName(workflowResultDto.getNextTaskName()); // 工作流API返回
            taskModelDto.setTaskCode(item.getApplyNo());
            taskModelDto.setTaskType(BusinessTypeEnum.JG_MAINTENANCE_NOTIFICATION.getCode());
            taskModelDto.setTaskTypeLabel(BusinessTypeEnum.JG_MAINTENANCE_NOTIFICATION.getName());
            String instanceId = workflowResultList.stream().filter(e -> e.getInstanceId().equals(item.getInstanceId())).findFirst().orElse(null).getInstanceId();
            taskModelDto.setRelationId(instanceId);
            taskModelDto.setExecuteUserIds(workflowResultDto.getNextExecutorUserIds()); // 工作流API返回
            taskModelDto.setTaskStatusLabel(FlowStatusEnum.TO_BE_PROCESSED.getName());
            taskModelDto.setFlowStatus(commonService.getDictionaryCodeByName(FlowStatusEnum.TO_BE_PROCESSED.getName())); // 流程状态枚举
            taskModelDto.setFlowStatusLabel(FlowStatusEnum.TO_BE_PROCESSED.getName());
            taskModelDto.setFlowCode(item.getNextTaskId());
            taskModelDto.setStartUserId(item.getCreateUserId());
            taskModelDto.setStartUser(item.getCreateUserName());
            taskModelDto.setStartUserCompanyName(item.getCreateUserCompanyName()); // 任务发起人所在单位
            taskModelDto.setStartDate(item.getCreateDate());
            TaskMessageDto taskMessageDto = new TaskMessageDto();
            BeanUtils.copyProperties(item, taskMessageDto);
            taskMessageDto.setNextTaskId(item.getNextTaskId());
            taskModelDto.setModel(taskMessageDto);
            taskModelDto.setNextExecuteUser(item.getNextExecuteIds());
            taskModelDto.setTaskContent(String.format("来自%s【%s】的业务办理，【申请单号：%s】", item.getEquList(), item.getSupervisoryCode(), item.getApplyNo()));
            taskModelDtoList.add(taskModelDto);
            if (bool) {
                // 删除暂存时生成的待办
                commonService.deleteTaskModel(item.getSequenceNbr() + "");
            }
        });
        commonService.buildTaskModel(taskModelDtoList);
    }


    private List<WorkflowResultDto> workFlowInfo(String submitType, List<Map<String, Object>> deviceList, String receiveCompanyCode) {
        if (SUBMIT_TYPE_FLOW.equals(submitType)) {
            // 发起流程
            ActWorkflowBatchDTO actWorkflowBatchDTO = new ActWorkflowBatchDTO();
            List<ActWorkflowStartDTO> list = new ArrayList<>();
            deviceList.forEach(item -> {
                ActWorkflowStartDTO dto = new ActWorkflowStartDTO();
                dto.setProcessDefinitionKey(PROCESS_DEFINITION_KEY);
                dto.setBusinessKey(item.get("SEQUENCE_NBR").toString());
                //下一节点执行人单位（下节点接收机构code）
                dto.setNextExecuteUserCompanyCode(receiveCompanyCode);
                dto.setCompleteFirstTask(Boolean.TRUE);
                list.add(dto);
            });

            actWorkflowBatchDTO.setProcess(list);
            List<ProcessTaskDTO> processTaskDTOS = cmWorkflowService.startBatch(actWorkflowBatchDTO);
            return commonService.buildWorkFlowInfo(processTaskDTOS);
        }
        return new ArrayList<>();
    }


    void getNext(ArrayList<String> roleListFirst, String instanceId, String[] taskName) {
        AjaxResult aj = Workflow.taskClient.getTaskNoAuth(instanceId);
        JSONObject taskNoAuth = JSON.parseObject(JSON.toJSONString(aj.get("data")));
        if (!ObjectUtils.isEmpty(taskNoAuth)) {
            String nextTaskId = taskNoAuth.getString("id");
            AjaxResult taskGroupName = Workflow.taskClient.getTaskGroupName(nextTaskId);
            taskName[0] = taskNoAuth.getString("name");
            JSONArray data = JSON.parseArray(JSON.toJSONString(taskGroupName.get("data")));
            for (Object datum : data) {
                if (((Map) datum).containsKey("groupId")) {
                    roleListFirst.add(((Map) datum).get("groupId").toString());
                }
            }
        }
    }

    private void convertField(JgMaintainNoticeDto model) {
        if (null == model)
            return;
        // 处理附件
        if (!ValidationUtil.isEmpty(model.getPowerOfAttorneyList())) {
            model.setPowerOfAttorney(JSON.toJSONString(model.getPowerOfAttorneyList()));
        }
        if (!ValidationUtil.isEmpty(model.getConstructionContractList())) {
            model.setConstructionContract(JSON.toJSONString(model.getConstructionContractList()));
        }
        // 分割省市区街道字段
        String province = model.getProvince();
        if (!ObjectUtils.isEmpty(province)) {
            String[] provinceList = province.split("_");
            if (provinceList.length > 1) {
                model.setProvince(provinceList[0]);
                model.setProvinceName(provinceList[1]);
            }
        }
        String city = model.getCity();
        if (!ObjectUtils.isEmpty(city)) {
            String[] cityList = city.split("_");
            if (cityList.length > 1) {
                model.setCity(cityList[0]);
                model.setCityName(cityList[1]);
            }
        }

        String county = model.getCounty();
        if (!ObjectUtils.isEmpty(county)) {
            String[] countyList = county.split("_");
            if (countyList.length > 1) {
                model.setCounty(countyList[0]);
                model.setCountyName(countyList[1]);
            }
        }
        String street = model.getStreet();
        if (!ObjectUtils.isEmpty(street)) {
            String[] streetList = street.split("_");
            if (streetList.length > 1) {
                model.setStreet(streetList[0]);
                model.setStreetName(streetList[1]);
            }
        }
        // 分割单位
        String useUnitId = model.getUseUnitCreditCode();
        if (!ObjectUtils.isEmpty(useUnitId)) {
            String[] useUnitList = useUnitId.split("_");
            if (useUnitList.length > 1) {
                model.setUseUnitCreditCode(useUnitList[0]);
                model.setUseUnitName(useUnitList[1]);
            }
        }
        //  分割接收机构
        String receiveOrgId = model.getReceiveOrgCode();
        if (!ObjectUtils.isEmpty(receiveOrgId)) {
            String[] receiveOrgIdList = receiveOrgId.split("_");
            if (receiveOrgIdList.length > 1) {
                model.setReceiveCompanyCode(receiveOrgIdList[0]);
                model.setReceiveOrgName(receiveOrgIdList[1]);
                model.setReceiveOrgCode(null);
            }
        }

        String constructionManager = model.getConstructionManagerId();
        if (!ObjectUtils.isEmpty(constructionManager)) {
            String[] constructionManagerList = constructionManager.split("_");
            if (constructionManagerList.length > 1) {
                model.setConstructionManagerId(constructionManagerList[0]);
                model.setConstructionManager(constructionManagerList[1]);
            }
        }

        String inspectUnitId = model.getInspectionUnitCreditCode();
        if (!ObjectUtils.isEmpty(inspectUnitId)) {
            String[] inspectUnitIdList = inspectUnitId.split("_");
            if (inspectUnitIdList.length > 1) {
                model.setInspectionUnitCreditCode(inspectUnitIdList[0]);
                model.setInspectionUnitName(inspectUnitIdList[1]);
            }
        }
    }

    public boolean submit(JgMaintainNotice notice, String op, String opinion) {
        AjaxResult ajaxResult = Workflow.taskClient.getTask(notice.getInstanceId());
        JSONObject dataObject = JSON.parseObject(JSON.toJSONString(ajaxResult.get("data")));
        String taskId = dataObject.getString("id");
        //组装信息
        TaskResultDTO dto = new TaskResultDTO();
        dto.setResultCode("approvalStatus");
        dto.setTaskId(taskId);
        if (!StringUtils.isEmpty(opinion)) {
            dto.setComment(opinion);
        }
        HashMap<String, Object> map = new HashMap<>();
        map.put("approvalStatus", op);
        dto.setVariable(map);
        //执行流程
        AjaxResult ajaxResult1 = null;
        try {
            ajaxResult1 = Workflow.taskClient.completeByTask(taskId, dto);
            if (ajaxResult1.get("code").equals(200)) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            log.error("JgMaintainNoticeServiceImpl.submit提交失败：{}", e);
            return false;
        }
    }

    public void cancel(JgMaintainNoticeDto noticeDto) {
        JgMaintainNotice jgMaintainNotice = this.baseMapper.selectById(noticeDto.getSequenceNbr());
        ProcessTaskDTO processTaskDTO = cmWorkflowService.rollBack(jgMaintainNotice.getInstanceId());
        // 提取节点等信息
        WorkflowResultDto workflowResultDto = commonService.buildWorkFlowInfo(Collections.singletonList(processTaskDTO)).get(0);
        jgMaintainNotice.setPromoter("");
        jgMaintainNotice.setNextExecuteIds(workflowResultDto.getNextExecutorRoleIds());
        jgMaintainNotice.setNoticeStatus(String.valueOf(FlowStatusEnum.ROLLBACK.getCode()));
        jgMaintainNotice.setNextTaskId(workflowResultDto.getNextTaskId());
        jgMaintainNotice.setNextExecuteUserIds(workflowResultDto.getNextExecutorUserIds());
        updateById(jgMaintainNotice);

        // 删除待办
        JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(jgMaintainNotice));
        jsonObject.put("nextExecuteUser", jgMaintainNotice.getNextExecuteIds());
        jsonObject.put("taskType", BusinessTypeEnum.JG_MAINTENANCE_NOTIFICATION.getCode());
        jsonObject.put("flowStatusLabel", FlowStatusEnum.ROLLBACK.getName());
        jsonObject.put("flowStatus", FlowStatusEnum.ROLLBACK.getCode());

        commonService.rollbackTask(jgMaintainNotice.getInstanceId(), jsonObject);
    }

    @Transactional
    public void accept(JgMaintainNoticeDto dto, String op, String opinion) {
        JgMaintainNotice jgMaintainNotice = this.jgMaintainNoticeMapper.selectById(dto.getSequenceNbr());
        // 组装设备注册代码
        StringBuffer stringBuffer = new StringBuffer();
        String ym = null;
        try {
            ym = DateUtils.dateFormat(new Date(), DateUtils.DATE_PATTERN_MM);
        } catch (ParseException e) {
            log.error("日期转换失败：{}", e);
        }
        //组装信息
        TaskResultDTO taskResultDTO = assembleData(jgMaintainNotice, op, opinion);
        ProcessTaskDTO processTaskDTO = cmWorkflowService.completeOrReject(jgMaintainNotice.getNextTaskId(), taskResultDTO, op);

        // 提取节点等信息
        WorkflowResultDto workflowResultDto = commonService.buildWorkFlowInfo(Collections.singletonList(processTaskDTO)).get(0);
        TaskV2Model taskV2Model = new TaskV2Model();
        if ("0".equals(op)) {
            // 判断如果下一步执行角色列表为空则流程完成
            if (StringUtils.isEmpty(workflowResultDto.getNextExecutorRoleIds())) {
                LambdaQueryWrapper<JgMaintainNoticeEq> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(JgMaintainNoticeEq::getEquipTransferId, dto.getSequenceNbr());
                JgMaintainNoticeEq jgRelationEquip = jgMaintainNoticeEqMapper.selectOne(queryWrapper);
                LambdaQueryWrapper<RegistrationInfo> queryWrapper2 = new LambdaQueryWrapper<>();
                queryWrapper2.eq(RegistrationInfo::getRecord, jgRelationEquip.getEquId());
                RegistrationInfo tzsJgRegistrationInfo = tzsJgRegistrationInfoMapper.selectOne(queryWrapper2);
                stringBuffer.append(tzsJgRegistrationInfo.getEquCategory()).append(jgMaintainNotice.getCity()).append(ym);
                jgMaintainNotice.setAcceptDate(new Date());
                jgMaintainNotice.setNoticeStatus(String.valueOf(FlowStatusEnum.TO_BE_FINISHED.getCode()));
                generateMaintainNoticeReport(jgMaintainNotice.getSequenceNbr());
                jgMaintainNotice.setPromoter("");
                jgMaintainNotice.setNoticeStatus(String.valueOf(FlowStatusEnum.TO_BE_FINISHED.getCode()));
                this.generateMaintainNoticeReport(jgMaintainNotice.getSequenceNbr());
                // 上个代办改为已办
                HashMap<String, Object> taskMap = new HashMap<>();
                taskMap.put("taskStatus", FlowStatusEnum.TO_BE_FINISHED.getCode());
                taskMap.put("taskStatusLabel", FlowStatusEnum.TO_BE_FINISHED.getName());
                taskMap.put("relationId", jgMaintainNotice.getInstanceId());
                taskMap.put("flowStatus", FlowStatusEnum.TO_BE_FINISHED.getCode());
                taskMap.put("flowStatusLabel", FlowStatusEnum.TO_BE_FINISHED.getName());
                TaskMessageDto taskMessageDto = new TaskMessageDto();
                BeanUtils.copyProperties(jgMaintainNotice, taskMessageDto);
                taskMap.put("model", taskMessageDto);
                commonService.updateTaskModel(taskMap);
            } else {
                jgMaintainNotice.setNextExecuteIds(workflowResultDto.getNextExecutorRoleIds());
                if (!ObjectUtils.isEmpty(jgMaintainNotice.getInstanceStatus())) {
                    jgMaintainNotice.setInstanceStatus(jgMaintainNotice.getInstanceStatus() + "," + workflowResultDto.getNextExecutorRoleIds());
                } else {
                    jgMaintainNotice.setInstanceStatus(workflowResultDto.getNextExecutorRoleIds());
                }
                jgMaintainNotice.setNoticeStatus(String.valueOf(FlowStatusEnum.TO_BE_PROCESSED.getCode()));
                // 上个代办改为已办
                HashMap<String, Object> taskMap = new HashMap<>();
                taskMap.put("taskStatus", FlowStatusEnum.TO_BE_PROCESSED.getCode());
                taskMap.put("taskStatusLabel", FlowStatusEnum.TO_BE_PROCESSED.getName());
                taskMap.put("flowStatus", FlowStatusEnum.TO_BE_PROCESSED.getCode());
                taskMap.put("flowStatusLabel", FlowStatusEnum.TO_BE_PROCESSED.getName());
                taskMap.put("relationId", jgMaintainNotice.getInstanceId());
                taskV2Model = commonService.updateTaskModel(taskMap);
                TaskModelDto taskModelDto = new TaskModelDto();
                BeanUtils.copyProperties(taskV2Model, taskModelDto);
                // 创建新的代办
                TaskMessageDto taskMessageDto = new TaskMessageDto();
                BeanUtils.copyProperties(jgMaintainNotice, taskMessageDto);
                taskModelDto.setModel(taskMessageDto);
                taskModelDto.setTaskName(workflowResultDto.getNextTaskName());
                taskModelDto.setExecuteUserIds(workflowResultDto.getNextExecutorUserIds());
                taskModelDto.setFlowStatus(FlowStatusEnum.TO_BE_PROCESSED.getCode());
                taskModelDto.setFlowStatusLabel(FlowStatusEnum.TO_BE_PROCESSED.getName());
                taskModelDto.setFlowCode(workflowResultDto.getNextTaskId());
                taskModelDto.setTaskStatusLabel(FlowStatusEnum.TO_BE_PROCESSED.getName());
                taskModelDto.setNextExecuteUser(workflowResultDto.getNextExecutorRoleIds());
                commonService.buildTaskModel(Collections.singletonList(taskModelDto));
            }
        } else {
            jgMaintainNotice.setPromoter("");
            jgMaintainNotice.setNoticeStatus(String.valueOf(FlowStatusEnum.REJECTED.getCode()));
            // 上个代办改为已办
            HashMap<String, Object> taskMap = new HashMap<>();
            taskMap.put("taskStatus", jgMaintainNotice.getNoticeStatus());
            taskMap.put("taskStatusLabel", FlowStatusEnum.REJECTED.getName());
            taskMap.put("relationId", jgMaintainNotice.getInstanceId());
            taskMap.put("flowStatus", FlowStatusEnum.REJECTED.getCode());
            taskMap.put("flowStatusLabel", FlowStatusEnum.REJECTED.getName());
            taskV2Model = commonService.updateTaskModel(taskMap);
            TaskModelDto taskModelDto = new TaskModelDto();
            BeanUtils.copyProperties(taskV2Model, taskModelDto);
            // 创建新的代办
            TaskMessageDto taskMessageDto = new TaskMessageDto();
            BeanUtils.copyProperties(jgMaintainNotice, taskMessageDto);
            taskModelDto.setModel(taskMessageDto);
            taskModelDto.setTaskName(workflowResultDto.getNextTaskName());
            taskModelDto.setExecuteUserIds(workflowResultDto.getNextExecutorUserIds());
            taskModelDto.setFlowStatus(FlowStatusEnum.REJECTED.getCode());
            taskModelDto.setFlowStatusLabel(FlowStatusEnum.REJECTED.getName());
            taskModelDto.setFlowCode(workflowResultDto.getNextTaskId());
            taskModelDto.setNextExecuteUser(workflowResultDto.getNextExecutorRoleIds());
            taskModelDto.setPageType("edit");
            commonService.buildTaskModel(Collections.singletonList(taskModelDto));
        }
        jgMaintainNotice.setNextExecuteUserIds(workflowResultDto.getNextExecutorUserIds());
        jgMaintainNotice.setNextTaskId(workflowResultDto.getNextTaskId());
        jgMaintainNoticeMapper.updateById(jgMaintainNotice);
    }

    private TaskResultDTO assembleData(JgMaintainNotice jgMaintainNotice, String op, String opinion) {
        TaskResultDTO taskResultDTO = new TaskResultDTO();
        taskResultDTO.setResultCode("approvalStatus");
        taskResultDTO.setTaskId(jgMaintainNotice.getNextTaskId());
        if (!StringUtils.isEmpty(opinion)) {
            taskResultDTO.setComment(opinion);
        }
        HashMap<String, Object> map = new HashMap<>();
        map.put("approvalStatus", op);
        taskResultDTO.setNextExecuteUserCompanyCode("1".equals(op) ? jgMaintainNotice.getInstallUnitCreditCode() : jgMaintainNotice.getReceiveCompanyCode());
        taskResultDTO.setVariable(map);
        return taskResultDTO;
    }
}