/*
 * Author: wangjian
 * 生成ServiceImpl
 */
package com.tofly.watermeter.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tofly.common.core.util.DateUtil;
import com.tofly.common.core.util.StringUtil;
import com.tofly.common.core.util.io.ExcelUtil;
import com.tofly.common.oauth.exception.ToflyDeniedException;
import com.tofly.common.oauth.util.SecurityUtils;
import com.tofly.watermeter.custom.entity.*;
import com.tofly.watermeter.custom.entity.webserverbean.ExchangeSB;
import com.tofly.watermeter.custom.entity.webserverbean.InstallCustom;
import com.tofly.watermeter.custom.entity.webserverbean.NewInstall;
import com.tofly.watermeter.custom.service.BwsbazTempService;
import com.tofly.watermeter.custom.service.websb.WebSBservice;
import com.tofly.watermeter.custom.util.Date7Utils;
import com.tofly.watermeter.em.Constant;
import com.tofly.watermeter.em.ExcelExportFileTypeEnum;
import com.tofly.watermeter.entity.Bwkjzjpz;
import com.tofly.watermeter.entity.Bwrksbdatail;
import com.tofly.watermeter.entity.Qfkhjbxx;
import com.tofly.watermeter.entity.Watermeter;
import com.tofly.watermeter.mapper.BwrksbdatailMapper;
import com.tofly.watermeter.service.*;
import com.tofly.watermeter.util.JxlsUtils;
import com.tofly.watermeter.util.ThreadPoolUtil;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * 入库水表明细表
 *
 * @author admin
 * @date Wed Mar 10 00:00:00 CST 2021
 */

@Service("bwrksbdatailService")
@AllArgsConstructor
public class BwrksbdatailServiceImpl extends ServiceImpl<BwrksbdatailMapper, Bwrksbdatail> implements BwrksbdatailService {

    private final BwsbazTempService tempService;
    private final BwhbdatailService hbdetailService;
    private final BwrktotalService totalService;
    private final QfkhjbxxService qfkhjbxxService;
    private final WatermeterService watermeterService;
    private final WebSBservice webSBservice;
    private final BwkjzjpzService bwkjzjpzService;

    @Override
    public int insertBatch(List<Bwrksbdatail> sbList, Bwrksbdatail sbAll) {
        return baseMapper.insertBatch(sbList, sbAll);
    }

    @Override
    public Bwrksbdatail getBySbbh(String sbbh) {
        if (StringUtil.isEmpty(sbbh)) {
            throw new ToflyDeniedException("请传入水表编号");
        }
        //处理水表编号，将水表编号拆成两部分：前缀和数字
//        int index = sbbh.indexOf("-");
//        //前缀
//        String prefix = sbbh.substring(0, index + 1);
//        //编号
//        Long number = Long.parseLong(sbbh.substring(index + 1));

        return baseMapper.getSbXq(sbbh);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean install(Bwrksbdatail bwrksbdatail) {

        //查询是否有这个用户  调用森仙居那边的接口  ；又喊不调用了，使用自己的客户信息，我佛了  改来改去的
//        KhInfo khInfo = new KhInfo();
//        khInfo.setYHBH(bwrksbdatail.getBwKhbh());
//        //查询
//        khInfo.setACTION("query");
//        //查询森鑫炬客户信息
//        Qfkhjbxx khMap = webSBservice.getKH(khInfo).get(0);

        //又走本库客户信息；我佛了
        //查询是否有这个用户
        Qfkhjbxx khMap = qfkhjbxxService.getOne(Wrappers.<Qfkhjbxx>lambdaQuery()
                .eq(Qfkhjbxx::getYhbh, bwrksbdatail.getBwKhbh()));


        //判断客户的注释掉，因为存在新装水表时没有客户的情况
//        if (StringUtil.isNull(khMap)) {
//            throw new ToflyDeniedException("请正确输入用户信息");
//        }


        //暂时取消判断
//        if (StringUtil.isNotNull(khMap.getSbbh())) {
//            throw new ToflyDeniedException("用戶：" + khMap.getYhxm() + "，已新装水表：" + khMap.getSbbh());
//        }


        //安装前查询是否已经安装了，避免已安装的水表
        Bwrksbdatail detail = baseMapper.selectOne(Wrappers.<Bwrksbdatail>lambdaQuery()
                .eq(Bwrksbdatail::getBwSbbh, bwrksbdatail.getBwSbbh())
                .select(Bwrksbdatail::getBwKhxm, Bwrksbdatail::getBwKhdz, Bwrksbdatail::getBwAzrq,
                        Bwrksbdatail::getBwAzry, Bwrksbdatail::getBwSbzt, Bwrksbdatail::getBwLsbh));
        if (StringUtil.isNull(detail)) {
            throw new ToflyDeniedException("请正确输入水表编号");
        }
        if (bwrksbdatail.getFlag() == 1 && "57".equals(detail.getBwSbzt())) {
            throw new ToflyDeniedException("该水表已安装在" + detail.getBwKhdz() + "，由" + detail.getAzryName() + "在" + detail.getBwAzrq() + "时安装");
        }
        if (!"56".equals(detail.getBwSbzt())) {
            //不是出库状态，不能新装
            throw new ToflyDeniedException("请仔细检查水表编号是否输错，该水表不符合新装流程，请规范操作");
        }
        //存在新装没有客户信息的情况，我佛了，这个业务后面提及的
        if (StringUtil.isNull(khMap)) {
            //修改水表信息中的客户信息
            baseMapper.update(null, Wrappers.<Bwrksbdatail>lambdaUpdate()
                    .eq(Bwrksbdatail::getBwSbbh, bwrksbdatail.getBwSbbh())
                    .set(Bwrksbdatail::getBwSbqd, 0)
                    .set(Bwrksbdatail::getBwAzry, bwrksbdatail.getBwAzry())
                    .set(Bwrksbdatail::getBwAzrq, bwrksbdatail.getBwAzrq())
                    .set(Bwrksbdatail::getBwSbzt, "57")
                    .set(Bwrksbdatail::getZjpdTime, bwrksbdatail.getBwAzrq()));
        } else {
            //修改水表信息中的客户信息
            baseMapper.update(null, Wrappers.<Bwrksbdatail>lambdaUpdate()
                    .eq(Bwrksbdatail::getBwSbbh, bwrksbdatail.getBwSbbh())
                    .set(Bwrksbdatail::getBwKhbh, khMap.getYhbh())
                    .set(StringUtil.isNotEmpty(khMap.getYhxm()), Bwrksbdatail::getBwKhxm, khMap.getYhxm())
                    .set(StringUtil.isNotEmpty(khMap.getYhdz()), Bwrksbdatail::getBwKhdz, khMap.getYhdz())
                    .set(StringUtil.isNotEmpty(khMap.getLxdh()), Bwrksbdatail::getBwKhdh, khMap.getLxdh())
                    .set(Bwrksbdatail::getBwSbqd, 0)
                    .set(Bwrksbdatail::getBwAzry, bwrksbdatail.getBwAzry())
                    .set(Bwrksbdatail::getBwAzrq, bwrksbdatail.getBwAzrq())
                    .set(Bwrksbdatail::getBwSbzt, "57")
                    .set(Bwrksbdatail::getZjpdTime, bwrksbdatail.getBwAzrq()));
            String cjCcode = qfkhjbxxService.getCodeById(bwrksbdatail.getBwSbcj());
            String lxCcode = qfkhjbxxService.getCodeById(bwrksbdatail.getBwSblx());
            String kjCcode = qfkhjbxxService.getCodeById(bwrksbdatail.getBwSbkj());
            //计算下次周检到期时间
            String xcZjrq = calculateXczjrq(lxCcode, kjCcode, bwrksbdatail.getBwAzrq());
            //又喊修改我们自己的客户表；我淦  ；修改客户信息中的水表信息
            qfkhjbxxService.update(Wrappers.<Qfkhjbxx>lambdaUpdate()
                    .eq(Qfkhjbxx::getYhbh, bwrksbdatail.getBwKhbh()).set(Qfkhjbxx::getSbbh, bwrksbdatail.getBwSbbh())
                    .set(Qfkhjbxx::getSbcj, cjCcode).set(Qfkhjbxx::getSbkj, kjCcode)
                    .set(Qfkhjbxx::getSblx, lxCcode).set(Qfkhjbxx::getAzrq, bwrksbdatail.getBwAzrq())
                    .set(Qfkhjbxx::getSbdd, 0).set(Qfkhjbxx::getBcZjrq, bwrksbdatail.getBwAzrq())
                    .set(Qfkhjbxx::getZbry, bwrksbdatail.getBwAzry())
                    .set(StringUtil.isNotEmpty(xcZjrq), Qfkhjbxx::getXcZjrq, xcZjrq));
            //暂不能修改第三方数据库中客户信息的水表数据
            NewInstall newInstall = new NewInstall();
            newInstall.setYHBH(bwrksbdatail.getBwKhbh());
            newInstall.setSBBH(bwrksbdatail.getBwSbbh());
            newInstall.setSBCJ(cjCcode);
            newInstall.setSBKJ(kjCcode);
            newInstall.setSBLX(lxCcode);
            newInstall.setAZRQ(DateUtil.parseDateToStr("yyyyMMdd", bwrksbdatail.getBwAzrq()));
            newInstall.setSBQD("0");
            newInstall.setAZRY(bwrksbdatail.getBwAzry().toString());
            newInstall.setACTION("query");
            //安装方式好像还没有喔，但是森鑫炬必须要这个参数，所以暂时写一个 1
            newInstall.setAZFS("立式");
            //森鑫炬修改客户信息
//            Map map = webSBservice.newInstall(newInstall);
            //异步执行，提高效率
            ExchangeSB exchangeSB = null;
            sysSXJAzOrHbData(newInstall, exchangeSB, "1");
        }

        return true;
    }

    /**
     * 异步执行同步更新森鑫炬安装水表数据
     *
     * @param newInstall
     */
    @Async
    @Transactional(rollbackFor = Exception.class)
    public void sysSXJAzOrHbData(NewInstall newInstall, ExchangeSB exchangeSB, String azORhbflag) {

        //安装
        if ("1".equals(azORhbflag)) {
            ThreadPoolUtil.executorService.execute(new Runnable() {
                @Override
                public void run() {
                    //森鑫炬修改客户信息
                    Map map = webSBservice.newInstall(newInstall);
                    //0000表示成功
                    if ("0000".equals(map.get("Code").toString())) {

                    }
                    //返回的提示
                    if (StringUtil.isNotNull(map.get("message"))) {

                    }
                }
            });
        }
        //换表
        else if ("2".equals(azORhbflag)) {
            ThreadPoolUtil.executorService.execute(new Runnable() {
                @Override
                public void run() {
                    //森鑫炬修改客户信息
                    Map map = webSBservice.exchangeSB(exchangeSB);

                    System.out.println("11111111");
                }
            });
        }

    }


    @Override
    public boolean delteInsatll(Long id) {
        //查询水表编号和客户编号
        Bwrksbdatail bwrksbdatail = baseMapper.selectOne(Wrappers.<Bwrksbdatail>lambdaQuery().eq(Bwrksbdatail::getId, id)
                .select(Bwrksbdatail::getBwSbbh, Bwrksbdatail::getBwKhbh));
        //判断；如果换表记录中有新表新装状态的，在删除时应该限制

        baseMapper.update(null, Wrappers.<Bwrksbdatail>lambdaUpdate()
                .eq(Bwrksbdatail::getId, id)
                .set(Bwrksbdatail::getBwKhbh, "")
                .set(Bwrksbdatail::getBwKhxm, "")
                .set(Bwrksbdatail::getBwKhdz, "")
                .set(Bwrksbdatail::getBwKhdh, "")
                .set(Bwrksbdatail::getBwSbqd, "")
                .set(Bwrksbdatail::getBwAzry, "")
                .set(Bwrksbdatail::getBwAzrq, "")
                .set(Bwrksbdatail::getBwGspq, "")
                .set(Bwrksbdatail::getZjpdTime, "")
                .set(Bwrksbdatail::getBwSbzt, "56"));

        qfkhjbxxService.update(Wrappers.<Qfkhjbxx>lambdaUpdate().eq(Qfkhjbxx::getYhbh, bwrksbdatail.getBwKhbh())
                .set(Qfkhjbxx::getSbbh, "")
                .set(Qfkhjbxx::getSbcj, "").set(Qfkhjbxx::getSbkj, "")
                .set(Qfkhjbxx::getSblx, "").set(Qfkhjbxx::getAzrq, "")
                .set(Qfkhjbxx::getSbdd, "").set(Qfkhjbxx::getBcZjrq, "")
                .set(Qfkhjbxx::getZbry, ""));


//还要修改第三方那边的水表信息数据，但是提供的接口无法实现，比如将水表编号设置为 空时 无法修改


        return true;
    }

    @Override
    public Bwrksbdatail getByYhbh(String yhbh) {


        return baseMapper.getByYhbh(yhbh);
    }

    @Override
    @SneakyThrows
    public IPage<BwsbazTemp> excelAz(Page page, MultipartFile file) {
        if (StringUtil.isNull(file)) {
            throw new ToflyDeniedException("请上传Excel文件");
        }
        //文件流
        InputStream inputStream = file.getInputStream();
        //实体类与Excel表格式
        ExcelUtil excel = new ExcelUtil(BwsbazTemp.class);
        //Excel中的数据导入到实体类
        List<BwsbazTemp> listAz = excel.importExcel(inputStream);
        //查询数据库中已经导入的数据
        List<BwsbazTemp> listAll = tempService.list();
        //根据Excel导入的数据和查出来的数据比较，然后比对水表编号，查看是否有重复的数据
        Map<String, BwsbazTemp> collect = listAll.stream().collect(Collectors.toMap(BwsbazTemp::getSbbh, m -> m, (k1, k2) -> k1));
        //得到重复数据
        List<String> sbbh = listAz.stream().filter(k -> collect.get(k.getSbbh()) != null).map(BwsbazTemp::getSbbh).collect(Collectors.toList());
        if (sbbh.size() > 0) {
            throw new ToflyDeniedException("水表编号：" + JSONArray.toJSONString(sbbh) + "为重复数据，文件导入失败");
        }
        //过滤空对象排序，用新的集合接收
        List<BwsbazTemp> bwsbazTempList = listAz.stream().filter(k -> StringUtil.isNotEmpty(k.getSbbh())).collect(Collectors.toList());
        //得到水表编号这一属性
        List<String> sbbhList = bwsbazTempList.stream().map(BwsbazTemp::getSbbh).collect(Collectors.toList());
        //还要根据水表编号查询水表信息，这里没做出来

        //将数据插入到临时数据
        boolean flag = tempService.saveBatch(bwsbazTempList);
        if (flag) {
            //返回Excel中导入的数据
            return tempService.page(page, Wrappers.<BwsbazTemp>lambdaQuery().in(BwsbazTemp::getSbbh, sbbhList));
        }
        return null;
    }

    @Override
    public boolean deleteTemp(List<String> sbbh) {
        tempService.remove(Wrappers.<BwsbazTemp>lambdaQuery().in(BwsbazTemp::getSbbh, sbbh));
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchImport(SbInfo infos) {
        //Excel导入 输入的数据（存在客户不存在或者水表不存在的情况，所以后面需要对这两个信息进行判断真假）
        List<BwsbazTemp> tempList = infos.getList();
        if (StringUtil.isNotNull(tempList) && tempList.size() > 1000) {
            throw new ToflyDeniedException("Excel批量安装数量最多1000条");
        }

        //拿到批量插入的数据，然后去查询是否有这个客户信息
        List<String> kbbhList = tempList.stream().map(BwsbazTemp::getKhbh).collect(Collectors.toList());

//        //又不调用了  我佛；修改
//        //根据客户编号 查询客户信息
//        //请求第三方客户档案接口
//        Map khMap = null;
//        //查询是否有这个用户  调用森仙居那边的接口  绝了  一会喊不调用一会又喊调用的
        //根据客户编号 查询客户信息
        List<Qfkhjbxx> qfkhjbxxList = qfkhjbxxService.list(Wrappers.<Qfkhjbxx>lambdaQuery().in(Qfkhjbxx::getYhbh, kbbhList));

//        //调用森鑫炬的客户信息
//        KhInfo khInfo = new KhInfo();
//        String khbhListStr = kbbhList.stream().collect(Collectors.joining(","));
//        khInfo.setYHBH(khbhListStr);
//        khInfo.setACTION("query");
//        List<Qfkhjbxx> qfkhjbxxList = webSBservice.getKH(khInfo);

        if (StringUtil.isNull(qfkhjbxxList) || qfkhjbxxList.size() == 0) {
            throw new ToflyDeniedException("请认真输入每位客户的编号");
        }

        //查询出来的客户编号
        Map<String, Qfkhjbxx> map = qfkhjbxxList.stream().collect(Collectors.toMap(Qfkhjbxx::getYhbh, m -> m));
        //比较传入的客户编号和查询出来的客户编号，把传入的没有的客户编号过滤出来返回，让其修改客户编号
        List<String> defKhbh = kbbhList.stream().filter(k -> StringUtil.isNull(map.get(k))).collect(Collectors.toList());
        if (defKhbh.size() > 0) {
            throw new ToflyDeniedException("客户编号：" + JSONArray.toJSONString(defKhbh) + "不正确，请检查后再输入");
        }

        //查询客户信息中是否有已经安装了水表的   暂时排除这个判断
//        List<String> keSbList = qfkhjbxxList.stream().filter(k -> StringUtil.isNotEmpty(k.getSbbh()))
//                .map(Qfkhjbxx::getYhbh).collect(Collectors.toList());
//        if (StringUtil.isNotNull(keSbList) && keSbList.size() > 0) {
//            throw new ToflyDeniedException("以下客户：" + JSONArray.toJSONString(keSbList) + "，已新装水表；请核对客户信息再上传");
//        }


        //批量安装在一个Excel表中安装人员都是一样的，所以只要第一个安装人员
        String azry = tempList.stream().map(BwsbazTemp::getAzry).collect(Collectors.toList()).get(0);
        //根据安装人员名称获取安装人员ID
        List<Long> userList = baseMapper.getUserIdByName(azry);
        if (userList.size() == 0) {
            throw new ToflyDeniedException("请正确输入安装人员姓名");
        }
        Long user = userList.get(0);


        //根据水表编号，查询安装水表的厂家、类型、口径信息
        List<Bwrksbdatail> sbList = baseMapper.selectList(Wrappers.<Bwrksbdatail>lambdaQuery()
                .in(Bwrksbdatail::getBwSbbh, tempList.stream().map(BwsbazTemp::getSbbh).collect(Collectors.toList()))
                .select(Bwrksbdatail::getBwSbkj, Bwrksbdatail::getBwSbcj, Bwrksbdatail::getBwSblx, Bwrksbdatail::getBwSbbh, Bwrksbdatail::getBwSbzt));
        if (StringUtil.isNull(sbList)) {
            throw new ToflyDeniedException("请认真输入每个水表编号");
        }

        //判断Excel输入的水表编号正确与否
        Map<String, Bwrksbdatail> bhAndBeanMap = sbList.stream().collect(Collectors.toMap(Bwrksbdatail::getBwSbbh, m -> m));
        //不存在的水表过滤
        List<String> sbbhList = tempList.stream().filter(k -> StringUtil.isNull(bhAndBeanMap.get(k.getSbbh())))
                .map(BwsbazTemp::getSbbh).collect(Collectors.toList());
        if (sbbhList.size() > 0) {
            throw new ToflyDeniedException("水表编号：" + JSONArray.toJSONString(sbbhList) + "不正确，请检查后再录入");
        }

        //以下两个判断，过程都是一样的，所以后面优化，直接使用普通for循环过滤出来
//        List<String> installSb = sbList.stream().filter(m -> "57".equals(m.getBwSbzt())).map(Bwrksbdatail::getBwSbbh).collect(Collectors.toList());
//        if (StringUtil.isNotNull(installSb) && installSb.size() > 0) {
//            throw new ToflyDeniedException("以下水表" + JSONArray.toJSONString(installSb) + "，已新装，不能重复安装");
//        }
        //判断水表出库没有，只有出库了才可以安装
        List<String> noCkSb = sbList.stream().filter(m -> !"56".equals(m.getBwSbzt())).map(Bwrksbdatail::getBwSbbh).collect(Collectors.toList());
        if (StringUtil.isNotNull(noCkSb) && noCkSb.size() > 0) {
            //不是出库状态，不能新装
            throw new ToflyDeniedException("以下水表" + JSONArray.toJSONString(noCkSb) + "，不符合新装流程，请规范操作");
        }
        //水表安装，修改原有的水表数据
//        baseMapper.updateAzSb(tempList, user, qfkhjbxxList.get(0).getCbpq());
        baseMapper.updateAzSb(tempList, user);//这里的抄表片区统一了，说的是批量都是同一个片区批量的

        //查询所有口径周检配置
//        List<Bwkjzjpz> kjPzList = kjpzService.list(Wrappers.<Bwkjzjpz>lambdaQuery().select(Bwkjzjpz::getKjName, Bwkjzjpz::getMonth));
        //list转MAP，key存储口径和value存储相应的周期检查月份
//        Map<String, Integer> mapKjMonth = kjPzList.stream().collect(Collectors.toMap(Bwkjzjpz::getKjName, Bwkjzjpz::getMonth));

//        List<Qfkhjbxx> updatekh = new ArrayList<>();
        //修改客户信息；这个是修改我们数据的，暂时不修改了，修改森鑫炬的。
//        qfkhjbxxService.updateBatchById(updatekh);
// 保存客户信息数据
        action(qfkhjbxxList, tempList, sbList, user);

        return true;
    }

    /**
     * 更新森鑫炬那边客户安装信息
     *
     * @param qfkhjbxxList 客户List
     * @param tempList
     * @param sbList
     * @param user
     */
    @Async
    public void action(List<Qfkhjbxx> qfkhjbxxList, List<BwsbazTemp> tempList, List<Bwrksbdatail> sbList, Long user) {
        //客户信息表中的厂家、类型、口径不存ID了，喊存CCODE；我淦，又要改  真的麻烦；查询所有厂家、口径、类型
        List<Map> codeList = qfkhjbxxService.getCodeByFids();
        //转MAP，存水表编号和客户信息
        Map<String, String> khAndSbMap = tempList.stream().collect(Collectors.toMap(BwsbazTemp::getKhbh, BwsbazTemp::getSbbh));
        //转MAP，存水表编号和安装日期
        Map<String, Date> khAndAzrqMap = tempList.stream().collect(Collectors.toMap(BwsbazTemp::getKhbh, BwsbazTemp::getAzrq));
//        //转MAP，存水表编号和安装人员
//        Map<String, String> sbAndAzry = tempList.stream().collect(Collectors.toMap(BwsbazTemp::getSbbh, BwsbazTemp::getAzry));
        List<Bwkjzjpz> bwkjzjpzList = bwkjzjpzService.list(Wrappers.<Bwkjzjpz>lambdaQuery().select(Bwkjzjpz::getCsCode, Bwkjzjpz::getMonth));

        ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                //转MAP；方便取值
                Map<Long, String> idAndCode = codeList.stream().collect(Collectors.toMap(s -> Long.valueOf(s.get("id").toString()), s -> s.get("ccode").toString()));
                Map<String, Bwrksbdatail> bhAndSbinfo = sbList.stream().collect(Collectors.toMap(Bwrksbdatail::getBwSbbh, k -> k));
                //周期配置转map
                Map<String, Integer> zjpzMap = bwkjzjpzList.stream().collect(Collectors.toMap(Bwkjzjpz::getCsCode, Bwkjzjpz::getMonth));
                //存放客户水表安装信息
                List<InstallCustom> newInstallList = new ArrayList<>();
                for (Qfkhjbxx v : qfkhjbxxList) {
                    String yhbh = v.getYhbh();
                    //保存是K为用户编号 ； V为水表编号
                    String sbbh = khAndSbMap.get(yhbh);
                    //安装日期
                    Date azrq = khAndAzrqMap.get(yhbh);
                    //过滤拿到满足条件的水表信息
//                    Bwrksbdatail bwrksbdatail = sbList.stream().filter(k -> sbbh.equals(k.getBwSbbh())).collect(Collectors.toList()).get(0);
                    Bwrksbdatail bwrksbdatail = bhAndSbinfo.get(sbbh);
//                    String cj = null;
//                    String lx = null;
//                    String kj = null;
//                    //过滤只要对应的厂家、类型、口径的CCODE
//                    List<Map> cjLisr = codeList.stream().filter(m -> (bwrksbdatail.getBwSbcj()).equals(Long.valueOf(m.get("id") + ""))).collect(Collectors.toList());
//                    List<Map> lxLisr = codeList.stream().filter(m -> (bwrksbdatail.getBwSblx()).equals(Long.valueOf(m.get("id") + ""))).collect(Collectors.toList());
//                    List<Map> kjLisr = codeList.stream().filter(m -> (bwrksbdatail.getBwSbkj()).equals(Long.valueOf(m.get("id") + ""))).collect(Collectors.toList());
//                    if (StringUtil.isNotNull(cjLisr) && cjLisr.size() > 0) {
//                        cj = cjLisr.get(0).get("ccode").toString();
//                    }
//                    if (StringUtil.isNotNull(lxLisr) && lxLisr.size() > 0) {
//                        lx = lxLisr.get(0).get("ccode").toString();
//                    }
//                    if (StringUtil.isNotNull(kjLisr) && kjLisr.size() > 0) {
//                        kj = kjLisr.get(0).get("ccode").toString();
//                    }
                    String cj = idAndCode.get(bwrksbdatail.getBwSbcj());
                    String lx = idAndCode.get(bwrksbdatail.getBwSblx());
                    String kj = idAndCode.get(bwrksbdatail.getBwSbkj());
                    Integer month = null;
                    //如果是普通表(code为 1);则只能根据口径计算到期月份时间；只有电子表才根据表型计算到期月份时间
                    if ("1".equals(lx)) {
                        month = zjpzMap.get(kj);
                    } else {
                        //如果是电子表就根据水表类型
                        month = zjpzMap.get(lx);
                    }
                    //下次周检时间
                    String xcZjrq = null;
                    if (StringUtil.isNotNull(month)) {
                        Date xcrq = Date7Utils.addNextPeriod(month, azrq);
                        xcZjrq = DateUtil.parseDateToStr("yyyyMM", xcrq);
                    }
                    //修改森鑫炬客户数据参数
                    NewInstall install = new NewInstall();
                    install.setYHBH(v.getYhbh());
                    install.setSBBH(sbbh);
                    install.setSBCJ(cj);
                    install.setSBKJ(kj);
                    install.setSBLX(lx);
                    install.setAZRQ(DateUtil.parseDateToStr("yyyyMMdd", azrq));
                    install.setSBQD("0");
                    install.setAZRY(user.toString());
                    install.setACTION("query");
                    install.setAZFS("立式");
                    //森鑫炬似乎没有批量修改新装客户信息的接口
                    Map map = webSBservice.newInstall(install);
                    InstallCustom installCustom = JSONArray.parseObject(JSONObject.toJSONString(install), InstallCustom.class);
                    installCustom.setAzrqTime(azrq);
                    installCustom.setXcZjrq(xcZjrq);
                    newInstallList.add(installCustom);
                }
                //更新本地数据库客户水表安装信息
                qfkhjbxxService.updateBatchCustom(newInstallList);
            }
        });

    }

    /**
     * @param lxCcode 水表类型code
     * @param kjCcode 水表口径code
     * @param time    安装时间或换表时间
     * @return 返回下次周检到期时间
     */
    public String calculateXczjrq(String lxCcode, String kjCcode, Date time) {
        //计算下次周检日期
        //如果是普通表(code为 1);则只能根据口径计算到期月份时间；只有电子表才根据表型计算到期月份时间
        Bwkjzjpz bwkjzjpz = null;
        if ("1".equals(lxCcode)) {
            bwkjzjpz = bwkjzjpzService.getOne(Wrappers.<Bwkjzjpz>lambdaQuery().eq(Bwkjzjpz::getCsCode, kjCcode).eq(Bwkjzjpz::getCsFlag, "0"));
        } else {
            //电子表
            bwkjzjpz = bwkjzjpzService.getOne(Wrappers.<Bwkjzjpz>lambdaQuery().eq(Bwkjzjpz::getCsCode, lxCcode).eq(Bwkjzjpz::getCsFlag, "1"));
        }
        //下次周检时间
        String xcZjrq = null;
        if (StringUtil.isNotNull(bwkjzjpz)) {
            Integer month = bwkjzjpz.getMonth();
            if (StringUtil.isNotNull(month)) {
                Date xcrq = Date7Utils.addNextPeriod(month, time);
                xcZjrq = DateUtil.parseDateToStr("yyyyMM", xcrq);
            }
        }
        return xcZjrq;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean exchange(CustomHbdetail bwhbdatail) {
        if (StringUtil.isEmpty(bwhbdatail.getBwHbyy())) {
            throw new ToflyDeniedException("请输入换表原因");
        }
        if (StringUtil.isNull(bwhbdatail.getBwJbzd())) {
            throw new ToflyDeniedException("请填写旧表止读");
        }
        //还是要传旧表编号，而且返回给了APP
        String jbNum = bwhbdatail.getBwJbbh();
        String xbNum = bwhbdatail.getBwXbbh();
        String yhbh = bwhbdatail.getBwKhbh();
        if (StringUtil.isEmpty(yhbh)) {
            throw new ToflyDeniedException("请传递客户编号");
        }
        if (xbNum.equals(jbNum)) {
            throw new ToflyDeniedException("请正确输入旧表编号与新表编号，两者不能重复");
        }
        //先查询旧表信息
//        Bwrksbdatail jbInfo = baseMapper.selectOne(Wrappers.<Bwrksbdatail>lambdaQuery()
//                .eq(Bwrksbdatail::getBwSbbh, jbNum)
//                .select(Bwrksbdatail::getBwKhbh, Bwrksbdatail::getBwKhxm,
//                        Bwrksbdatail::getBwKhdz, Bwrksbdatail::getBwKhdh,
//                        Bwrksbdatail::getBwGspq, Bwrksbdatail::getBwSbqd,
//                        Bwrksbdatail::getBwSbcj, Bwrksbdatail::getBwSbkj,
//                        Bwrksbdatail::getBwSblx, Bwrksbdatail::getBwSbzt,
//                        Bwrksbdatail::getBwAzrq));
        //这里改成用用户表号查询客户信息，主要原因是由于旧表水表编号可能存在重复或者无表的情况，所以使用用户编号查询才是唯一标识
        Qfkhjbxx JBqfkhjbxx = qfkhjbxxService.getKhInfoByYhbh(yhbh);
        if (StringUtil.isNull(JBqfkhjbxx)) {
            throw new ToflyDeniedException("旧表水表不存在，请正确输入旧表水表");
        }
        //新表
        Bwrksbdatail ss = baseMapper.selectOne(Wrappers.<Bwrksbdatail>lambdaQuery().eq(Bwrksbdatail::getBwSbbh, xbNum)
                .select(Bwrksbdatail::getBwSbbh, Bwrksbdatail::getBwSbcj, Bwrksbdatail::getBwSbkj, Bwrksbdatail::getBwSblx, Bwrksbdatail::getBwSbzt));
        if (StringUtil.isNull(ss)) {
            throw new ToflyDeniedException("请正确输入新表信息");
        }
        //判断新表是否是已经出库(56)或者已维修好(950)的水表；备注：已维修好的水表可以直接进行换表操作
        String sbzt = ss.getBwSbzt();
        if (!("950".equals(sbzt) || "56".equals(sbzt))) {
            throw new ToflyDeniedException("请正确输入新表信息");
        }
        //根据客户中的水表信息CODE转换为水表信息ID
        JBqfkhjbxx.setSbcjId(qfkhjbxxService.getIdByCode(2, JBqfkhjbxx.getSbcj()));
        JBqfkhjbxx.setSbkjId(qfkhjbxxService.getIdByCode(1, JBqfkhjbxx.getSbkj()));
        JBqfkhjbxx.setSblxId(qfkhjbxxService.getIdByCode(3, JBqfkhjbxx.getSblx()));
        //涉及到旧表换表，则旧表必须是已经安装的状态
//        if (!"57".equals(jbInfo.getBwSbzt())) {
//            throw new ToflyDeniedException("请正确输入旧表水表");
//        }

//        String yhbh = JBqfkhjbxx.getYhbh();
        String yhxm = JBqfkhjbxx.getYhxm();
        String yhdz = JBqfkhjbxx.getYhdz();
        String lxdh = JBqfkhjbxx.getLxdh();
        Date azrq = JBqfkhjbxx.getAzrq();
        //换表中的新表就是安装
        baseMapper.update(null, Wrappers.<Bwrksbdatail>lambdaUpdate()
                .eq(Bwrksbdatail::getBwSbbh, xbNum)
                .set(Bwrksbdatail::getBwKhbh, yhbh).set(StringUtil.isNotEmpty(yhxm), Bwrksbdatail::getBwKhxm, yhxm)
                .set(StringUtil.isNotEmpty(yhdz), Bwrksbdatail::getBwKhdz, yhdz)
                .set(StringUtil.isNotEmpty(lxdh), Bwrksbdatail::getBwKhdh, lxdh).set(Bwrksbdatail::getBwSbqd, 0)
                .set(Bwrksbdatail::getBwAzry, SecurityUtils.getUserId()).set(Bwrksbdatail::getBwAzrq, bwhbdatail.getBwHbrq())
                .set(Bwrksbdatail::getBwSbzt, "57"));
        //这里全部改成的是“” , 后面改一下
        //查询有没有这个旧表
        Bwrksbdatail isExistJbInfo = baseMapper.selectOne(Wrappers.<Bwrksbdatail>lambdaQuery()
                .eq(Bwrksbdatail::getBwSbbh, jbNum)
                .select(Bwrksbdatail::getBwSbbh));
        //如果本套系统中存在该水表，那么就对旧表信息进行更改
        if (StringUtil.isNotNull(isExistJbInfo)) {
            baseMapper.update(null, Wrappers.<Bwrksbdatail>lambdaUpdate()
                    .eq(Bwrksbdatail::getBwSbbh, jbNum)
//                .set(Bwrksbdatail::getBwKhbh, "").set(Bwrksbdatail::getBwKhxm, "")
//                .set(Bwrksbdatail::getBwKhdh, "").set(Bwrksbdatail::getBwKhdz, "")
//                .set(Bwrksbdatail::getBwGspq, "").set(Bwrksbdatail::getBwAzry, "").set(Bwrksbdatail::getBwAzrq, "")
                    .set(Bwrksbdatail::getBwSbzt, "630"));//这里改成换表状态
//                .set("0".equals(flag), Bwrksbdatail::getBwSbzt, "61").set("1".equals(flag), Bwrksbdatail::getBwSbzt, "55"));
//                .set(Bwrksbdatail::getCreateDate, null).set(Bwrksbdatail::getBwAzrq, null)
        }

        //计算表用时情况
        Long diffDateDay = Date7Utils.diffDateDay(azrq, bwhbdatail.getBwHbrq());
        //保存换表信息
        bwhbdatail.setSyDate(diffDateDay);
        bwhbdatail.setJbAzrq(azrq);
        bwhbdatail.setBwKhbh(yhbh);
        bwhbdatail.setBwKhdh(lxdh);
        bwhbdatail.setBwKhdz(yhdz);
        bwhbdatail.setBwKhxm(yhxm);
        //TODO
//        bwhbdatail.setBwJbcj(JBqfkhjbxx.getSbcjId());
//        bwhbdatail.setBwJblx(JBqfkhjbxx.getSblxId());
//        bwhbdatail.setBwJbkj(JBqfkhjbxx.getSbkjId());
//        bwhbdatail.setBwXbcj(ss.getBwSbcj());
//        bwhbdatail.setBwXbkj(ss.getBwSbkj());
//        bwhbdatail.setBwXblx(ss.getBwSblx());
        hbdetailService.save(bwhbdatail);

        //得到新表厂家、口径、类型名称
//        Bwrksbdatail sbDetail = baseMapper.selectOne(Wrappers.<Bwrksbdatail>lambdaQuery().eq(Bwrksbdatail::getBwSbbh, xbNum)
//                .select(Bwrksbdatail::getBwSbcj, Bwrksbdatail::getBwSbkj, Bwrksbdatail::getBwSblx));
        //查找周检周期
//        Integer month = kjpzService.getOne(Wrappers.<Bwkjzjpz>lambdaQuery().eq(Bwkjzjpz::getKjName, ss.getSbkjName())
//                .select(Bwkjzjpz::getMonth)).getMonth();
        //计算下次周检时间
//        Date zjTime = Date7Utils.addNextPeriod(month, bwhbdatail.getBwHbrq());
        //客户信息表中的厂家、类型、口径不存ID了，喊存CCODE；我淦，又要改  真的麻烦；查询所有厂家、口径、类型
//        List<Map> codeList = qfkhjbxxService.getCodeByFids();

        //过滤只要对应的厂家、类型、口径的CCODE
        String cjCcode = qfkhjbxxService.getCodeById(ss.getBwSbcj());
        String lxCcode = qfkhjbxxService.getCodeById(ss.getBwSblx());
        String kjCcode = qfkhjbxxService.getCodeById(ss.getBwSbkj());
        //计算下次周检到期时间
        String xcZjrq = calculateXczjrq(lxCcode, kjCcode, bwhbdatail.getBwHbrq());
        //修改我们客户信息数据表；后面又说不修改了，用森鑫炬的接口
        qfkhjbxxService.update(Wrappers.<Qfkhjbxx>lambdaUpdate().eq(Qfkhjbxx::getYhbh, yhbh)
                .set(Qfkhjbxx::getSbcj, cjCcode).set(Qfkhjbxx::getSblx, lxCcode)
                .set(Qfkhjbxx::getSbkj, kjCcode).set(Qfkhjbxx::getAzrq, bwhbdatail.getBwHbrq())
                .set(Qfkhjbxx::getZhHbrq, bwhbdatail.getBwHbrq())
                .set(Qfkhjbxx::getBcZjrq, bwhbdatail.getBwHbrq())
                .set(Qfkhjbxx::getSbbh, xbNum)
                .set(StringUtil.isNotEmpty(xcZjrq), Qfkhjbxx::getXcZjrq, xcZjrq)
                .set(Qfkhjbxx::getZbry, bwhbdatail.getBwHbry()));


        //修改第三方的客户换表后的信息信息
        //暂时第三方还没有接口，无法做
        //有接口做了
        ExchangeSB exchangeSB = new ExchangeSB();
        exchangeSB.setACTION("query");
        exchangeSB.setYHBH(yhbh);
        exchangeSB.setSQR(bwhbdatail.getBwHbry().toString());//申请人；我们的换表没有走工单申请，没有申请人 //必填，暂时跑通
        exchangeSB.setSQYY(bwhbdatail.getBwHbyy());//必填，暂时跑通
        exchangeSB.setJBQD("0");
        exchangeSB.setJBZD(bwhbdatail.getBwJbzd().toString());
        exchangeSB.setHBSL((bwhbdatail.getBwJbzd() - 0) + "");
        exchangeSB.setHBYY(bwhbdatail.getBwHbyy());
        exchangeSB.setBZ(bwhbdatail.getBwBz());
        exchangeSB.setHBR(bwhbdatail.getBwHbry().toString());
        exchangeSB.setHBRQ(DateUtil.parseDateToStr("yyyyMMdd", bwhbdatail.getBwHbrq()));
        exchangeSB.setCZY(bwhbdatail.getCreateUser().toString());
        exchangeSB.setHBSLJSFS("2");
        exchangeSB.setXBQD("0");
        exchangeSB.setSBSBM(xbNum);//森鑫炬那边的参数必填，但是我们没有这个参数字段，所以加一个数据在这里，暂时跑通
        exchangeSB.setSBBH(xbNum);
        exchangeSB.setSBQFH(xbNum);//森鑫炬那边的参数必填，但是我们没有这个参数字段，所以加一个数据在这里，暂时跑通
        exchangeSB.setSBMP(cjCcode);
        exchangeSB.setSBLX(lxCcode);
        exchangeSB.setSBKJ(kjCcode);
        exchangeSB.setSBXH(lxCcode);//森鑫炬那边的参数必填，但是我们没有这个参数字段，所以加一个数据在这里，暂时跑通
        exchangeSB.setXBDD("0");
        exchangeSB.setSBJXJG("");
        exchangeSB.setSBAZFS("立式");

//        Map map = webSBservice.exchangeSB(exchangeSB);
        NewInstall newInstall = null;
        sysSXJAzOrHbData(newInstall, exchangeSB, "2");
//        if (StringUtil.isNotNull(map.get("data"))) {
//            return map.get("data").toString();
//        } else {
//            return map.get("message").toString();
//        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean exchangeApp(CustomHbdetail bwhbdatail) {

        if (StringUtil.isEmpty(bwhbdatail.getBwHbyy())) {
            throw new ToflyDeniedException("请输入换表原因");
        }
        //还是要传旧表编号，而且返回给了APP
        String jbNum = bwhbdatail.getBwJbbh();
        String xbNum = bwhbdatail.getBwXbbh();
        String xbRfid = bwhbdatail.getXbRfid();
        String jbRfid = bwhbdatail.getJbRfid();
        String yhbh = bwhbdatail.getBwKhbh();
        if (StringUtil.isEmpty(yhbh)) {
            throw new ToflyDeniedException("请传递客户编号");
        }
        //如果传了RFID，则需要判断一体化里面有没有这个RFID，避免重复
        if (StringUtil.isNotEmpty(xbRfid)) {
            Watermeter watermeter = watermeterService.getOne(Wrappers.<Watermeter>lambdaQuery().eq(Watermeter::getRfid, xbRfid)
                    .eq(Watermeter::getStatus, "1")
                    .select(Watermeter::getId, Watermeter::getSid));
            if (StringUtil.isNotNull(watermeter)) {
                throw new ToflyDeniedException("已经存在RFID：" + xbRfid + "；请重新输入");
            }
        }
//        String flag = bwhbdatail.getFlag();
        if (xbNum.equals(jbNum)) {
            throw new ToflyDeniedException("请正确输入旧表编号与新表编号，两者不能重复");
        }
        Qfkhjbxx JBqfkhjbxx = qfkhjbxxService.getKhInfoByYhbh(yhbh);
        if (StringUtil.isNull(JBqfkhjbxx)) {
            throw new ToflyDeniedException("旧表水表不存在，请正确输入旧表水表");
        }
        //新表
        Bwrksbdatail ss = baseMapper.selectOne(Wrappers.<Bwrksbdatail>lambdaQuery().eq(Bwrksbdatail::getBwSbbh, xbNum)
                .select(Bwrksbdatail::getBwSbbh, Bwrksbdatail::getBwSbcj, Bwrksbdatail::getBwSbkj, Bwrksbdatail::getBwSblx,
                        Bwrksbdatail::getBwSbzt));
        if (StringUtil.isNull(ss)) {
            throw new ToflyDeniedException("请正确输入新表水表");
        }
        //判断新表是否是已经出库(56)或者已维修好(950)的水表；备注：已维修好的水表可以直接进行换表操作
        String sbzt = ss.getBwSbzt();
        if (!("950".equals(sbzt) || "56".equals(sbzt))) {
            throw new ToflyDeniedException("请正确输入新表信息");
        }
        //根据客户中的水表信息CODE转换为水表信息ID
        JBqfkhjbxx.setSbcjId(qfkhjbxxService.getIdByCode(2, JBqfkhjbxx.getSbcj()));
        JBqfkhjbxx.setSbkjId(qfkhjbxxService.getIdByCode(1, JBqfkhjbxx.getSbkj()));
        JBqfkhjbxx.setSblxId(qfkhjbxxService.getIdByCode(3, JBqfkhjbxx.getSblx()));
        //涉及到旧表换表，则旧表必须是已经安装的状态
//        if (!"57".equals(jbInfo.getBwSbzt())) {
//            throw new ToflyDeniedException("请正确输入旧表水表");
//        }
//        String yhbh = JBqfkhjbxx.getYhbh();
        String yhxm = JBqfkhjbxx.getYhxm();
        String yhdz = JBqfkhjbxx.getYhdz();
        String lxdh = JBqfkhjbxx.getLxdh();
        Date azrq = JBqfkhjbxx.getAzrq();
        //换表中的新表就是安装
        baseMapper.update(null, Wrappers.<Bwrksbdatail>lambdaUpdate()
                .eq(Bwrksbdatail::getBwSbbh, xbNum)
                .set(Bwrksbdatail::getBwKhbh, yhbh).set(StringUtil.isNotEmpty(yhxm), Bwrksbdatail::getBwKhxm, yhxm)
                .set(StringUtil.isNotEmpty(yhdz), Bwrksbdatail::getBwKhdz, yhdz)
                .set(StringUtil.isNotEmpty(lxdh), Bwrksbdatail::getBwKhdh, lxdh).set(Bwrksbdatail::getBwSbqd, 0)
                .set(Bwrksbdatail::getBwAzry, SecurityUtils.getUserId()).set(Bwrksbdatail::getBwAzrq, bwhbdatail.getBwHbrq())
                .set(Bwrksbdatail::getBwSbzt, "57"));

        //这里全部改成的是“” , 后面改一下
        //查询有没有这个旧表
        Bwrksbdatail isExistJbInfo = baseMapper.selectOne(Wrappers.<Bwrksbdatail>lambdaQuery()
                .eq(Bwrksbdatail::getBwSbbh, jbNum)
                .select(Bwrksbdatail::getBwSbbh));
        //如果有就更新旧表信息
        if (StringUtil.isNotNull(isExistJbInfo)) {
            baseMapper.update(null, Wrappers.<Bwrksbdatail>lambdaUpdate()
                    .eq(Bwrksbdatail::getBwSbbh, jbNum)
                    .set(Bwrksbdatail::getBwSbzt, "630"));//这里改成换表状态
        }

        //计算抄表用时
        Long diffDateDay = Date7Utils.diffDateDay(azrq, bwhbdatail.getBwHbrq());
        //保存换表信息
        bwhbdatail.setSyDate(diffDateDay);
        bwhbdatail.setJbAzrq(azrq);
        bwhbdatail.setBwKhbh(yhbh);
        bwhbdatail.setBwKhdh(lxdh);
        bwhbdatail.setBwKhdz(yhdz);
        bwhbdatail.setBwKhxm(yhxm);
        //TODO
//        bwhbdatail.setBwJbcj(JBqfkhjbxx.getSbcjId());
//        bwhbdatail.setBwJblx(JBqfkhjbxx.getSblxId());
//        bwhbdatail.setBwJbkj(JBqfkhjbxx.getSbkjId());
//        bwhbdatail.setBwXbcj(ss.getBwSbcj());
//        bwhbdatail.setBwXbkj(ss.getBwSbkj());
//        bwhbdatail.setBwXblx(ss.getBwSblx());
//        bwhbdatail.setBwHbry(SecurityUtils.getUserId());
        hbdetailService.save(bwhbdatail);
        //换表修改一体化中旧表表位数据；将原有的水表改为禁用；然后新增一条该客户数据，客户信息不变，更新水表信息
        Watermeter watermeter = watermeterService.getOne(Wrappers.<Watermeter>lambdaQuery()
                .eq(Watermeter::getSid, jbNum).eq(Watermeter::getStatus, "1"));
        if (StringUtil.isNotNull(watermeter)) {
            Long watermeterId = watermeter.getId();
            //修改旧表位置状态为 禁用
            watermeterService.update(Wrappers.<Watermeter>lambdaUpdate().eq(Watermeter::getId, watermeterId).set(Watermeter::getStatus, "0"));
            //往表位里面添加 新表
            watermeter.setSid(xbNum);
            watermeter.setDiameter(ss.getBwSbkj());
            watermeter.setMetertype(ss.getBwSblx());
            watermeter.setManufacturer(ss.getBwSbcj().toString());
            watermeter.setRfid(xbRfid);
            watermeter.setId(null);
            watermeter.setCreateUserName(null);
            watermeter.setStatus("1");
            watermeterService.save(watermeter);
        }
        //过滤只要对应的厂家、类型、口径的CCODE
        String cjCcode = qfkhjbxxService.getCodeById(ss.getBwSbcj());
        String lxCcode = qfkhjbxxService.getCodeById(ss.getBwSblx());
        String kjCcode = qfkhjbxxService.getCodeById(ss.getBwSbkj());
        //计算下次周检到期时间
        String xcZjrq = calculateXczjrq(lxCcode, kjCcode, bwhbdatail.getBwHbrq());
        //换表人员
        Long hbryId = SecurityUtils.getUserId();
        //修改我们客户信息数据表；后面又说不修改了，用森鑫炬的接口
        qfkhjbxxService.update(Wrappers.<Qfkhjbxx>lambdaUpdate().eq(Qfkhjbxx::getYhbh, yhbh)
                .set(Qfkhjbxx::getSbcj, cjCcode).set(Qfkhjbxx::getSblx, lxCcode)
                .set(Qfkhjbxx::getSbkj, kjCcode).set(Qfkhjbxx::getAzrq, bwhbdatail.getBwHbrq())
                .set(Qfkhjbxx::getZhHbrq, bwhbdatail.getBwHbrq())
                .set(Qfkhjbxx::getBcZjrq, bwhbdatail.getBwHbrq())
                .set(Qfkhjbxx::getSbbh, xbNum)
                .set(StringUtil.isNotEmpty(xcZjrq), Qfkhjbxx::getXcZjrq, xcZjrq)
                .set(Qfkhjbxx::getZbry, hbryId));

        //修改第三方的客户换表后的信息
        ExchangeSB exchangeSB = new ExchangeSB();
        exchangeSB.setACTION("query");
        exchangeSB.setYHBH(yhbh);
        exchangeSB.setSQR(hbryId.toString());//申请人；我们的换表没有走工单申请，没有申请人 //必填，暂时跑通
        exchangeSB.setSQYY(bwhbdatail.getBwHbyy());//必填，暂时跑通
        exchangeSB.setJBQD("0");
        exchangeSB.setJBZD(bwhbdatail.getBwJbzd().toString());
        exchangeSB.setHBSL((bwhbdatail.getBwJbzd() - 0) + "");
        exchangeSB.setHBYY(bwhbdatail.getBwHbyy());
        exchangeSB.setBZ(bwhbdatail.getBwBz());
        exchangeSB.setHBR(hbryId.toString());
        exchangeSB.setHBRQ(DateUtil.parseDateToStr("yyyyMMdd", bwhbdatail.getBwHbrq()));
        exchangeSB.setCZY(hbryId.toString());
        exchangeSB.setHBSLJSFS("2");
        exchangeSB.setXBQD("0");
        exchangeSB.setSBSBM(xbNum);//森鑫炬那边的参数必填，但是我们没有这个参数字段，所以加一个数据在这里，暂时跑通
        exchangeSB.setSBBH(xbNum);
        exchangeSB.setSBQFH(xbNum);//森鑫炬那边的参数必填，但是我们没有这个参数字段，所以加一个数据在这里，暂时跑通
        exchangeSB.setSBMP(cjCcode);
        exchangeSB.setSBLX(lxCcode);
        exchangeSB.setSBKJ(kjCcode);
        exchangeSB.setSBXH(lxCcode);//森鑫炬那边的参数必填，但是我们没有这个参数字段，所以加一个数据在这里，暂时跑通
        exchangeSB.setXBDD("0");
        exchangeSB.setSBJXJG("");
        exchangeSB.setSBAZFS("立式");
//        Map map = webSBservice.exchangeSB(exchangeSB);
        NewInstall newInstall = null;
        sysSXJAzOrHbData(newInstall, exchangeSB, "2");
        return true;
    }


    @Override
    public Long getNumAndQz(Long rkId) {
        return baseMapper.getNumAndQz(rkId);
    }

    @Override
    public IPage<Map> getsbkc(Page page, String bwSbcj, String bwSbkj, String bwSblx) {
        List<String> cjList = null;
        List<String> kjList = null;
        List<String> lxList = null;
        if (StringUtil.isNotEmpty(bwSbcj)) {
            cjList = Arrays.asList(bwSbcj.split(","));
        }
        if (StringUtil.isNotEmpty(bwSbkj)) {
            kjList = Arrays.asList(bwSbkj.split(","));
        }
        if (StringUtil.isNotEmpty(bwSblx)) {
            lxList = Arrays.asList(bwSblx.split(","));
        }
        return totalService.getSbKc(page, cjList, kjList, lxList);
    }

    @Override
    public IPage<Map> getInstall(Page page, Statistic statistic) {
        List<String> cjList = null;
        List<String> kjList = null;
        List<String> lxList = null;
        String bwSbcj = statistic.getSbcj();
        String bwSbkj = statistic.getSbkj();
        String bwSblx = statistic.getSblx();
        if (StringUtil.isNotEmpty(bwSbcj)) {
            cjList = Arrays.asList(bwSbcj.split(","));
        }
        if (StringUtil.isNotEmpty(bwSbkj)) {
            kjList = Arrays.asList(bwSbkj.split(","));
        }
        if (StringUtil.isNotEmpty(bwSblx)) {
            lxList = Arrays.asList(bwSblx.split(","));
        }
        return baseMapper.getInstall(page, statistic, cjList, kjList, lxList);
    }


    @Override
    public IPage<Bwrksbdatail> getHbInfo(Page page, Statistic statistic) {
        return baseMapper.getHbInfo(page, statistic);
    }

    @Override
    public IPage<Map> getScrapInfo(Long cj, Long kj, Long lx, String state) {
        return baseMapper.getScrapInfo(cj, kj, lx, state);
    }


    @Override
    public IPage<Map> getCkSb(Page page, Statistic statistic) {
        List<String> cjList = null;
        List<String> kjList = null;
        List<String> lxList = null;
        String bwSbcj = statistic.getSbcj();
        String bwSbkj = statistic.getSbkj();
        String bwSblx = statistic.getSblx();
        if (StringUtil.isNotEmpty(bwSbcj)) {
            cjList = Arrays.asList(bwSbcj.split(","));
        }
        if (StringUtil.isNotEmpty(bwSbkj)) {
            kjList = Arrays.asList(bwSbkj.split(","));
        }
        if (StringUtil.isNotEmpty(bwSblx)) {
            lxList = Arrays.asList(bwSblx.split(","));
        }
        return baseMapper.getCkSb(page, statistic, cjList, kjList, lxList);
    }

    @Override
    public List<Map> getHb(Statistic statistic, HttpServletResponse response) {
        List<String> cjList = null;
        List<String> kjList = null;
        List<String> lxList = null;
        String bwSbcj = statistic.getSbcj();
        String bwSbkj = statistic.getSbkj();
        String bwSblx = statistic.getSblx();
        //按照月份查询情况
        String startMonth = statistic.getStartMonth();
        String endMonth = statistic.getEndMonth();
        //按照具体时间查询情况
        Date startTime = statistic.getStartTime();
        Date endTime = statistic.getEndTime();
        //是否导出
        String template = statistic.getTemplateFlag();

        if (StringUtil.isNotEmpty(bwSbcj)) {
            cjList = Arrays.asList(bwSbcj.split(","));
        }
        if (StringUtil.isNotEmpty(bwSbkj)) {
            kjList = Arrays.asList(bwSbkj.split(","));
        }
        if (StringUtil.isNotEmpty(bwSblx)) {
            lxList = Arrays.asList(bwSblx.split(","));
        }
        //先厂家汇总数量统计 （如果是按照月份查询，那么还会对月份进行分组，如果按照具体时间，则只会对厂家分组查询）
        List<StatisticResult> cjColletList = baseMapper.getMonthCj(statistic, cjList, kjList, lxList);
        //然后再分具体厂家、口径、类型数量统计
        List<StatisticResult> specificList = baseMapper.getMonthSpecific(statistic, cjList, kjList, lxList);

        if (StringUtil.isNotEmpty(startMonth) && StringUtil.isNotEmpty(endMonth)) {
            //对具体进行月份、厂家分组 然后将分组后的相同月份相同厂家；不同口径、类型的数据放入到月份厂家汇总数据中
            Map<String, List<StatisticResult>> monthSpecificMap = specificList.stream()
                    .collect(Collectors.groupingBy(v -> "月份" + v.getMonth() + "厂家" + v.getSbcj()));
            //处理数据，放入汇总数据中
            cjColletList.forEach(v -> {
                String month = v.getMonth();
                String sbcj = v.getSbcj();
                String query = "月份" + month + "厂家" + sbcj;
                List<StatisticResult> equalMonthSpercificList = monthSpecificMap.get(query);
                v.setStatisticResultList(equalMonthSpercificList);
            });
            //对总数据进行月份分组
            //最终处理的结果是：以月份为第一列汇总，然后厂家分类的汇总数据，然后又是不同口径、类型的详情列表数据
            Map<String, List<StatisticResult>> monthCjMap = cjColletList.stream().collect(Collectors.groupingBy(StatisticResult::getMonth));
            //处理结果展示数据
            List<Map> mapList = new ArrayList<>();
            monthCjMap.forEach((k, v) -> {
                Map map = new HashMap(10);
                map.put("month", k);
                map.put("resultList", v);
                int cell = 0;
                //Excel表导出合并时有用，表示合并的行数；所以需要拿到数据中月份下面最多有多少条数据(行数)
                for (StatisticResult rows : v) {
                    cell = cell + rows.getStatisticResultList().size();
                }
                map.put("row", cell);
                mapList.add(map);
            });
            //是否导出
            if ("1".equals(template)) {
                // 根据templateServiceType,templateFlag获取对应模板数据，找到枚举中相应的Excel文件名、路径等信息
                ExcelExportFileTypeEnum excelExportFileTypeEnum = ExcelExportFileTypeEnum.getExcelExportFileTypeEnum("exchangeMonthService", template);
                if (null == excelExportFileTypeEnum) {
                    return null;
                }
                Map<String, Object> model = new HashMap<>(10);
                model.put("dataMap", mapList);
                JxlsUtils.exportExcel(excelExportFileTypeEnum, model, response, Constant.FILE_PATH_TEST_EXPORT_EXCEL);
                return null;
            }
            return mapList;
        }
        //如果是具体时间查询，就是对厂家数据汇总情况
        else if (StringUtil.isNotNull(startTime) && StringUtil.isNotNull(endTime)) {
            //对厂家分组，然后将分组后的相同厂家不同口径、类型的数据放入到厂家汇总数据中
            Map<String, List<StatisticResult>> sbcjSpercificMap = specificList.stream().collect(Collectors.groupingBy(StatisticResult::getSbcj));
            //处理数据，放入汇总数据中
            cjColletList.forEach(v -> {
                String sbcj = v.getSbcj();
                //判断相同厂家数据
                if (sbcjSpercificMap.containsKey(sbcj)) {
                    v.setStatisticResultList(sbcjSpercificMap.get(sbcj));
                }
            });
            //最终处理结果：以厂家为第一列汇总，然后是不同口径、类型的详情列表数据
            Map<String, List<StatisticResult>> cjMap = cjColletList.stream().collect(Collectors.groupingBy(StatisticResult::getSbcj));
            //处理结果展示数据
            List<Map> mapList = new ArrayList<>();
            cjMap.forEach((k, v) -> {
                Map map = new HashMap(10);
                map.put("cj", k);
                map.put("resultList", v);
                mapList.add(map);
            });
            return mapList;
        }
        return null;
    }


    //前缀
    public static String prefix(String sbbh) {
        int index = sbbh.indexOf("-");
        return sbbh.substring(0, index + 1);
    }

    //编号
    public static Long num(String sbbh) {
        int index = sbbh.indexOf("-");
        return Long.parseLong(sbbh.substring(index + 1));
    }


}
