package com.sy.coinage.workshop.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.sy.coinage.app.req.BindReq;
import com.sy.coinage.app.req.HalfBindReq;
import com.sy.coinage.config.PrinterConfig;
import com.sy.coinage.core.constants.BusinessEnum;
import com.sy.coinage.core.exception.RetException;
import com.sy.coinage.core.util.CommonUtil;
import com.sy.coinage.core.util.DateUtils;
import com.sy.coinage.core.vo.CacheUserVO;
import com.sy.coinage.core.vo.OptVO;
import com.sy.coinage.sys.model.Dict;
import com.sy.coinage.sys.service.IDictService;
import com.sy.coinage.sys.service.IUserService;
import com.sy.coinage.util.printer.RfidInfoDTO;
import com.sy.coinage.util.printer.ZplImgConvertPrinter;
import com.sy.coinage.workshop.WareUtil;
import com.sy.coinage.workshop.req.BaseInfoReq;
import com.sy.coinage.workshop.service.*;
import com.zebra.sdk.comm.ConnectionException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.sy.coinage.workshop.dao.BaseInfoDao;
import com.sy.coinage.workshop.model.*;
import org.springframework.transaction.annotation.Transactional;

import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * -rfid基础信息登记表ServiceImpl
 */
@Slf4j
@Service
public class BaseInfoServiceImpl extends ServiceImpl<BaseInfoDao, BaseInfo> implements IBaseInfoService {

    @Autowired
    private IBaseInfoSubService baseInfoSubService;

    @Autowired
    private IUserService userService;

    @Autowired
    private ILogisticsService logisticsService;

    @Autowired
    private IProductService productService;

    @Autowired
    private IDictService dictService;

    @Autowired
    private IStockService stockService;

    @Autowired
    private IWorkshopAccountService workshopAccountService;

    @Autowired
    private PrinterConfig printerConfig;

    @Override
    public BaseInfo getByRfid(String rfid) {
        LambdaQueryWrapper<BaseInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BaseInfo::getRfid, rfid);
        BaseInfo resp = this.getOne(queryWrapper);
        if (resp == null) {
            throw new RetException("BaseInfo数据不存在，rfid=" + rfid);
        }
        BaseInfoSub sub = this.getSubInfo(resp.getId());
        if (sub != null) {
            resp.setCrownPrefixSub(sub.getCrownPrefix());
            resp.setCrownFromSub(sub.getCrownFrom());
            resp.setCrownToSub(sub.getCrownTo());
        }
        return resp;
    }

    @Override
    public BaseInfo getByRfid(String rfid, Integer status) {
        LambdaQueryWrapper<BaseInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BaseInfo::getRfid, rfid);
        // 生命周期状态:1初始登记 2:车间入库 3:车间出库 4:总库入库  5:主库抽检出库 6.车间抽检入库确认
        // 7.车间抽检出库8 主库抽检返回确认 9返捡总库出库 10:返捡车间确认 11拆包 12：已发货 13:返回机台
        // 查询总库中的数据 包括 8 主库抽检返回确认 11拆包的
        if (status.intValue() == 1) {
            queryWrapper.and(wq -> { // 入库的可以是初始的 返检的 13:返回机台
                wq.eq(BaseInfo::getStatus, status).or().eq(BaseInfo::getStatus, 13);
                // wq.eq(BaseInfo::getStatus, status).or().eq(BaseInfo::getStatus, 6).or().eq(BaseInfo::getStatus, 10);
            });

        } else if (status.intValue() == 2) {
            queryWrapper.and(wq -> { // 入库的可以是初始的 返检的 13:返回机台
                wq.eq(BaseInfo::getStatus, status).or().eq(BaseInfo::getStatus, 6).or().eq(BaseInfo::getStatus, 10);
                // wq.eq(BaseInfo::getStatus, status).or().eq(BaseInfo::getStatus, 6).or().eq(BaseInfo::getStatus, 10);
            });
        } else if (status.intValue() == 4) {
            queryWrapper.and(wq -> {
                wq.eq(BaseInfo::getStatus, status).or().eq(BaseInfo::getStatus, 8).or().eq(BaseInfo::getStatus, 11);
            });
        } else {
            queryWrapper.eq(BaseInfo::getStatus, status);
        }
        BaseInfo resp = this.getOne(queryWrapper);
        if (resp == null) {
            throw new RetException("BaseInfo数据不存在，rfid=" + rfid + ",生命周期=" + status);
        }
        BaseInfoSub sub = this.getSubInfo(resp.getId());
        if (sub != null) {
            resp.setCrownPrefixSub(sub.getCrownPrefix());
            resp.setCrownFromSub(sub.getCrownFrom());
            resp.setCrownToSub(sub.getCrownTo());
        }
        return resp;
    }

    private BaseInfoSub getSubInfo(Integer id) {
        LambdaQueryWrapper<BaseInfoSub> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BaseInfoSub::getBaseInfoId, id);
        long count = baseInfoSubService.count(queryWrapper);
        if (count > 0) {
            return this.baseInfoSubService.getOne(queryWrapper);
        }
        return null;
    }

    @Override
    public BaseInfo getBySecuritiesId(Integer securitiesId, Integer deptId, Integer status) {
        QueryWrapper<BaseInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.select(
                "*,max(gross_weight - tare_weight) as max_weight, min(gross_weight- tare_weight) as min_weight");
        queryWrapper.eq("status", status).eq("securities_id", securitiesId);
        queryWrapper.eq(deptId != null, "dept_id", deptId);
        BaseInfo resp = this.getOne(queryWrapper);
        if (resp == null) {
            throw new RetException(
                "BaseInfo数据不存在，securitiesId=" + securitiesId + ",生命周期=" + status);
        }
        return resp;
    }

    @Override
    public BaseInfo getBySerialNumber(String serialNumber, Integer status) {
        BaseInfo resp = null;
        LambdaQueryWrapper<BaseInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BaseInfo::getSerialNumber, serialNumber);
        if (status.intValue() == 1) {
            queryWrapper.and(wq -> { // 入库的可以是初始的 返检的 13:返回机台
                wq.eq(BaseInfo::getStatus, status).or().eq(BaseInfo::getStatus, 13);
                // wq.eq(BaseInfo::getStatus, status).or().eq(BaseInfo::getStatus, 6).or().eq(BaseInfo::getStatus, 10);
            });
        } else if (status.intValue() == 4) {
            queryWrapper.and(qw -> {
                qw.eq(BaseInfo::getStatus, status).or().eq(BaseInfo::getStatus, 8).or().eq(BaseInfo::getStatus, 11);
            });
        } else if (status.intValue() == 2) {
            queryWrapper.and(wq -> { // 入库的可以是初始的 返检的 13:返回机台
                wq.eq(BaseInfo::getStatus, status).or().eq(BaseInfo::getStatus, 6).or().eq(BaseInfo::getStatus, 10);
                // wq.eq(BaseInfo::getStatus, status).or().eq(BaseInfo::getStatus, 6).or().eq(BaseInfo::getStatus, 10);
            });
        } else {
            queryWrapper.eq(BaseInfo::getStatus, status);
        }
        queryWrapper.orderByAsc(BaseInfo::getId);
        Page<BaseInfo> page = new Page<>(1, 1);
        IPage<BaseInfo> list = this.page(page, queryWrapper);
        if (list.getRecords() != null && list.getRecords().size() > 0) {
            resp = list.getRecords().get(0);
            BaseInfoSub sub = this.getSubInfo(resp.getId());
            if (sub != null) {
                resp.setCrownPrefixSub(sub.getCrownPrefix());
                resp.setCrownFromSub(sub.getCrownFrom());
                resp.setCrownToSub(sub.getCrownTo());
            }
            return resp;
        }
        throw new RetException("BaseInfo数据不存在，serialNumber=" + serialNumber);
    }

    @Override
    public BaseInfo getBySerialNumberDesc(String serialNumber, Integer status) {
        BaseInfo resp = null;
        LambdaQueryWrapper<BaseInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BaseInfo::getSerialNumber, serialNumber);
        if (status.intValue() == 4) {
            queryWrapper.and(qw -> {
                qw.eq(BaseInfo::getStatus, status).or().eq(BaseInfo::getStatus, 8).or().eq(BaseInfo::getStatus, 11);
            });
        } else if (status.intValue() == 2) {
            queryWrapper.and(wq -> { // 入库的可以是初始的 返检的 13:返回机台
                wq.eq(BaseInfo::getStatus, status).or().eq(BaseInfo::getStatus, 6).or().eq(BaseInfo::getStatus, 10);
                // wq.eq(BaseInfo::getStatus, status).or().eq(BaseInfo::getStatus, 6).or().eq(BaseInfo::getStatus, 10);
            });
        } else {
            queryWrapper.eq(BaseInfo::getStatus, status);
        }
        queryWrapper.orderByDesc(BaseInfo::getId);
        Page<BaseInfo> page = new Page<>(1, 1);
        IPage<BaseInfo> list = this.page(page, queryWrapper);
        if (list.getRecords() != null && list.getRecords().size() > 0) {
            resp = list.getRecords().get(0);
            BaseInfoSub sub = this.getSubInfo(resp.getId());
            if (sub != null) {
                resp.setCrownPrefixSub(sub.getCrownPrefix());
                resp.setCrownFromSub(sub.getCrownFrom());
                resp.setCrownToSub(sub.getCrownTo());
            }
            return resp;
        }
        throw new RetException("BaseInfo数据不存在，serialNumber=" + serialNumber);
    }

    @Override
    @Transactional
    public void halfBind(HalfBindReq req, CacheUserVO user) {
        BaseInfo old = this.getBySerialNumber(req.getSerialNumber(), 4);
        Integer unpackageStatus = old.getUnpackageStatus();
        //拆包状态 1:未拆包 2:已拆包
        old.setUnpackageStatus(2);
        old.setUnpackageTime(new Date());
        old.setQty(old.getQty() - req.getQty());
        this.updateById(old);
        BaseInfo model = new BaseInfo();
        model.setWeightTime(old.getWeightTime());
        model.setWeightDate(old.getWeightDate());
        model.setWeightor(old.getWeightor());
        model.setUnpackageStatus(2);
        model.setUnpackageTime(old.getUnpackageTime());
        model.setResDept(old.getResDept());
        model.setResDeptId(old.getResDeptId());
        model.setDept(old.getDept());
        model.setDeptId(old.getDeptId());
        model.setLocAreaId(old.getLocAreaId());
        model.setLocWareId(old.getLocWareId());
        model.setSecurities(old.getSecurities());
        model.setSecuritiesId(old.getSecuritiesId());
        // 绑定rfid数据的来源类型： 1:封包线整拍数据 2.封包线非整拍数据 3:拆包后新构成的rfid
        // 4:原有物料整拍绑定 5.原有物料整拍绑定（原始非整拍）
        model.setOriginType(3);
        model.setCheckId(req.getCheckId());
        model.setChecker(this.userService.getById(req.getCheckId()).getRealName());
        // 拆拍登记模式1:条码模式2:手工模式
        // 当仅为拆包登记绑定新的rfid时（origin_type=2），将拆出的数据变为字符串保存
        model.setCrownBetween(JSON.toJSONString(req.getCrownStr()));
        model.setCreateId(user.getId());
        model.setCreateBy(user.getRealName());
        model.setQty(req.getQty());
        model.setRfid(req.getRfid());
        model.setSerialNumber(req.getSerialNumber());
        // 生命周期状态:1初始登记 2:车间入库 3:车间出库 4:总库入库 5:主库抽检出库 6.车间抽检入库确认
        // 7.车间抽检出库8 主库抽检返回确认 9返检总库出库 10:返检车间确认 11拆包12：已发货
        model.setStatus(11);
        this.save(model);
        // FIXME 记录物流信息日志表
        this.logisticsService.addHalfBind(model.getRfid(), model.getSerialNumber(), model.getLocWareId(), null, model.getStatus(), model.getCheckId(), model.getChecker(),
                model.getCreateId(), model.getCreateBy(), model.getCrownBetween(), null, old.getRfid());
        // 未拆过的拍子进行计算
        if ((unpackageStatus != null && unpackageStatus.intValue() == 2) || old.getOriginType() == 2) {
            return;
        }
        // 库存 整拍数量减少1
        this.stockService.stockSub(model.getSecuritiesId(), model.getSecurities(), model.getLocAreaId(), model.getLocWareId(), null, 1, 0, 0, 0);
        // 库存 箱数增加
        this.stockService.stockAdd(model.getSecuritiesId(), model.getSecurities(), model.getLocAreaId(), model.getLocWareId(), null, 0, old.getQty() + model.getQty(), 0, 0);
    }

    @Override
    @Transactional
    public void bind(BindReq req, CacheUserVO user) {
        BaseInfo model = this.getById(req.getId());
        // 绑定rfid数据的来源类型： 1:封包线整拍数据 2.封包线非整拍数据 3:拆包后新构成的rfid
        // 4:原有物料整拍绑定 5.原有物料整拍绑定（原始非整拍）
        model.setOriginType(4);
        model.setCheckId(req.getCheckId());
        model.setChecker(this.userService.getById(req.getCheckId()).getRealName());
        model.setRfid(req.getRfid());
        model.setSerialNumber(req.getSerialNumber());
        // 生命周期状态:1初始登记 2:车间入库 3:车间出库 4:总库入库 5:主库抽检出库 6.车间抽检入库确认
        // 7.车间抽检出库8 主库抽检返回确认 9返检总库出库 10:返检车间确认 11拆包12：已发货
        model.setStatus(4);
        // FIXME 库位信息
        model.setLocWareId(req.getWareId());
        model.setLocAreaId(req.getAreaId());
        this.updateById(model);
        // FIXME 记录物流信息日志表
        this.logisticsService.add(model.getRfid(), model.getSerialNumber(), model.getLocWareId(), null, model.getStatus(), model.getCheckId(), model.getChecker(),
                model.getCreateId(), model.getCreateBy(), null, null);
        // 库存 整拍数量增加1
        this.stockService.stockAdd(model.getSecuritiesId(), model.getSecurities(), model.getLocAreaId(), model.getLocWareId(), null, 1, 0, 0, 0);
        Product product = this.productService.getById(model.getSecuritiesId());
        List<Stock> stockList = this.stockService.getStockList(req.getWareId(), model.getSecuritiesId());
        Integer wareTotal = WareUtil.piecesTotal(stockList, product);
        Integer total = product.getBoxAmount() * product.getAmountPerBox();
//        Integer wareTotal = (stock.getRacketNum() == null ? 0 : stock.getRacketNum()) * product.getBoxAmount() * product.getAmountPerBox() + (stock.getBoxNum() == null ? 0 : stock.getBoxNum()) * product.getAmountPerBox() + (stock.getPiecesTotal() == null ? 0 : stock.getPiecesTotal());
        // 1.实物收发卡-收
        this.workshopAccountService.shopIn(1, model.getDeptId(), model.getDept(),
                model.getCreateId(), model.getCreateBy(), model.getCheckId(), model.getChecker(), null,
                total, wareTotal, 1, 2, "整拍登记", req.getWareId(), model.getSecuritiesId(),
                model.getSecurities());
    }

    @Override
    public void add(BaseInfoReq req, CacheUserVO user) {
        Product product = productService.getById(req.getSecuritiesId());
        BaseInfo model = new BaseInfo();
        BeanUtils.copyProperties(req, model);
        model.setSecurities(product.getSecurities());
        model.setDeptId(user.getDeptId());
        model.setDept(user.getDept());
        model.setCreateId(user.getId());
        model.setCreateBy(user.getRealName());
        // 绑定rfid数据的来源类型： 1:封包线整拍数据 2.封包线非整拍数据 3:拆包后新构成的rfid
        // 4:原有物料整拍绑定 5.原有物料整拍绑定（原始非整拍）
        model.setOriginType(4);
        // 生命周期状态:1初始登记 2:车间入库 3:车间出库 4:总库入库 5:主库抽检出库 6.车间抽检入库确认
        // 7.车间抽检出库8 主库抽检返回确认 9返检总库出库 10:返检车间确认 11拆包12：已发货
        model.setStatus(1);
        model.setCrownPrefix(product.getCrownPrefix());
        this.save(model);
        // FIXME 记录物流信息日志表
        this.logisticsService.add(model.getRfid(), model.getSerialNumber(), model.getLocWareId(), null, model.getStatus(), model.getCheckId(), model.getChecker(),
                model.getCreateId(), model.getCreateBy(), null, null);
    }

    @Override
    @Transactional
    public BaseInfo updateCheckStatus(String rfid, Integer oldStatus, Integer newStatus, Date now, Integer checkStatus) {
        BaseInfo model = this.getByRfid(rfid, oldStatus);
        // 生命周期状态:1初始登记 2:车间入库 3:车间出库 4:总库入库 5:主库抽检出库 6.车间抽检入库确认
        // 7.车间抽检出库8 主库抽检返回确认 9返检总库出库 10:返检车间确认 11拆包 12：已发货 13:返回机台
        model.setStatus(newStatus);
        if (newStatus.intValue() == 5) {
            // 抽捡状态1:主库出库 2:车间入库 3:车间出库 4:主库入库
            model.setCheckStatus(checkStatus);
            // 主库出库抽捡时间
            model.setCheckTime(now);
        } else if (newStatus.intValue() == 6) {
            // 抽捡状态1:主库出库 2:车间入库 3:车间出库 4:主库入库
            model.setCheckStatus(checkStatus);
            // 抽捡:车间确认入库时间
            model.setWorkshopCheckInTime(now);
        } else if (newStatus.intValue() == 7) {
            // 抽捡状态1:主库出库 2:车间入库 3:车间出库 4:主库入库
            model.setCheckStatus(checkStatus);
            // 抽捡:车间确认入库时间
            model.setWorkshopCheckOutTime(now);
        } else if (newStatus.intValue() == 8) {
            // 抽捡状态1:主库出库 2:车间入库 3:车间出库 4:主库入库
            model.setCheckStatus(checkStatus);
            // 抽查返回时间
            model.setCheckReturnTime(now);
        }
        this.updateById(model);
        return model;
    }

    @Override
    @Transactional
    public BaseInfo updateReturnCheckStatus(String rfid, Integer oldStatus, Integer newStatus, Date now) {
        BaseInfo model = this.getByRfid(rfid, oldStatus);
        // 生命周期状态:1初始登记 2:车间入库 3:车间出库 4:总库入库 5:主库抽检出库 6.车间抽检入库确认
        // 7.车间抽检出库8 主库抽检返回确认 9返检总库出库 10:返检车间确认 11拆包 12：已发货 13:返回机台
        model.setStatus(newStatus);
        if (newStatus.intValue() == 9) {
            // "返检状态 1:未返检 2: 已返检
            model.setReturnCheckStatus(2);
            // 返检时间
            model.setReturnCheckTime(now);
            // 车间返捡确认状态1:未确认2:已确认接收
            model.setReturnCheckConfirmStatus(1);
        } else if (newStatus.intValue() == 10) {
            // 车间返检确认时间
            model.setReturnCheckConfirmTime(now);
            // 车间返捡确认状态1:未确认2:已确认接收
            model.setReturnCheckConfirmStatus(2);
        }
        this.updateById(model);
        return model;
    }

    @Override
    public BaseInfo updateWorkShopStatus(String serialNumber, String rfid, Integer oldStatus, Integer newStatus,
                                         Integer wareId, Integer areaId, Integer deptId, String dept) {
        BaseInfo model = null;
        if (StringUtils.isNotBlank(rfid)) {
            model = this.getByRfid(rfid, oldStatus);
        } else {
            model = this.getBySerialNumber(serialNumber, oldStatus);
        }
        // 生命周期状态:1初始登记 2:车间入库 3:车间出库 4:总库入库 5:主库抽检出库 6.车间抽检入库确认
        // 7.车间抽检出库8 主库抽检返回确认 9返检总库出库 10:返检车间确认 11拆包 12：已发货 13:返回机台
        model.setStatus(newStatus);
        if (wareId != null) {
            model.setLocWareId(wareId);
            Dict d = this.dictService.getByVal("locationOpt", wareId, null);
            model.setLocWare(d.getName());
        }
        if (areaId != null) {
            model.setLocAreaId(areaId);
        }
        if (dept != null) {
            model.setDeptId(deptId);
            model.setDept(dept);
        }
        this.updateById(model);
        return model;
    }

    @Override
    public IPage<BaseInfo> queryPageList(Page<BaseInfo> page, LambdaQueryWrapper<BaseInfo> queryWrapper) {
        IPage<BaseInfo> resp = this.baseMapper.queryPageList(page, queryWrapper);
        if (resp.getRecords() != null && resp.getRecords().size() > 0) {
            List<OptVO> list = this.dictService.opt("locationOpt", null);
            for (BaseInfo info : resp.getRecords()) {
                if (info.getLocWareId() != null && info.getLocWareId() > 0) {
                    Optional<OptVO> dict = list.stream().filter(item -> item.getVal().equals(String.valueOf(info.getLocWareId()))).findFirst();
                    if (dict != null && dict.get() != null) {
                        info.setLocWare(dict.get().getName());
                    }
                }
            }
        }
        return resp;
    }

    @Override
    @Transactional
    public void print(Integer id, CacheUserVO user) {

        LambdaUpdateWrapper<BaseInfo> updateWrapper = new LambdaUpdateWrapper<>();
        // 打印状态: 1.未打印 2.页面已打印 9.自动已打印 8.人工干预（自动打印数据不全）
        updateWrapper.set(BaseInfo::getPrintTime, new Date()).set(BaseInfo::getPrintStatus, 2);
        updateWrapper.set(BaseInfo::getPrinterId, user.getId())
            .set(BaseInfo::getPrinter, user.getRealName());
        updateWrapper.eq(BaseInfo::getId, id);
        this.update(updateWrapper);
        //FIXME 增加打印
        //1.构造打印对象RfidInfoDTO, 通过id获取
        BaseInfo model = this.getById(id);
        RfidInfoDTO dto = new RfidInfoDTO();
        dto.setCrownBetween(model.getCrownBetween());
        dto.setWeightor(model.getWeightor());
        dto.setSecurities(model.getSecurities());
        dto.setRfidEpc(model.getRfid());
        dto.setSerialNumber(model.getSerialNumber());
        if (model.getWeightDate() != null) {
            dto.setWeightDate(DateUtils.toString(model.getWeightDate()));
        }
        dto.setGrossWeight(String.valueOf(model.getGrossWeight()));
        dto.setTareWeight(String.valueOf(model.getTareWeight()));
        dto.setWeightTime(model.getWeightTime());
        try {
            ZplImgConvertPrinter.printZpl(printerConfig.getIpAddress(), printerConfig.getPort(), dto);

            log.info("print rfid dto is ended :{}", JSONObject.toJSONString(dto));
        } catch (ConnectionException e) {
            log.error("print zebra rfid tag is error!!pls check ip! error :{}", e.getMessage());
        }
    }

    @Override
    public void printBlankTag() {
        try {
            ZplImgConvertPrinter.printBlankZpl(printerConfig.getIpAddress(), printerConfig.getPort());

            log.info("print blank tag   is ended !");
        } catch (ConnectionException e) {
            log.error("print zebra rfid tag is error!!pls check ip! error :{}", e.getMessage());
        }
    }

    @Override
    public void autoPrint(BaseInfo model) {
        boolean isCanPrint = isBaseInfoCanPrint(model);
        if (!isCanPrint) {//数据冠字号前缀不全，需要人工干预，补全数据，在进行页面补打
            log.info("autoPrint :the crownPrefix is null,model : {}");
            //更新状态值为8,需要人工补全数据后，在页面中进行打印
            model.setPrintStatus(8);
            this.baseMapper.updateById(model);
            log.info("autoPrint: rfid, serialNumber :{}, status : 8 ", model.getSerialNumber());
            return;
        }

        RfidInfoDTO dto = new RfidInfoDTO();
        dto.setCrownBetween(model.getCrownBetween());
        dto.setWeightor(model.getWeightor());
        dto.setSecurities(model.getSecurities());
        dto.setRfidEpc(model.getRfid());
        dto.setSerialNumber(model.getSerialNumber());
        if (model.getWeightDate() != null) {
            dto.setWeightDate(DateUtils.toString(model.getWeightDate()));
        }
        dto.setGrossWeight(String.valueOf(model.getGrossWeight()));
        dto.setTareWeight(String.valueOf(model.getTareWeight()));
        dto.setWeightTime(model.getWeightTime());
        try {
            boolean flag = ZplImgConvertPrinter.printZpl(printerConfig.getIpAddress(), printerConfig.getPort(), dto);

            log.info("print rfid dto is ended :{},flag:{}", JSONObject.toJSONString(dto),flag);

            //将已自动打印的状态变为9
            if(flag){
                model.setPrintStatus(9);
                this.baseMapper.updateById(model);
                log.info("after auto print rfid, serialNumber :{}, status : 9 ");
            }

        } catch (ConnectionException e) {
            log.error("print zebra rfid tag is error!!pls check ip! error :{}", e.getMessage());
        }


    }

    @Override
    public BaseInfo getByCrown(Integer securitiesId, String crown) {
        QueryWrapper<BaseInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("securities_id", securitiesId);
        queryWrapper.and(qw -> {
            qw.le("rfid_base_info.crown_from", crown).ge("rfid_base_info.crown_to", crown)
                    .or().le("rfid_base_info_sub.crown_from", crown)
                    .ge("rfid_base_info_sub.crown_to", crown);
        });
        Page<BaseInfo> page = new Page<>(1, 1);
        IPage<BaseInfo> resp = this.baseMapper.queryOne(page, queryWrapper);
        if (resp.getRecords() != null && resp.getRecords().size() > 0) {
            return resp.getRecords().get(0);
        }
        return null;
    }

    @Override
    public BaseInfo getLast(Integer deptId) {
        LambdaQueryWrapper<BaseInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BaseInfo::getResDeptId, deptId);
        queryWrapper.orderByDesc(BaseInfo::getId);
        Page<BaseInfo> page = new Page<>(1, 1);
        IPage<BaseInfo> data = this.page(page, queryWrapper);
        return data.getRecords().get(0);
    }

    @Override
    public void updateRfidInfo(BaseInfoReq req) {

        //首先判断是不是一个号段
        String start = req.getCrownFrom();
        String end = req.getCrownTo();
        String[] startArray = start.split("-");
        String[] endArray = end.split("-");
        //起始号段 ，起始序号
        String startCode = startArray[0];
        String startSeq = startArray[1];

        String endCode = endArray[0];
        String endSeq = endArray[1];

        //
        String crownPrefix = req.getCrownPrefix();

        //startCode == endCode ,则只更新当前数据，不涉及子表
        if(startCode.equalsIgnoreCase(endCode)){

            BaseInfo model = this.getById(req.getId());
            BeanUtils.copyProperties(req, model);
            model.setCrownBetween(model.getCrownPrefix() +"-"+ model.getCrownFrom() + " 至 "
                    + model.getCrownPrefix() +"-"+ model.getCrownTo());
            // model.setUpdateBy(user.getName());
            this.updateById(model);
            //判断子表中是否存在，如果子表存在，则需要删除子表里的数据
            BaseInfoSub subInfo = this.getSubInfo(model.getId());
            if(subInfo!=null){
                baseInfoSubService.removeById(subInfo.getId());
            }


        }else {
            //当不相等，则需要更新主表，及子表
            BaseInfo model = this.getById(req.getId());
            BeanUtils.copyProperties(req, model);
            //注意更新crownBetween,crownFrom,crownTo字段
            String crownFromFirst = startCode.concat("-").concat(startSeq) ;
            String crownToFirst =  startCode.concat("-").concat( "5000");
            String crownFromSecond = endCode.concat( "-").concat( "0001");
            String crownToSecond =  endCode.concat("-").concat(endSeq);
            StringBuffer crownBetweenSb = new StringBuffer();
            crownBetweenSb.append(crownPrefix).append("-").append(crownFromFirst).append(" 至 ").append(crownPrefix).append("-").append(crownToFirst).append(",");
            crownBetweenSb.append(crownPrefix).append("-").append(crownFromSecond).append(" 至 ").append(crownPrefix).append("-").append(crownToSecond);
            model.setCrownBetween(crownBetweenSb.toString());
            model.setCrownFrom(crownFromFirst);
            model.setCrownTo(crownToFirst);
            this.updateById(model);
            log.info(" update rfid_base_info, baseInfo is :{}",JSONObject.toJSONString(model));
            // 判断子表,如果存在，则更新，如果不存在，则插入
            BaseInfoSub subInfo = this.getSubInfo(model.getId());
            if(subInfo!=null){
                subInfo.setCrownFrom(crownFromSecond);
                subInfo.setCrownTo(crownToSecond);
                subInfo.setCrownPrefix(crownPrefix);
                baseInfoSubService.updateById(subInfo);
            }else{
                subInfo = new BaseInfoSub();
                subInfo.setBaseInfoId(model.getId());
                subInfo.setSerialNumber(model.getSerialNumber());
                subInfo.setCrownPrefix(model.getCrownPrefix());
                subInfo.setCrownFrom(crownFromSecond);
                subInfo.setCrownTo(crownToSecond);
                baseInfoSubService.save(subInfo);

            }
          log.info("operate baseInfoSub :{}",JSONObject.toJSONString(subInfo));

        }




    }

    /**
     * 校验baseInfo：
     * 当数据crown_prefix字段为空时，就返回false
     * 当字段不为空，返回true
     *
     * @param info
     * @return
     */
    private boolean isBaseInfoCanPrint(BaseInfo info) {

        boolean isCanPrint = false;
        if (StringUtils.isNotEmpty(info.getCrownPrefix())) {
            isCanPrint = true;
        }
        return isCanPrint;
    }

}
