package com.tofly.feesapi.cbgl.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
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.ibm.icu.text.SimpleDateFormat;
import com.tofly.common.core.util.StringUtil;
import com.tofly.feesapi.bjgl.entity.YhCbkxx;
import com.tofly.feesapi.bjgl.service.YhCbkxxService;
import com.tofly.feesapi.bmgl.entity.*;
import com.tofly.feesapi.bmgl.service.*;
import com.tofly.feesapi.cbgl.entity.YyCblr;
import com.tofly.feesapi.cbgl.entity.YyCblrLs;
import com.tofly.feesapi.cbgl.entity.dto.*;
import com.tofly.feesapi.cbgl.entity.vo.*;
import com.tofly.feesapi.cbgl.mapper.YyCblrMapper;
import com.tofly.feesapi.cbgl.service.YyCblrLsService;
import com.tofly.feesapi.cbgl.service.YyCblrService;
import com.tofly.feesapi.common.constant.CbbzEnum;
import com.tofly.feesapi.common.constant.JsbzEnum;
import com.tofly.feesapi.common.constant.ShbzEnum;
import com.tofly.feesapi.common.core.dto.Order;
import com.tofly.feesapi.common.core.dto.PageDto;
import com.tofly.feesapi.common.core.vo.PageResult;
import com.tofly.feesapi.common.core.vo.ResultVo;
import com.tofly.feesapi.common.enums.CblyEnum;
import com.tofly.feesapi.common.exception.FeesErrorCode;
import com.tofly.feesapi.common.exception.FeesException;
import com.tofly.feesapi.dzfp.service.EiKprpzService;
import com.tofly.feesapi.file.entity.File;
import com.tofly.feesapi.file.service.IFileInfoService;
import com.tofly.feesapi.mxcx.entity.dto.QftjSeachFilter;
import com.tofly.feesapi.mxcx.entity.vo.QftjabsSelect;
import com.tofly.feesapi.mxcx.entity.vo.QftjabsSelectCount;
import com.tofly.feesapi.security.util.SecurityUtils;
import com.tofly.feesapi.sfgl.entity.dto.YyQfmxStatFilter;
import com.tofly.feesapi.sfgl.entity.vo.YyStat;
import com.tofly.feesapi.sfgl.service.IZnbCsjsLogService;
import com.tofly.feesapi.sfgl.service.YyQfmxService;
import com.tofly.feesapi.udb.entity.User;
import com.tofly.feesapi.udb.service.IUserService;
import com.tofly.feesapi.xtgl.entity.SysGdcsb;
import com.tofly.feesapi.xtgl.entity.Syscommlog;
import com.tofly.feesapi.xtgl.service.ISysGdcsbService;
import com.tofly.feesapi.xtgl.service.ISyscommlogService;
import com.tofly.feesapi.xtgl.service.impl.SysGdcsbServiceImpl;
import com.tofly.feesapi.yhgl.entity.YhKhjbxx;
import com.tofly.feesapi.yhgl.entity.dto.YhKhjbxxInsert;
import com.tofly.feesapi.yhgl.mapper.YhKhjbxxDbhlsMapper;
import com.tofly.feesapi.yhgl.service.YhKhjbxxDbhlsService;
import com.tofly.feesapi.yhgl.service.YhKhjbxxService;
import com.tofly.feesapi.yhgl.service.YhsjqxService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
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.transaction.support.TransactionTemplate;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

import static com.tofly.feesapi.common.constant.Constants.PERCENT_FORMAT;

@Service("yyCblrService")
@Slf4j
public class YyCblrServiceImpl extends ServiceImpl<YyCblrMapper, YyCblr> implements YyCblrService {

    @Autowired
    private ISysGdcsbService gdcsbService;
    @Autowired
    private YyCblrLsService cblrLsService;
    @Autowired
    private BmCbbService cbbService;
    @Autowired
    private YhCbkxxService cbkxxService;
    @Autowired
    private YhKhjbxxService khjbxxService;
    @Autowired
    private IUserService userService;
    @Autowired
    private SysChildCodeService sysChildCodeService;
    @Autowired
    private ISyscommlogService syscommlogService;
    @Autowired
    private YyQfmxService yyQfmxService;
    @Autowired
    private YhKhjbxxDbhlsService yhKhjbxxDbhlsService;
    @Autowired
    private IFileInfoService iFileInfoService;
    @Autowired
    private TransactionTemplate transactionTemplate;
    @Autowired
    private BmDbhysyhService bmDbhysyhService;
    @Autowired
    private YhsjqxService yhsjqxService;
    @Autowired
    private BmCbplService bmCbplService;
    @Autowired
    private SysGdcsbServiceImpl sysGdcsbService;
    @Autowired
    private BmYslxService yslxService;
    @Autowired
    private BmSjService bmSjService;
    @Autowired
    private IZnbCsjsLogService znbCsjsLogService;

    @Autowired
    private BmYmjzConfigLsService bmYmjzConfigLsService;
    @Autowired
    private BmYmjzConfigService bmYmjzConfigService;

    @Autowired
    private EiKprpzService eiKprpzService;

    @Override
    public YyCblr save(YhKhjbxxInsert insert, YhCbkxx cbkxx) {
        String ssgs = insert.getSsgs();
        String sscbpq = insert.getSscbpq();
        String sscbb = insert.getSscbb();
        String yhbh = cbkxx.getYhbh();
        String cbkh = cbkxx.getCbkh();
        String cbkid = cbkxx.getCbkid();
        return savePlan(yhbh, cbkh, cbkid, ssgs, sscbpq, sscbb);//添加抄表计划
    }

    @Override
    public PageResult<YyCblrSelect> getPage(PageDto pageDto, YyCblrFilter filter) {
        filter.setOrders(null);//与分页参数重合需清除
        if (!StringUtil.isEmpty(filter.getUserId())) {
            filter.setUserId(SecurityUtils.getUserId().toString());
        }
        List<Order> orders = pageDto.getOrders();
        if (orders.size() > 0) {
            orders = orders.stream().map(item -> {
                if (item.getColumn().equals("yhbh")) {
                    Order order = new Order();
                    order.setColumn("a.yhbh");
                    order.setAsc(item.isAsc());
                    return order;
                }
                return item;
            }).collect(Collectors.toList());
            pageDto.setOrders(orders);
        } else {
            orders.add(new Order("a.yhbh", true));
        }
        pageDto.setOrders(orders);

        boolean tf = true;
        String cwrq = filter.getCwrq();
        if (ObjUtil.isNotNull(filter.getBfb())) {
            String selectCwrq = gdcsbService.selectCwrq();
            DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                    .appendPattern("yyyyMM")
                    .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
                    .toFormatter();
            LocalDate localDate = LocalDate.parse(selectCwrq, formatter);
            cwrq = localDate.plusMonths(-1).format(formatter);
        }

        PageDto<YyCblrSelect> page = baseMapper.getPage(pageDto, filter, tf, cwrq);

        if (StringUtil.isNotEmpty(filter.getSfcktp()) && "1".equals(filter.getSfcktp())) {
            if (page != null && !page.getRecords().isEmpty()) {
                page.getRecords().forEach(p -> {
                    List<File> files = iFileInfoService.getFileList(new LambdaQueryWrapper<File>().eq(File::getTableBh, p.getYhbh()).and(c -> c.eq(File::getFileNote, p.getCwrq())));
                    if (files != null && files.size() > 0) {
                        Set<String> set = files.stream().map(File::getFileNewFn).collect(Collectors.toSet());
                        p.setPhoto(StringUtils.join(set, ","));
                    } else {
                        p.setPhoto("");
                    }
                });
            }
        }

        if (ObjUtil.isNotNull(page) && CollUtil.isNotEmpty(page.getRecords())) {
            List<YyCblrSelect> records = page.getRecords();
            List<BmCbpl> bmCbpls = bmCbplService.list();
            if (CollUtil.isNotEmpty(bmCbpls)) {
                Map<String, String> plmap = bmCbpls.stream().collect(Collectors.toMap(BmCbpl::getCode, BmCbpl::getCbyf));
                records.forEach(o -> {
                    String cbplCode = o.getCbpl();
                    if (StrUtil.isNotEmpty(cbplCode)) {
                        o.setCbpl(plmap.get(cbplCode));
                    }
                });
            }
        }

        return page.toVo();
    }

    @Override
    public PageResult<YyCblrSelect> lycbglfy(PageDto pageDto, YyCblrFilter filter) {
        filter.setOrders(null);//与分页参数重合需清除
        if (!StringUtil.isEmpty(filter.getUserId())) {
            filter.setUserId(SecurityUtils.getUserId().toString());
        }
        List<Order> orders = pageDto.getOrders();
        if (orders.size() > 0) {
            orders = orders.stream().map(item -> {
                if (item.getColumn().equals("yhbh")) {
                    Order order = new Order();
                    order.setColumn("a.yhbh");
                    order.setAsc(item.isAsc());
                    return order;
                }
                return item;
            }).collect(Collectors.toList());
            pageDto.setOrders(orders);
        } else {
            orders.add(new Order("a.yhbh", true));
        }

        boolean tf = true;
        String cwrq = filter.getCwrq();
        if (ObjUtil.isNotNull(filter.getBfb())) {
            String selectCwrq = gdcsbService.selectCwrq();
            DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                    .appendPattern("yyyyMM")
                    .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
                    .toFormatter();
            LocalDate localDate = LocalDate.parse(selectCwrq, formatter);
            cwrq = localDate.plusMonths(-1).format(formatter);
        }

        PageDto<YyCblrSelect> page = baseMapper.lycbglfy(pageDto, filter, tf, cwrq);
        if (ObjUtil.isNotNull(page) && CollectionUtil.isNotEmpty(page.getRecords())) {
            Map<String, String> cbplMap = bmCbplService.getCbplMap();
            List<YyCblrSelect> records = page.getRecords();
            records.forEach(o -> {
                Integer xycb = o.getXycb();
                if (ObjUtil.isNull(xycb)) {
                    o.setXycb(0);
                }

                String cbpl = o.getCbpl();
                if (StrUtil.isNotEmpty(cbpl) && StrUtil.isNotEmpty(cbplMap.get(cbpl))) {
                    o.setCbpl(cbplMap.get(cbpl));
                }
            });
        }

        return page.toVo();
    }

    @Override
    public List<String> getCbkids(YyCblrFilter filter) {
        return this.baseMapper.getCbkids(filter);
    }

    @Override
    public YyCblrView getViewById(String yhbh, String cbkh) {
        YyCblrView view = this.baseMapper.getViewById(yhbh, cbkh);
        return view;
    }

    @Override
    @DSTransactional
    public boolean update(YyCblrUpdate update) {
        String yhbh = update.getYhbh();
        String cbkh = update.getCbkh();
        String cblx = update.getCblx();
        if (StringUtils.isBlank(yhbh)) {
            throw new FeesException("用户编号不能为空", FeesErrorCode.BUSINESS_ERROR);
        }
        if (StringUtils.isBlank(cbkh)) {
            throw new FeesException("抄表卡号不能为空", FeesErrorCode.BUSINESS_ERROR);
        }
        if (StringUtils.isBlank(cblx)) {
            throw new FeesException("抄表类型不能为空", FeesErrorCode.BUSINESS_ERROR);
        }
        YyCblr yyCblr = this.getOne(Wrappers.lambdaQuery(YyCblr.class).eq(YyCblr::getYhbh, yhbh).eq(YyCblr::getCbkh, cbkh));

//        if (yyCblr.getShbz() != null && yyCblr.getShbz() == ShbzEnum.审核通过) {
//            throw new FeesException("审核通过不允许修改", FeesErrorCode.BUSINESS_ERROR);
//        }
        if (yyCblr.getJsbz() != null && yyCblr.getJsbz() == JsbzEnum.已算费) {
            throw new FeesException("已算费不允许修改", FeesErrorCode.BUSINESS_ERROR);
        }

        BmCbb cbb = cbbService.getById(yyCblr.getSscbb());
        if (StringUtil.isNotEmpty(cbb.getCby())) {
            yyCblr.setCbrybm(cbb.getCby());
            User user = userService.get(Long.valueOf(cbb.getCby()));
            if (ObjUtil.isNotNull(user)) {
                yyCblr.setCbryxm(user.getRealName());
            }
        }

        BigDecimal before = yyCblr.getScds();//修改前上次读数
        BeanUtils.copyProperties(update, yyCblr);
        BigDecimal sl = getSjsl(update);
        yyCblr.setSl(sl);

        yyCblr.setLrrybm(String.valueOf(SecurityUtils.getUserId()));
        yyCblr.setLrryxm(SecurityUtils.getUser().getRealName());
        if (StringUtil.isNull(update.getCbrq())) {
            yyCblr.setCbrq(new Date());
        } else {
            yyCblr.setCbrq(update.getCbrq());
        }
        yyCblr.setLrrq(yyCblr.getCbrq());
        yyCblr.setCbbz(CbbzEnum.已抄表);
        yyCblr.setCbly(update.getCbly());
        yyCblr.setSbzt(update.getSbzt());
        yyCblr.setShbz(ShbzEnum.审核通过);
        if (updateById(yyCblr)) {
            cbkxxService.lambdaUpdate()
                    .set(YhCbkxx::getFmzt, update.getFmzt())
                    .set(YhCbkxx::getSbzt, yyCblr.getSbzt())
                    .eq(YhCbkxx::getCbkid, yyCblr.getCbkid())
                    .update();
        }
        String xgds = update.getXgds();

        if ("1".equals(xgds)) {
            Syscommlog log = new Syscommlog();
            log.setTablename("yy_cblr");
            BigDecimal after = update.getScds();
            log.setMstext(String.format("抄表录入-修改底数【用户编号%s，抄表卡号%s，修改前%s，修改后%s】", yhbh, cbkh, before, after));
            log.setUserid(String.valueOf(SecurityUtils.getUserId()));

            log.setOptype("Modif");
            LocalDateTime now = LocalDateTime.now();
            log.setAddate(now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss")));
            syscommlogService.save(log);
        }
        return true;
    }

    private BigDecimal getSjsl(YyCblrUpdate update) {
        String cblx = update.getCblx();
        BigDecimal sl = null;
        BigDecimal scds = update.getScds();
        BigDecimal bcds = update.getBcds();
        BigDecimal jjl = update.getJjl();
        if (scds == null) {
            throw new FeesException("上次读数不能为空", FeesErrorCode.BUSINESS_ERROR);
        }
        if (bcds == null) {
            throw new FeesException("本次读数不能为空", FeesErrorCode.BUSINESS_ERROR);
        }
        if (jjl == null && !"-3".equals(cblx)) {
            throw new FeesException("加减量不能为空", FeesErrorCode.BUSINESS_ERROR);
        }

        if ("0".equals(cblx)) {//正常
            sl = bcds.subtract(scds).add(jjl);
        } else if ("-2".equals(cblx)) {//表满度
            String sblcbm = update.getSblc();
            if (StringUtils.isBlank(sblcbm))
                throw new FeesException("水表量程编码不能为空", FeesErrorCode.BUSINESS_ERROR);
            SysChildCode sblc = sysChildCodeService.get("13", sblcbm);
            if (sblc == null) throw new FeesException("水表量程不存在", FeesErrorCode.BUSINESS_ERROR);
            int sblccd = Integer.valueOf(sblcbm);
            sl = new BigDecimal(Math.pow(10, sblccd)).subtract(scds).add(bcds).abs().add(jjl);
            String yhbh = update.getYhbh();
            cbkxxService.updateSblc(yhbh, sblcbm);
        } else if ("-3".equals(cblx)) {//洗换表
            BigDecimal jbzd = update.getJbzd();
            BigDecimal xbqd = update.getXbqd();
            sl = jbzd.subtract(scds).add(bcds.subtract(xbqd));
        } else if ("-8".equals(cblx)) {//表倒走
            sl = bcds.subtract(scds).abs().add(jjl);
        }
        return sl;
    }

    @Override
    public List<YyCblrSelect> getList(YyCblrFilter filter) {
        List<Order> orders = filter.getOrders();
        if (orders.size() > 0) {
            orders = orders.stream().map(item -> {
                if (item.getColumn().equals("yhbh")) {
                    Order order = new Order();
                    order.setColumn("a.yhbh");
                    order.setAsc(item.isAsc());
                    return order;
                }
                return item;
            }).collect(Collectors.toList());
        } else {
            orders.add(new Order("a.yhbh", true));
        }
        filter.setOrders(orders);
        return baseMapper.getList(filter);
    }

    @Override
    public List<CbSltjSelect> cbsltj(YyCblrtjFilter filter) {
        if (!Arrays.asList("cbry", "ysxz", "cbb").contains(filter.getTjlb())) {
            return new ArrayList<>();
        }

        String selectCwrq = gdcsbService.selectCwrq();
        List<CbSltjSelect> cbsltj = new ArrayList<>();

        if (selectCwrq.equals(filter.getCwrq())) {
            cbsltj = cbsltj_one(filter);
        } else {
            cbsltj = cblrLsService.cbsltj(filter);
        }

        return cbsltj;
    }

    @Override
    @Transactional
    public void sccblr() {
        List<BmCbb> cbbs = cbbService.lambdaQuery().select(BmCbb::getSsgs, BmCbb::getSscbpq, BmCbb::getCbbbm).list();
        cbbs = cbbs.stream().sorted(Comparator.comparing(BmCbb::getSsgs)
                .thenComparing(BmCbb::getSscbpq)).collect(Collectors.toList());
        cbbs.forEach(cbb -> {
            sccblr(cbb);
        });
    }

    /**
     * 月末结转-自动审核抄表和计算抄表欠费
     */
    public void cbymjz() {
        Syscommlog syscommlog = new Syscommlog();
        try {
            log.info(DateUtil.now() + " : 月末结转开始 ===================> ");
            String selectCwrq = gdcsbService.selectCwrq();
            //智能表每月汇总
            znbCsjsLogService.znbZdsc(selectCwrq);

            autoAuditCblr(syscommlog);
            // 获取已抄表未算费数据
            List<YyCblr> cblrs = this.lambdaQuery()
                    .eq(YyCblr::getCbbz, CbbzEnum.已抄表.getValue())
                    .eq(YyCblr::getShbz, ShbzEnum.审核通过.getValue())
                    .eq(YyCblr::getJsbz, JsbzEnum.未算费.getValue())
                    .list();

            // 计算欠费明细
            int cgs = yyQfmxService.Tasksf(cblrs);
            int total = cblrs.size();
            syscommlogService.ymjzsfdyrz(total, cgs);

            // 抄表计划更新
            cbymjzDataDis(cblrs, cgs, selectCwrq);

            //第三方开票人结转
            eiKprpzService.Jzkpr();

            log.info(DateUtil.now() + "：月末结转结束 =============================> ");
        } catch (Exception e) {
            log.error("月末结转失败 =============================> ", e);
            String remark = String.format("月末结转失败：%s", e.getMessage());
            syscommlogService.xz("yy_qfmx", "月末结转调用cbymjzTask", remark, "YMJZ");
            throw new FeesException("月末结转失败", FeesErrorCode.BUSINESS_ERROR);
        }
    }

    public void jtljlql() {
        String selectCwrq = sysGdcsbService.selectCwrq();
        String month = selectCwrq.substring(selectCwrq.length() - 2);
        long count = khjbxxService.lambdaQuery()
                .eq(YhKhjbxx::getJtljlqcsj, month)
                .apply("yhbh in (select yhbh from yh_cbkxx where " +
                        "sjbm in (select code from bm_sj wjere jtbz='1') or " +
                        "sjbm1 in (select code from bm_sj wjere jtbz='1') or " +
                        "sjbm2 in (select code from bm_sj wjere jtbz='1'))")
                .count();
        if (count > 0) {
            boolean tf = khjbxxService.lambdaUpdate()
                    .set(YhKhjbxx::getJtzqljl, BigDecimal.ZERO)
                    .eq(YhKhjbxx::getJtljlqcsj, month)
                    .apply("yhbh in (select yhbh from yh_cbkxx where " +
                            "sjbm in (select code from bm_sj wjere jtbz='1') or " +
                            "sjbm1 in (select code from bm_sj wjere jtbz='1') or " +
                            "sjbm2 in (select code from bm_sj wjere jtbz='1'))")
                    .update();
            if (tf) {
                syscommlogService.xz("yy_khjbxx", "计划流量清零调用jtljlqlTask", "计划流量清零成功", "JTLJLQL");
            } else {
                syscommlogService.xz("yy_khjbxx", "计划流量清零调用jtljlqlTask", "计划流量清零失败", "JTLJLQL");
            }
        }

    }

    /**
     * 自动计划审核
     */
    private void autoAuditCblr(Syscommlog syscommlog) {
        // 未审核
        long wshcount = this.lambdaQuery()
                .eq(YyCblr::getCbbz, CbbzEnum.已抄表.getValue())
                .eq(YyCblr::getShbz, ShbzEnum.未审核.getValue())
                .eq(YyCblr::getJsbz, JsbzEnum.未算费.getValue())
                .count();

        if (wshcount > 0) {
            this.lambdaUpdate().eq(YyCblr::getCbbz, CbbzEnum.已抄表)
                    .eq(YyCblr::getShbz, ShbzEnum.未审核)
                    .eq(YyCblr::getJsbz, JsbzEnum.未算费)
                    .set(YyCblr::getShbz, ShbzEnum.审核通过)
                    .update();

            syscommlog.setTablename("yy_cblr");
            syscommlog.setMstext("月末结转调用cbymjzTask");
            syscommlog.setAddate(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss")));
            syscommlog.setRemark(String.format("自动审核抄表数据共%s条", wshcount));
            syscommlog.setUserid("YMJZ");
            syscommlogService.save(syscommlog);
        }

    }

    /**
     * 抄表计划更新、归档，重置下一周期抄表计划
     */
    public void cbymjzDataDis(List<YyCblr> cblrs, int cgs, String selectCwrq) {
        transactionTemplate.execute(status -> {
            boolean tf;
            if (cblrs.size() > 0 && cblrs.size() > cgs) {
                tf = this.baseMapper.YMJZSFSB();
                if (!tf) {
                    log.error("月末结转-失败记录添加到月末结转算费失败表失败");
                    status.setRollbackOnly();
                }
            }

            List<YyCblr> wsfcblrs = this.lambdaQuery()
                    .eq(YyCblr::getCbbz, CbbzEnum.已抄表.getValue())
                    .eq(YyCblr::getJsbz, JsbzEnum.未算费.getValue())
                    .list();

            if (wsfcblrs.size() > 0) {
                czwsfcblr();
            }

            String newCwrq = gdcsbService.autoUpdateCwrq(selectCwrq);

            // 新增抄表历史记录
            tf = this.baseMapper.yyCblrls();
            if (!tf) {
                status.setRollbackOnly();
            }

            //更新普表、远程表档案中的水表起数、最新抄表日期字段
            tf = this.baseMapper.updateCbb();
            if (!tf) {
                log.error("月末结转-更新普表、远程表档案中的水表起数、最新抄表日期字段失败");
                status.setRollbackOnly();
            }

            //结转低保户用户
            String year = selectCwrq.substring(0, selectCwrq.length() - 2);
            tf = yhKhjbxxDbhlsService.insertDbh(year);
            if (!tf) {
                log.error("月末结转-结转低保户用户失败");
                status.setRollbackOnly();
            } //月阶梯累计量清零
            long countyh = khjbxxService.lambdaQuery()
                    .inSql(YhKhjbxx::getYhbh, "SELECT YHBH FROM YH_CBKXX A INNER JOIN BM_SJ B ON (A.SJBM = B.CODE)  WHERE B.JTJSLX = '1'")
                    .count();

            if (countyh > 0) {
                tf = khjbxxService.lambdaUpdate().set(YhKhjbxx::getJtzqljl, 0)
                        .inSql(YhKhjbxx::getYhbh, "SELECT YHBH FROM YH_CBKXX A INNER JOIN BM_SJ B ON (A.SJBM = B.CODE)  WHERE B.JTJSLX = '1'")
                        .update();
                if (!tf) {
                    log.error("月末结转-月阶梯累计量清零失败");
                    status.setRollbackOnly();
                }
            }
            //年阶梯累积量清零,判断结转时间是不是一月份
            if (newCwrq.endsWith("01")) {
                countyh = khjbxxService.lambdaQuery()
                        .inSql(YhKhjbxx::getYhbh, "SELECT YHBH FROM YH_CBKXX A INNER JOIN BM_SJ B ON (A.SJBM = B.CODE)  WHERE B.JTJSLX = '2'")
                        .count();
                if (countyh > 0) {
                    tf = khjbxxService.lambdaUpdate()
                            .set(YhKhjbxx::getJtzqljl, 0)
                            .inSql(YhKhjbxx::getYhbh, "SELECT YHBH FROM YH_CBKXX A INNER JOIN BM_SJ B ON (A.SJBM = B.CODE)  WHERE B.JTJSLX = '2'")
                            .update();
                    if (!tf) {
                        log.error("月末结转-年阶梯累计量清零失败");
                        status.setRollbackOnly();
                    }
                }

                String yhyear = newCwrq.substring(0, selectCwrq.length() - 2);
                countyh = bmDbhysyhService.lambdaQuery()
                        .eq(BmDbhysyh::getYear, yhyear)
                        .count();
                if (countyh == 0) {
                    tf = bmDbhysyhService.insertBmDbh(year, yhyear);
                    if (!tf) {
                        log.info("月末结转-插入低保户用水优惠失败");
                        status.setRollbackOnly();
                    }
                    bmDbhysyhService.lambdaUpdate()
                            .set(BmDbhysyh::getIsdisabled, "0")
                            .eq(BmDbhysyh::getIsdisabled, "1")
                            .eq(BmDbhysyh::getYear, year)
                            .update();
                }

                //低保户累计清零，人口数归为4
                tf = khjbxxService.lambdaUpdate()
                        .set(YhKhjbxx::getRks, 4)
                        .set(YhKhjbxx::getDbhndljl, 0)
                        .inSql(YhKhjbxx::getYhbh, "select yhbh from yh_khjbxx where yhzt='1'")
                        .update();
                if (!tf) {
                    log.info("年末结转-人口数归为4失败");
                    status.setRollbackOnly();
                }
                long countyc = bmYmjzConfigService.lambdaQuery().count();
                if (countyc > 0) {
                    long jzyear = Long.parseLong(newCwrq.substring(0, newCwrq.length() - 2));
                    tf = bmYmjzConfigLsService.insertls(jzyear);
                    if (!tf) {
                        log.info("年末结转-结转月末配置失败");
                        status.setRollbackOnly();
                    }
                }
            } else {
                //低保户累计清零
                tf = khjbxxService.lambdaUpdate()
                        .set(YhKhjbxx::getDbhndljl, 0)
                        .inSql(YhKhjbxx::getYhbh, "select yhbh from yh_khjbxx where yhzt='1'")
                        .update();
                if (!tf) {
                    log.info("月末结转-低保户水量归零失败");
                    status.setRollbackOnly();
                }
            }

            //最后更新抄表计划的数据
            tf = zdgxcblr(newCwrq);
            if (!tf) {
                log.info("月末结转-最后更新抄表计划的数据失败");
                status.setRollbackOnly();
                return false;
            }

            // 根据抄表频率更新标记
            markCblrByCbpl(newCwrq);
            return true;
        });
    }

    private boolean zdgxcblr(String newCwrq) {
        return this.lambdaUpdate()
                .set(YyCblr::getCwrq, newCwrq)
                .setSql("SCDS=BCDS")
                .setSql("sccbrq=(case when cbrq is null then sccbrq else cbrq end)")
                .set(YyCblr::getJjl, 0)
                .set(YyCblr::getSl, 0)
                .set(YyCblr::getCbryxm, "")
                .set(YyCblr::getCbrybm, "")
                .set(YyCblr::getCbrq, "")
                .set(YyCblr::getLrrq, "")
                .set(YyCblr::getLrrybm, "")
                .set(YyCblr::getLrryxm, "")
                .set(YyCblr::getPhoto, "")
                .set(YyCblr::getCbbz, CbbzEnum.未抄表.getValue())
                .set(YyCblr::getShbz, ShbzEnum.未审核.getValue())
                .set(YyCblr::getJsbz, JsbzEnum.未算费.getValue())
                .set(YyCblr::getCbcs, 1)
                .set(YyCblr::getBz, "")
                .set(YyCblr::getCblx, "0")
                .set(YyCblr::getCbfs, "01")
                .set(YyCblr::getCbly, "0")
                .set(YyCblr::getJbzd, 0)
                .set(YyCblr::getXbqd, 0)
                .eq(YyCblr::getSsgs, "1")
                .update();
    }

    private boolean czwsfcblr() {
        return this.lambdaUpdate()
                .set(YyCblr::getCbbz, CbbzEnum.未抄表)
                .set(YyCblr::getShbz, ShbzEnum.未审核)
                .set(YyCblr::getJjl, 0)
                .set(YyCblr::getSl, 0)
                .setSql("BCDS=SCDS")
                .eq(YyCblr::getCbbz, CbbzEnum.已抄表)
                //.eq(YyCblr::getShbz, ShbzEnum.未审核)
                .eq(YyCblr::getJsbz, JsbzEnum.未算费)
                .update();
    }

    /**
     * 批量插入历史抄表明细
     */
    private boolean plcrlscbmx() {
        boolean isSuccess = true;
        Long count = baseMapper.selectCount(Wrappers.<YyCblr>lambdaQuery());

        try {
            if (count > 5000) {
                long size = 5000;
                long maxIndex = (count / size);
                if (count % size > 0) {
                    maxIndex = maxIndex + 1;
                }

                for (long current = 1; current <= maxIndex; current++) {
                    Page<YyCblrLs> page = new Page<>(current, size);
                    List<YyCblrLs> plcxcblrmx = baseMapper.plcxcblrmx(page);
                    plcxcblrmx.forEach(o -> o.setId(IdUtil.simpleUUID().toUpperCase()));
                    cblrLsService.saveBatch(plcxcblrmx);
                }
            } else {
                List<YyCblrLs> plcxcblrmx = baseMapper.cxcblrmx();
                plcxcblrmx.forEach(o -> o.setId(IdUtil.simpleUUID().toUpperCase()));
                cblrLsService.saveBatch(plcxcblrmx);
            }
        } catch (Exception e) {
            log.error("新增抄表历史记录失败 =====================> ", e);
            isSuccess = false;
        }
        return isSuccess;
    }

    /**
     * 抄表频率标记
     */
    private void markCblrByCbpl(String newCwrq) {
        Long count = this.lambdaQuery().count();
        if (count == 0) {
            return;
        }

        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                .appendPattern("yyyyMM")
                .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
                .toFormatter();
        LocalDate localDate = LocalDate.parse(newCwrq, formatter);
        int bjMonth = localDate.getMonthValue();

        List<BmCbpl> bmCbpls = bmCbplService.getBaseMapper().selectList(new QueryWrapper<>());
        if (CollectionUtil.isEmpty(bmCbpls)) {
            log.info("系统未配置抄表频率,无需标记");
            return;
        }

        List<String> cbplCodes = new ArrayList<>();
        bmCbpls.forEach(o -> {
            String code = o.getCode();
            String cbyf = o.getCbyf();
            if (StrUtil.isNotEmpty(code) && StrUtil.isNotEmpty(cbyf)
                    && cbyf.contains(String.valueOf(bjMonth))) {
                cbplCodes.add(code);
            }
        });

        // 更新需要抄表标志
        String cpplcodes = cbplCodes.stream().map(str -> "'" + str + "'").collect(Collectors.joining(","));
        this.lambdaUpdate()
                .set(YyCblr::getXycb, 1)
                .inSql(YyCblr::getCbkid, String.format("select cbkid from yh_cbkxx where cbpl in (%s)", cpplcodes))
                .update();
        log.info("更新需要抄表标志完成");
    }

    @Override
    public List<CbltjSelect> cbltj(YyCblrtjFilter filter) {
        if (!Arrays.asList("cbry", "cbb").contains(filter.getTjlb())) return new ArrayList<>();
        String selectCwrq = gdcsbService.selectCwrq();
        if (selectCwrq.equals(filter.getCwrq())) {
            return this.cbltj_one(filter);
        } else {
            return cblrLsService.cbltj(filter);
        }
    }

    @Override
    public PageResult<YyCbycmxSelect> cbycmx(PageDto pageDto, YyCbycmxFilter filter) {
        PageResult<YyCbycmxSelect> result = cblrLsService.cbycmxPage(pageDto, filter);
        return result;
    }

    @Override
    public List<YyCbycmxSelect> cbycmx(YyCbycmxFilter filter) {
        return cblrLsService.cbycmx(filter);
    }

    @Override
    public void updateJsbz(String cbkid) {
        this.lambdaUpdate()
                .set(YyCblr::getJsbz, JsbzEnum.已算费)
                .eq(YyCblr::getCbkid, cbkid)
                .update();
    }

    @Override
    public CblrCountSelect getPage2(PageDto pageDto, YyCblrFilter filter) {
        filter.setOrders(null);//与分页参数重合需清除
        if (StringUtil.isEmpty(filter.getUserId())) {
            filter.setUserId(SecurityUtils.getUserId().toString());
        }
        PageDto<YyCblrSelect> page = this.baseMapper.getPage2(pageDto, filter, true);
        //所有页合计
        CblrCountSelect cblrCountSelect = this.baseMapper.getCblrCount(filter);
        if (StringUtil.isNotNull(cblrCountSelect)) {
            cblrCountSelect.setList(page.toVo());
        }
        return cblrCountSelect;
    }


    /**
     * 根据用户编号查询抄表记录
     */
    @Override
    public List<YyCblrSelect> getCbjl(QftjSeachFilter filter) {
        List<YyCblrSelect> records = baseMapper.getCbjlByYhbhs(filter);
        return records;
    }

    @Override
    public List<YyCblrSelect> getListCbmx(YyCblrFilter filter) {
        List<YyCblrSelect> list = this.baseMapper.getListCbmx(filter);
        return list;
    }

    @Override
    public Map getZfCblrMap(String cbkid) {
        return this.baseMapper.getZfCblrMap(cbkid);
    }

    @Override
    public Map getZmCblrMap(String cbkid) {
        return this.baseMapper.getZmCblrMap(cbkid);
    }

    @Override
    public YyStat stat(YyQfmxStatFilter filter) {
        return this.baseMapper.stat(filter);
    }

    private List<CbltjSelect> cbltj_one(YyCblrtjFilter filter) {
        List<CbltjSelect> cbltj = baseMapper.cbltj(filter);
        List<User> users = userService.list();
        cbltj.forEach(e -> {
            if ("cbb".equals(filter.getTjlb())) {
                String cbrybm = e.getCby();
                if (cbrybm != null) {
                    users.stream().filter(u -> u.getId().toString().equals(cbrybm)).findFirst()
                            .ifPresent(user -> e.setCby(user.getRealName()));
                }
            }
            if ("cbry".equals(filter.getTjlb())) {
                String cbrybm = e.getTjlb();
                if (cbrybm != null) {
                    users.stream().filter(u -> u.getId().toString().equals(cbrybm)).findFirst()
                            .ifPresent(user -> e.setTjlb(user.getRealName()));
                }
            }
            //e.setScbs(20);
            //e.setYcbs(30);
            Integer ycbs = e.getYcbs();
            Integer scbs = e.getScbs();
            e.setWcbs(ycbs - scbs);
            BigDecimal cbl = new BigDecimal(scbs * 100).divide(new BigDecimal(ycbs), 2, RoundingMode.DOWN);
            e.setCbl(PERCENT_FORMAT.format(cbl));
        });

        if (!cbltj.isEmpty()) {
            int ycbs = cbltj.stream().map(e -> e.getYcbs()).reduce(0, (x, y) -> x + y);
            int scbs = cbltj.stream().map(e -> e.getScbs()).reduce(0, (x, y) -> x + y);
            int scsl = cbltj.stream().map(e -> e.getScsl()).reduce(0, (x, y) -> x + y);
            int wcbs = cbltj.stream().map(e -> e.getWcbs()).reduce(0, (x, y) -> x + y);
            BigDecimal cbl = new BigDecimal(scbs * 100).divide(new BigDecimal(ycbs), 2, RoundingMode.DOWN);
            cbltj.add(new CbltjSelect("合计", ycbs, scbs, scsl, wcbs, PERCENT_FORMAT.format(cbl), ""));
        }
        return cbltj;
    }

    /**
     * 创建抄表计划
     */
    private int sccblr(BmCbb cbb) {
        String cbbbm = cbb.getCbbbm();
        String ssgs = cbb.getSsgs();
        String sscbpq = cbb.getSscbpq();

        // 获取抄表卡信息
        List<YhCbkxx> cbkxxList = getCbkxxList(cbbbm, ssgs);

        String lastCwrq = LocalDate.now().plusMonths(-1).format(DateTimeFormatter.ofPattern("yyyyMM"));

        List<YyCblr> lastCblrs = getCblrs(cbbbm, ssgs, lastCwrq);

        Map<String, BigDecimal> scdsMap = lastCblrs.stream().collect(Collectors.toMap(YyCblr::getCbkid, YyCblr::getBcds));
        String cwrq = gdcsbService.selectCwrq();

        // 生成本次财务日期抄表计划
        List<YyCblr> cblrs = cbkxxList.stream()
                .map(e -> createCblr(ssgs, sscbpq, cbbbm, e, scdsMap.getOrDefault(e.getCbkid(), BigDecimal.ZERO), cwrq))
                .collect(Collectors.toList());

        List<YyCblr> currentCblrs = getCblrs(cbbbm, ssgs, cwrq);
        currentCblrs.forEach(e -> this.removeById(e));

        // 删除上周期计划,已完成的添加到历史记录
        lastCblrs.forEach(e -> this.removeById(e));
        lastCblrs.stream().filter(e -> e.getCbbz() == CbbzEnum.已抄表)
                .forEach(e -> cblrLsService.save(createCblrls(e)));

        cblrs.forEach(e -> this.save(e));
        return cblrs.size();
    }

    private YyCblrLs createCblrls(YyCblr e) {
        YyCblrLs cblrLs = new YyCblrLs();
        BeanUtils.copyProperties(e, cblrLs);
        return cblrLs;
    }

    private YyCblr createCblr(String ssgs, String sscbpq, String cbbbm, YhCbkxx e, BigDecimal scds, String cwrq) {
        YyCblr yyCblr = new YyCblr();
        BeanUtils.copyProperties(e, yyCblr, "bz");
        yyCblr.setSsgs(ssgs);
        yyCblr.setSscbpq(sscbpq);
        yyCblr.setSscbb(cbbbm);
        yyCblr.setCwrq(cwrq);
        yyCblr.setScds(scds);
        return yyCblr;
    }

    private List<YhCbkxx> getCbkxxList(String cbbbm, String ssgs) {
        List<YhKhjbxx> list = khjbxxService.lambdaQuery()
                .select(YhKhjbxx::getYhbh).eq(YhKhjbxx::getSsgs, ssgs).eq(YhKhjbxx::getSscbb, cbbbm).list();

        List<String> yhbhs = list.stream().map(e -> e.getYhbh()).collect(Collectors.toList());
        List<YhCbkxx> cbkxxes = new ArrayList<>();

        if (CollectionUtil.isNotEmpty(yhbhs)) {
            cbkxxes = cbkxxService.lambdaQuery().in(YhCbkxx::getYhbh, yhbhs).list();
        }

        return cbkxxes;
    }

    private List<YyCblr> getCblrs(String cbbbm, String ssgs, String cwrq) {

        List<YyCblr> cblrs = this.lambdaQuery()
                .eq(YyCblr::getSscbb, cbbbm)
                .eq(YyCblr::getSsgs, ssgs)
                .eq(YyCblr::getCwrq, cwrq)
                .list();
        return cblrs;

    }

    private List<CbSltjSelect> cbsltj_one(YyCblrtjFilter filter) {
        List<CbSltjSelect> cbsltj = baseMapper.cbsltj(filter);
//        if ("cbry".equals(filter.getTjlb())) {
//            szrymc(cbsltj);
//        }

        if (!cbsltj.isEmpty()) {
            int cbhs = cbsltj.stream().map(e -> e.getCbhs()).reduce(0, (x, y) -> x + y);
            int cbsl = cbsltj.stream().map(e -> e.getCbsl()).reduce(0, (x, y) -> x + y);
            cbsltj.add(new CbSltjSelect("合计", cbhs, cbsl));
        }
        return cbsltj;
    }

//    private void szrymc(List<CbSltjSelect> cbsltj) {
//        List<User> users = userService.list();
//        if (ObjUtil.isNotNull(users)) {
//            for (CbSltjSelect sltjSelect : cbsltj) {
//                String cbrybm = sltjSelect.getTjlb();
//                if (StrUtil.isNotEmpty(cbrybm) && NumberUtil.isNumber(cbrybm)) {
//                    User user = users.stream().filter(u -> u.getId().toString().equals(cbrybm)).findFirst().orElse(null);
//                    if (StringUtil.isNotNull(user)) {
//                        sltjSelect.setTjlb(user.getRealName());
//                    }
//                }
//            }
//        }
//    }

    private YyCblr savePlan(String yhbh, String cbkh, String strcbkh, String ssgs, String sscbpq, String sscbb) {
        YyCblr plan = new YyCblr();
        String strcwrq = gdcsbService.selectCwrq();
        plan.setCwrq(strcwrq);//财务日期
        plan.setJsbz(JsbzEnum.未算费);//计算标志 0未算费，1已算费
        plan.setJfzt("1");//计费状态  1正常，2停用
        plan.setCbbz(CbbzEnum.未抄表);//未抄表状态
        plan.setShbz(ShbzEnum.未审核);//未审核标志

        plan.setYhbh(String.valueOf(yhbh));//用户编号
        plan.setCbkh(cbkh);//抄表卡号
        plan.setCbkid(strcbkh);//抄表卡ID
        plan.setSsgs(ssgs);//公司
        plan.setSscbpq(sscbpq);//片区
        plan.setSscbb(sscbb);//抄表本
        this.save(plan);
        return plan;
    }


    public ResultVo appUploadInfo(AppCblrUpload uploadInfo, Date date) {

        int code = 0;
        if (StringUtils.isBlank(uploadInfo.getYhbh())) {
            return new ResultVo(-1, "用户编号位空");
        }

        SysGdcsb gdcsb = gdcsbService.getOne(Wrappers.lambdaQuery(SysGdcsb.class).eq(SysGdcsb::getGdbz, "0"));
        if (Objects.isNull(gdcsb)) {
            return new ResultVo(-2, "财务日期异常");
        }

        if (!gdcsb.getCwrq().equals(uploadInfo.getCwrq())) {
            return new ResultVo(-3, "财务日期不匹配");
        }


        YyCblr cblr = this.getOne(Wrappers.lambdaQuery(YyCblr.class).eq(YyCblr::getYhbh, uploadInfo.getYhbh()).eq(YyCblr::getCbkh, uploadInfo.getCbkh()));
        if (Objects.isNull(cblr)) {
            return new ResultVo(-4, "抄表计划异常");
        }

        if (!cblr.getScds().equals(uploadInfo.getScds())) {
            return new ResultVo(-5, "抄表度数不匹配");
            //return code = -5;//抄表度数不一致
        }

        if (cblr.getCbbz() == CbbzEnum.已抄表 || cblr.getJsbz() == JsbzEnum.已算费) {
            //return code = -6; //已抄表 或者 已计算
            return new ResultVo(-6, "当前计划【已抄表】或【已算费】");
        }

        cblr.setCblx(uploadInfo.getCblx());
        cblr.setBcds(uploadInfo.getBcds());
        cblr.setJbzd(uploadInfo.getJbzd());
        cblr.setXbqd(uploadInfo.getXbqd());
        if (uploadInfo.getSjsl().intValueExact() == 0 && (cblr.getBcds().intValueExact() - cblr.getScds().intValueExact() > 0
                && Integer.valueOf(cblr.getCblx()) != -2 && Integer.valueOf(cblr.getCblx()) != -3)) {
            BigDecimal sl = uploadInfo.getBcds().subtract(uploadInfo.getScds());
            cblr.setSl(sl);
        } else {
            cblr.setSl(uploadInfo.getSjsl());
        }

        // cblr.setCbrq(new Date());
        if (StringUtil.isNull(uploadInfo.getCbrq())) {
            cblr.setCbrq(date);
        } else {
            cblr.setCbrq(uploadInfo.getCbrq());
        }
        cblr.setCbrybm(uploadInfo.getCbrybm());
        cblr.setCbryxm(uploadInfo.getCbryxm());
        cblr.setLrrybm(uploadInfo.getCbrybm());
        cblr.setLrryxm(uploadInfo.getCbryxm());
        cblr.setCbbz(CbbzEnum.已抄表);
        cblr.setShbz(ShbzEnum.未审核);
        cblr.setCbly(CblyEnum.APP抄表.getValue().toString());
        cblr.setBz(CblyEnum.APP抄表.name());
        cblr.setCbfs(uploadInfo.getCbfs());
        cblr.setLrrq(date);
        cblr.setSbzt(uploadInfo.getSbzt());

        if (!StringUtils.isEmpty(uploadInfo.getFmzt()) || !StringUtils.isEmpty(uploadInfo.getSbzt())) {
            cbkxxService.lambdaUpdate()
                    .set(YhCbkxx::getFmzt, uploadInfo.getFmzt())
                    .set(YhCbkxx::getSbzt, uploadInfo.getSbzt())
                    .eq(YhCbkxx::getCbkid, cblr.getCbkid())
                    .update();
        }

        boolean isu = this.update(cblr, new QueryWrapper<YyCblr>().eq("yhbh", cblr.getYhbh()));
        if (isu)
            return new ResultVo(1, "上传成功.");
        else
            return new ResultVo(0, "上传失败");
    }

    public Map<String, BigDecimal> getZbFbs() {
        List<Map> mapList = this.baseMapper.getZbFbs();
        Map<String, BigDecimal> map = new HashMap<>();
        for (Map m : mapList) {
            String cbkid = m.get("cbkid").toString();
            String num = m.get("num").toString();
            map.put(cbkid, BigDecimal.valueOf(Long.valueOf(num)));
        }
        return map;
    }

    @Override
    public ZcbcssltjDto zcbcszsltj(QftjSeachFilter filter) {
        return baseMapper.zcbcszsltj(filter);
    }


    @Override
    public TreeMap<String, List<CblrSflxSelect>> getSlfxtj(CblrSflxFilter filter) {


        String strcwrq = sysGdcsbService.selectCwrq();
        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                .appendPattern("yyyyMM")
                .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
                .toFormatter();
        // 解析财务日期字符串到LocalDate
        LocalDate date = LocalDate.parse(filter.getCwrq(), formatter);//当月
        LocalDate dateEnd = LocalDate.parse(filter.getCwrqend(), formatter);//截至月

        List<BmYslx> lstYslx = yslxService.list();
        lstYslx.sort((o1, o2) -> o1.getCode().compareTo(o2.getCode()));

        TreeMap<String, List<CblrSflxSelect>> mapList = new TreeMap<>();
        LocalDate currect = date;
        while (!currect.isAfter(dateEnd)) {
            List<CblrSflxSelect> lstlx = new ArrayList<>();

            String currectStr = currect.format(formatter);
            LocalDate symonth = currect.minusMonths(1); //减上一个月
            LocalDate snyear = currect.minusYears(1); //获取上年


            lstYslx.forEach(p -> {
                filter.setYslx(p.getCode());
                CblrSflxMxSelect cblrSflxMxSelect = null;

                CblrSflxFilter nowFilter = new CblrSflxFilter();
                nowFilter.setCwrq(currectStr);
                nowFilter.setYslx(p.getCode());
                //当月
                if (strcwrq.equals(currectStr)) {
                    cblrSflxMxSelect = this.baseMapper.getCblrSl(nowFilter);
                } else {
                    cblrSflxMxSelect = this.baseMapper.getCblrSlLs(nowFilter);
                }

                CblrSflxFilter monthFilter = new CblrSflxFilter();
                monthFilter.setCwrq(symonth.format(DateTimeFormatter.ofPattern("yyyyMM")));
                monthFilter.setYslx(p.getCode());
                CblrSflxMxSelect cblrSflxMonthMxSelect = this.baseMapper.getCblrSlLs(monthFilter);


                //年度
                CblrSflxFilter lastYearFilter = new CblrSflxFilter();
                lastYearFilter.setCwrq(snyear.format(DateTimeFormatter.ofPattern("yyyyMM")));
                lastYearFilter.setYslx(p.getCode());
                CblrSflxMxSelect cblrSflxLastYearMxSelect = this.baseMapper.getCblrSlLs(lastYearFilter);


                CblrSflxSelect cblrSflxSelect = new CblrSflxSelect();
                cblrSflxSelect.setYslxcode(p.getCode());
                cblrSflxSelect.setYslx(p.getName());

                if (StringUtil.isNull(cblrSflxMxSelect)) {
                    cblrSflxSelect.setDqsl(0);

                } else {
                    cblrSflxSelect.setDqsl(cblrSflxMxSelect.getSl());
                }

                if (StringUtil.isNull(cblrSflxMonthMxSelect)) {
                    cblrSflxSelect.setSysl(0);
                } else {
                    cblrSflxSelect.setSysl(cblrSflxMonthMxSelect.getSl());
                }
                //环比比例
                cblrSflxSelect.setHbbl(String.format("%.2f", jsbl(cblrSflxSelect.getDqsl(), cblrSflxSelect.getSysl())) + "%");

                if (StringUtil.isNull(cblrSflxLastYearMxSelect)) {
                    cblrSflxSelect.setSndsl(0);

                } else {
                    cblrSflxSelect.setSndsl(cblrSflxLastYearMxSelect.getSl());
                }
                //同比比例计算
                cblrSflxSelect.setTbbl(String.format("%.2f", jsbl(cblrSflxSelect.getDqsl(), cblrSflxSelect.getSndsl())) + "%");
                lstlx.add(cblrSflxSelect);
            });

            mapList.put(currectStr, lstlx);
            currect = currect.plusMonths(1);
        }
        return mapList;
    }

    @Override
    public List<CblrSflxSelect> getSlfxtj1(CblrSflxFilter filter) {

        String strcwrq = sysGdcsbService.selectCwrq();
        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                .appendPattern("yyyyMM")
                .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
                .toFormatter();
        // 解析财务日期字符串到LocalDate
        LocalDate date = LocalDate.parse(filter.getCwrq(), formatter);//当月
        LocalDate dateEnd = LocalDate.parse(filter.getCwrqend(), formatter);//截至月

        long monthsBetween = ChronoUnit.MONTHS.between(date, dateEnd); //相差月份数

        Integer monthsBetweenInt = (int) monthsBetween;

        List<CblrSflxSelect> lstlx = new ArrayList<>();

        List<BmYslx> lstYslx = yslxService.list();
        lstYslx.sort((o1, o2) -> o1.getCode().compareTo(o2.getCode()));

        //当期
        CblrSflxFilter nowFilter = new CblrSflxFilter();
        nowFilter.setCwrq(filter.getCwrq());
        nowFilter.setCwrqend(filter.getCwrqend());
        nowFilter.setSspq(filter.getSspq());
        List<CblrSflxMxSelect> cblrSflxMxSelect = this.baseMapper.retportSlfx(nowFilter);


        //上月度
        CblrSflxFilter lastmonthFilter = new CblrSflxFilter();
        lastmonthFilter.setCwrq(String.valueOf(date.minusMonths(monthsBetweenInt + 1).format(DateTimeFormatter.ofPattern("yyyyMM"))));
        lastmonthFilter.setCwrqend(String.valueOf(date.minusMonths(1).format(DateTimeFormatter.ofPattern("yyyyMM"))));
        lastmonthFilter.setSspq(filter.getSspq());
        List<CblrSflxMxSelect> lastMonthMxSelect = this.baseMapper.retportSlfx(lastmonthFilter);

        //上年度
        CblrSflxFilter lastYearFilter = new CblrSflxFilter();
        lastYearFilter.setCwrq(date.minusYears(1).format(DateTimeFormatter.ofPattern("yyyyMM")));
        lastYearFilter.setCwrqend(dateEnd.minusYears(1).format(DateTimeFormatter.ofPattern("yyyyMM")));
        lastYearFilter.setSspq(filter.getSspq());
        List<CblrSflxMxSelect> cblrSflxLastYearMxSelect = this.baseMapper.retportSlfx(lastYearFilter);

        lstYslx.forEach(p -> {

            CblrSflxSelect cblrSflxSelect = new CblrSflxSelect();
            cblrSflxSelect.setYslxcode(p.getCode());
            cblrSflxSelect.setYslx(p.getName());
            CblrSflxMxSelect now = cblrSflxMxSelect.stream().filter(fi -> fi.getCode().equals(p.getCode())).findFirst().orElse(null);
            if (StringUtil.isNull(now)) {
                cblrSflxSelect.setDqsl(0);
            } else {
                cblrSflxSelect.setDqsl(now.getSl());
            }


            CblrSflxMxSelect lastmonth = lastMonthMxSelect.stream().filter(fi -> fi.getCode().equals(p.getCode())).findFirst().orElse(null);
            if (StringUtil.isNull(lastmonth)) {
                cblrSflxSelect.setSysl(0);
            } else {
                cblrSflxSelect.setSysl(lastmonth.getSl());
            }

            //环比比例
            cblrSflxSelect.setHbbl(String.format("%.2f", jsbl(cblrSflxSelect.getDqsl(), cblrSflxSelect.getSysl())) + "%");
            CblrSflxMxSelect lastyear = cblrSflxLastYearMxSelect.stream().filter(fi -> fi.getCode().equals(p.getCode())).findFirst().orElse(null);
            if (StringUtil.isNull(lastyear)) {
                cblrSflxSelect.setSndsl(0);

            } else {
                cblrSflxSelect.setSndsl(lastyear.getSl());
            }
            //同比比例计算
            cblrSflxSelect.setTbbl(String.format("%.2f", jsbl(cblrSflxSelect.getDqsl(), cblrSflxSelect.getSndsl())) + "%");

            lstlx.add(cblrSflxSelect);
        });

        return lstlx;
    }

    /*根据水量分析明细报表*/
    @Override
    public PageResult<CblrSflxSelect> getSllxfxReport(PageDto pageDto, CblrSflxFilter filter) {
        String strcwrq = sysGdcsbService.selectCwrq();

        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                .appendPattern("yyyyMM")
                .parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
                .toFormatter();
        LocalDate date = LocalDate.parse(filter.getCwrq(), formatter);//当月

        List<Order> orders = pageDto.getOrders();
        if (orders.size() > 0) {
            orders = orders.stream().map(item -> {
                if (item.getColumn().equals("yhbh")) {
                    Order order = new Order();
                    order.setColumn("a.yhbh");
                    order.setAsc(item.isAsc());
                    return order;
                }
                return item;
            }).collect(Collectors.toList());
        } else {
            orders.add(new Order("a.yhbh", true));
        }

        List<BmSj> bmsj = bmSjService.list();

        String sycwrq = date.minusMonths(1).format(DateTimeFormatter.ofPattern("yyyyMM"));
        String Sncwrq = date.minusYears(1).format(DateTimeFormatter.ofPattern("yyyyMM"));

        PageDto<CblrSflxSelect> pgList = this.baseMapper.retportSlfxMx(pageDto, filter, "0", sycwrq, Sncwrq);
        // 更新需要抄表标志
        if (CollectionUtil.isNotEmpty(pgList.getRecords())) {

            List<String> lstYhbh = pgList.getRecords().stream().map(p -> p.getYhbh()).collect(Collectors.toList());
            List<YhKhjbxx> khjbxxes = khjbxxService.getListByYhbh(lstYhbh);
            List<YhCbkxx> cbkxxes = cbkxxService.getListCbkxxByYhbh(lstYhbh);


            pgList.getRecords().forEach(p -> {
                YhKhjbxx khjbxx = khjbxxes.stream().filter(fi -> fi.getYhbh().equals(p.getYhbh())).findFirst().orElse(null);
                if (khjbxx != null) {
                    p.setYhxm(khjbxx.getYhxm());
                }

                YhCbkxx cbkxx = cbkxxes.stream().filter(fi -> fi.getYhbh().equals(p.getYhbh())).findFirst().orElse(null);
                if (cbkxx != null) {
                    BmSj sj = bmsj.stream().filter(fi -> fi.getCode().equals(cbkxx.getSjbm())).findFirst().orElse(null);
                    p.setYslx(sj.getName());
                    p.setYslxcode(sj.getCode());
                }

//
//                 CblrSflxFilter now=new CblrSflxFilter();
//                 now.setCwrq(filter.getCwrq());
//                 now.setYhbh(p.getYhbh());
//
//
//               String ly=strcwrq.equals(filter.getCwrq())?"yy_cblr":"yy_cblr_ls";
//
//               CblrSflxYhbhSelect nowCblrSflx=this.baseMapper.retportSlfxMxByYhbh(now,ly);
//
//                CblrSflxFilter sy=new CblrSflxFilter();
//                sy.setCwrq(date.minusMonths(1).format(DateTimeFormatter.ofPattern("yyyyMM")));
//                sy.setYhbh(p.getYhbh());
//                CblrSflxYhbhSelect syCblrSflx=this.baseMapper.retportSlfxMxByYhbh(sy,"yy_cblr_ls");
//
//
//                CblrSflxFilter sn=new CblrSflxFilter();
//                sn.setCwrq(date.minusYears(1).format(DateTimeFormatter.ofPattern("yyyyMM")));
//                sn.setYhbh(p.getYhbh());
//                CblrSflxYhbhSelect snCblrSflx=this.baseMapper.retportSlfxMxByYhbh(sn,"yy_cblr_ls");
//
//                if(StringUtil.isNull(nowCblrSflx)) {
//                    p.setDqsl(0);
//                }else {
//                    p.setDqsl(nowCblrSflx.getSl());
//                }
//
//                if(StringUtil.isNull(syCblrSflx)) {
//                    p.setSysl(0);
//                }else {
//                    p.setSysl(syCblrSflx.getSl());
//                }
//                p.setHbbl(String.format("%.2f", jsbl(p.getDqsl(), p.getSysl())));
//
//                if(StringUtil.isNull(snCblrSflx)) {
//                    p.setSndsl(0);
//                }else {
//                    p.setSndsl(snCblrSflx.getSl());
//                }
//                p.setTbbl(String.format("%.2f", jsbl(p.getDqsl(), p.getSndsl())));
            });


//            if(!StringUtil.isEmpty(filter.getBl())) {
//                BigDecimal bl=new BigDecimal(filter.getBl());
//
//                List<CblrSflxSelect>  newList=pgList.getRecords().stream().filter(fi ->  new BigDecimal(fi.getHbbl()).compareTo(bl)>0 ).collect(Collectors.toList());
//                pgList.setRecords(newList);
//                pgList.setTotal(newList.size());
//            }

        }


        return pgList.toVo();
    }

    private double jsbl(Integer sl, Integer sl1) {
        return (sl - sl1) / (sl1 == 0 ? 1 : sl1) * 100;
    }


}
