package digital.laboratory.platform.entrustment.service.impl;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
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.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.config.ConfigureBuilder;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import digital.laboratory.platform.common.core.constant.CommonConstants;
import digital.laboratory.platform.common.core.constant.OSSDirectoryConstants;
import digital.laboratory.platform.common.core.util.BusinessCodeUtils;
import digital.laboratory.platform.common.core.util.R;
import digital.laboratory.platform.common.feign.RemoteTemplate2htmlService;
import digital.laboratory.platform.common.mybatis.security.service.DLPUser;
import digital.laboratory.platform.common.oss.service.OssFile;
import digital.laboratory.platform.common.security.util.SecurityUtils;
import digital.laboratory.platform.entrustment.dto.PrintDTO;
import digital.laboratory.platform.entrustment.entity.*;
import digital.laboratory.platform.entrustment.enums.AnalysisOptionEnums;
import digital.laboratory.platform.entrustment.enums.EntrustmentStatusConstants;
import digital.laboratory.platform.entrustment.handler.AppStartupRunner;
import digital.laboratory.platform.entrustment.mapper.EntrustmentIdentificationMaterialMapper;
import digital.laboratory.platform.entrustment.mapper.EntrustmentMapper;
import digital.laboratory.platform.othersys.utils.ConvertUtils;
import digital.laboratory.platform.entrustment.service.*;
import digital.laboratory.platform.entrustment.vo.EntrustmentIdentificationMaterialVO;
import digital.laboratory.platform.entrustment.vo.SampleBoxVO;
import digital.laboratory.platform.sys.entity.BalanceUseRecord;
import digital.laboratory.platform.sys.entity.DrugLite;
import digital.laboratory.platform.sys.entity.SysUser;
import digital.laboratory.platform.sys.entity.entrustment.Sample;
import digital.laboratory.platform.sys.entity.entrustment.SampleBox;
import digital.laboratory.platform.sys.feign.RemoteEquipmentService;
import digital.laboratory.platform.sys.feign.RemoteSampleService;
import digital.laboratory.platform.sys.feign.RemoteUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static java.util.Comparator.comparing;

/**
 * 检材信息服务实现类
 *
 * @author Zhang Xiaolong created at  2022-03-22
 * @describe 检材信息服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class EntrustmentIdentificationMaterialServiceImpl extends ServiceImpl<EntrustmentIdentificationMaterialMapper, EntrustmentIdentificationMaterial> implements EntrustmentIdentificationMaterialService {
    private final EntrustmentIdentificationMaterialMapper entrustmentIdentificationMaterialMapper;
    @Resource
    private EntrustmentService entrustmentService;
    @Resource
    private SampleBoxService sampleBoxService;
    @Resource
    private RemoteUserService remoteUserService;

    @Resource
    private SampleService sampleService;

    @Resource
    private CaseEvidenceService caseEvidenceService;

    @Resource
    private OssFile ossFile;

    @Resource
    private TakerService takerService;

    @Resource
    private RemoteEquipmentService remoteEquipmentService;

    @Resource
    private CaseEventService caseEventService;

    @Resource
    private RemoteTemplate2htmlService remoteTemplate2htmlService;

    @Resource
    private RemoteSampleService remoteSampleService;

    @Resource
    private EntrustmentMapper entrustmentMapper;

    @Resource
    private SynchronizeDataService synchronizeDataService;

    @Resource
    private SynchronizeMaterialVoService synchronizeMaterialVoService;

    /**
     * ## 检材编码
     * ```
     * JC <物证编号后 28 位> <顺序号4位>
     * 例如:
     * JC 5201010400002020030002 0000001 0001
     * 合计 34 位
     * ```
     * 一份物证, 有可能会多次送检。每次送检的时候, 在原来的顺序号上递增。
     * 定义这个编号的时候有点纠结, 有两个方向的关联: 在案件号上扩充、在物证号上扩充。我们选择在物证号上扩充。
     * 检材编码的长度不一定刚好是 34 位！我们取“物证编号后 28 位”时, 其实是去掉物证编码前第1个字符后剩下的部分。
     * 如果物证编码不是 29 位, 那么取到的就不是 28 位, 而是物证编码长度减1位。
     *
     * @param evidenceNo
     * @return
     */
    @Override
    public String getNewIdentificationMaterialNo(String evidenceNo) {
        String prefix = CommonConstants.CODE_PREFIX_IDENTIFICATION_MATERIAL + StrUtil.removePrefixIgnoreCase(evidenceNo, CommonConstants.CODE_PREFIX_EVIDENCE);

        int newCount = 1;
        String maxIdentificationMaterialNo = prefix + "0000";   // 前缀 + 4个零
        List<EntrustmentIdentificationMaterial> imList = entrustmentIdentificationMaterialMapper.selectList(Wrappers.<EntrustmentIdentificationMaterial>query()
                .likeRight("im_no", prefix)
        );
        for (EntrustmentIdentificationMaterial eim : imList) {
            String pureIdentificationMaterialNo = eim.getImNo();
            if (StrUtil.isNotBlank(pureIdentificationMaterialNo)) {
                pureIdentificationMaterialNo = StrUtil.removeSuffixIgnoreCase(pureIdentificationMaterialNo, "A");
                pureIdentificationMaterialNo = StrUtil.removeSuffixIgnoreCase(pureIdentificationMaterialNo, "B");
                if (StrUtil.compareIgnoreCase(maxIdentificationMaterialNo, pureIdentificationMaterialNo, true) < 0) {
                    maxIdentificationMaterialNo = pureIdentificationMaterialNo;     // 找最大的检材号
                }
            }
        }

        String newIdentificationMaterialNo = BusinessCodeUtils.StringCodeInc(maxIdentificationMaterialNo);
        return newIdentificationMaterialNo;

        // // 根据前缀查询最大物证编码
        // String maxno = entrustmentIdentificationMaterialMapper.getMaxIdentificationMaterialNo(prefix);
        // if (maxno != null) {
        // 	String strCount = StrUtil.removePrefix(maxno, prefix);
        // 	try
        // 	{
        // 		int maxcount = Integer.parseUnsignedInt(strCount);
        // 		newCount = maxcount + 1;
        // 	}
        // 	catch (NumberFormatException e) {
        // 		// 如果后缀有非数字, 则无视之, 重头编码
        // 		newCount = 1;
        // 	}
        // }
        //
        // String newCode = prefix+ String.format("%04d", newCount);
        //
        // return newCode;
    }

    /**
     * 创建新的检材
     * 根据参数中的物证生成新的检材, 新创建的检材将继承该物证的部分属性
     *
     * @param ce
     * @return
     */
    @Override
    public EntrustmentIdentificationMaterial createNewIdentificationMaterial(CaseEvidence ce) {
        EntrustmentIdentificationMaterial im = new EntrustmentIdentificationMaterial();
        im.setImNo(this.getNewIdentificationMaterialNo(ce.getEvidenceNo()));
        im.setEvidenceId(ce.getId());
        im.setCaseId(ce.getCaseId());
        //im.setEntrustmentId();              // 现在还不知道委托的情况
        im.setName(ce.getName() + "的检材");
        im.setType(ce.getType());
        im.setColor(ce.getColor());
        im.setForm(ce.getForm());
        im.setQuantity(ce.getQuantity());       // ??
        im.setUnit(ce.getUnit());
        im.setAdditionalProperties(ce.getAdditionalProperties());
        im.setPersonName(ce.getPersonName());
        im.setPersonCert(ce.getPersonCert());
        im.setPersonId(ce.getPersonId());
        im.setPersonGender(ce.getPersonGender());
        im.setPersonNationality(ce.getPersonNationality());
        im.setPersonNation(ce.getPersonNation());
        im.setPersonAddress(ce.getPersonAddress());
        im.setPersonAge(ce.getPersonAge());

        return im;
    }

    @Override
    public long countByEntrustmentId(String entrustmentId) {
        return baseMapper.selectCount(Wrappers.<EntrustmentIdentificationMaterial>query()
                .eq(StrUtil.isNotBlank(entrustmentId), "entrustment_id", entrustmentId)
        );

    }

    @Override
    public List<EntrustmentIdentificationMaterialVO> getEntrustmentIdentificationMaterialVOList(QueryWrapper<EntrustmentIdentificationMaterial> qw) {
        return baseMapper.getEntrustmentIdentificationMaterialVOList(qw);
    }

    @Override
    public int setEntrustmentIdentificationMaterialStatusByEntrustment(EntrustmentIdentificationMaterial im, String EntrustmentId) {
        UpdateWrapper<EntrustmentIdentificationMaterial> updateWrapper = new UpdateWrapper<EntrustmentIdentificationMaterial>();
        updateWrapper.eq("entrustment_id", EntrustmentId);
        //updateWrapper.set("status", status);

        return baseMapper.update(im, updateWrapper);
    }

    //修改受理模块，调整盒子的功能，增加以下3个接口  08-03
    @Override
    public List<EntrustmentIdentificationMaterial> getQueryListByBoxID(String boxId, String boxType) {
        List<EntrustmentIdentificationMaterial> retList = new ArrayList<>();
        if (boxType.equals("A")) {
            retList = this.list(Wrappers.<EntrustmentIdentificationMaterial>query()
                    .eq("sample1_box_id", boxId));
        } else {
            retList = this.list(Wrappers.<EntrustmentIdentificationMaterial>query()
                    .eq("sample2_box_id", boxId));
        }
        return retList;
    }

    @Override
    public Boolean delSampleBoxInfo(String boxId, String sampleNo, String boxType) {
        EntrustmentIdentificationMaterial sourceMaterial = null;

        if (boxType.equals("A")) {
            sourceMaterial = this.getBaseMapper().selectOne(Wrappers.<EntrustmentIdentificationMaterial>query()
                    .eq("sample1_box_id", boxId)
                    .eq("sample1_no", sampleNo));
            if (sourceMaterial != null) {
                Entrustment entrustment = entrustmentService.getById(sourceMaterial.getEntrustmentId());
                if (entrustment.getStatus() >= EntrustmentStatusConstants.ENTRUSTMENT_STATUS_ACCEPTED.getStatus()) {
                    Sample sample = new Sample();
                    sample.setIdentificationMaterialId(sourceMaterial.getId());
                    sample.setBoxId(boxId);
                    sample.setSampleType(boxType);
                    remoteSampleService.updateBoxId(sample, -1);
                }
                sourceMaterial.setSample1BoxId("");
                return this.updateById(sourceMaterial);
            }
        } else {
            sourceMaterial = this.getBaseMapper().selectOne(Wrappers.<EntrustmentIdentificationMaterial>query()
                    .eq("sample2_box_id", boxId)
                    .eq("sample2_no", sampleNo));
            if (sourceMaterial != null) {
                Entrustment entrustment = entrustmentService.getById(sourceMaterial.getEntrustmentId());
                if (entrustment.getStatus() >= EntrustmentStatusConstants.ENTRUSTMENT_STATUS_ACCEPTED.getStatus()) {
                    Sample sample = new Sample();
                    sample.setIdentificationMaterialId(sourceMaterial.getId());
                    sample.setBoxId(boxId);
                    sample.setSampleType(boxType);
                    remoteSampleService.updateBoxId(sample, -1);
                }
                sourceMaterial.setSample2BoxId("");
                return this.updateById(sourceMaterial);
            }
        }


        if (sourceMaterial == null) {
            System.out.println("没有找到ID为:" + sampleNo + "的样本");
            return false;
        } else return false;
    }

    @Override
    public SampleBoxVO getBoxCountInfo(String boxId) {
        List<EntrustmentIdentificationMaterial> retList =
                this.list(Wrappers.<EntrustmentIdentificationMaterial>query()
                        .eq("sample1_box_id", boxId)
                        .or()
                        .eq("sample2_box_id", boxId));
        SampleBox sampleBox = sampleBoxService.getById(boxId);
        List<Sample> sampleList = new ArrayList<>();
        SampleBoxVO retData = new SampleBoxVO(sampleBox, sampleList);
        retData.setBoxSampleCount(retList.size());
        return retData;
    }

    @Override
    @Transactional
    public List<EntrustmentIdentificationMaterial> putSampleToBox(String boxId, List<String> sampleNoList, String boxType) {

        if (!boxType.equals("A") && !boxType.equals("B")) {
            throw new RuntimeException(String.format("传入的包装类型只能是A或者B"));
        }
        List<EntrustmentIdentificationMaterial> materials = new ArrayList<>();
        //现在支持批量加入包装
        for (String sampleNo : sampleNoList) {
            Sample sample = new Sample();
            if (boxType.equals("A")) {
                EntrustmentIdentificationMaterial material = this.getBaseMapper().selectOne(Wrappers.<EntrustmentIdentificationMaterial>query()
                        .eq("sample1_no", sampleNo));
                if (material != null) {
                    if (!StrUtil.isNotBlank(material.getAcceptNo())) {
                        throw new RuntimeException(String.format("该检材还未受理，请先受理检材后再进行添加！"));
                    }
                    material.setSample1BoxId(boxId);
                    materials.add(material);
                }
            } else {
                EntrustmentIdentificationMaterial material = this.getBaseMapper().selectOne(Wrappers.<EntrustmentIdentificationMaterial>query()
                        .eq("sample2_no", sampleNo));
                if (material != null) {
                    if (!StrUtil.isNotBlank(material.getAcceptNo())) {
                        throw new RuntimeException(String.format("该检材还未受理，请先受理检材后再进行添加！"));
                    }
                    material.setSample2BoxId(boxId);
                    materials.add(material);
                }
            }
        }

        Entrustment entrustment = entrustmentService.getById(materials.get(0).getEntrustmentId());
        //判断是否受理了，如果受理完成之后再加入包装袋，则需在操作检材流转系统，更新boxID
        if (materials != null && materials.size() > 0) {

            if (entrustment.getStatus() >= EntrustmentStatusConstants.ENTRUSTMENT_STATUS_ACCEPTED.getStatus()) {
                for (EntrustmentIdentificationMaterial material : materials) {
                    Sample sample = new Sample();
                    sample.setIdentificationMaterialId(material.getId());
                    sample.setBoxId(boxId);
                    sample.setSampleType(boxType);
                    remoteSampleService.updateBoxId(sample, 1);
                }
            }
        }

        List<EntrustmentIdentificationMaterial> list = this.list(new LambdaQueryWrapper<EntrustmentIdentificationMaterial>()
                .eq(EntrustmentIdentificationMaterial::getEntrustmentId, entrustment.getId())
                .eq(boxType.equals("A"), EntrustmentIdentificationMaterial::getSample1BoxId, boxId)
                .eq(boxType.equals("B"), EntrustmentIdentificationMaterial::getSample2BoxId, boxId));

        if (list != null && list.size() > 0) {
            materials.addAll(list);
        }
        return this.updateBatchById(materials) ? materials : null;
    }

    @Override
    public String getUserNameByEntrustUserID(String userId) {
        R<SysUser> retData = remoteUserService.innerGetById(userId);
        if (retData.getData() != null) {
            return retData.getData().getName();
        } else {
            return "用户不存在";
        }
    }

    //获取案前检验的受理编号
    @Override
    public String getNewMaterialAcceptNoForBeforeCase(String entrustBeforeAcceptNo) {
        String maxMaterialAcceptNo = "";//案前检验最大的检材受理编号
        String first_part = entrustBeforeAcceptNo;//将案前委托的委托受理编号作为检材的第一部分
        if (!StringUtils.isNotBlank(entrustBeforeAcceptNo)) {
            //委托没受理号，可能是新的
            String newEntrustAcceptNo = entrustmentService.getNewEntrustAcceptNoForBeforeCase();
            first_part = newEntrustAcceptNo;
            //maxMaterialAcceptNo=baseMapper.getMaxMaterialAcceptNo(newEntrustAcceptNo);//根据委托的受理编号查出最大的检材编号
        }
        List<EntrustmentIdentificationMaterial> mList = this.list(Wrappers.<EntrustmentIdentificationMaterial>query()
                .like("accept_no", first_part));
        //有受理编号的情况下，看看是否用这个受理编号受理过，如果没有就是1号
        if (mList.size() > 0) {
            List<EntrustmentIdentificationMaterial> maxList = mList.stream().sorted(comparing(EntrustmentIdentificationMaterial::getAcceptNo, (x, y) -> {
                int x1 = Integer.parseInt(x.substring(x.lastIndexOf("-") + 1));
                int y1 = Integer.parseInt(y.substring(y.lastIndexOf("-") + 1));
                return x1 < y1 ? 1 : -1;
            })).collect(Collectors.toList());
            maxMaterialAcceptNo = maxList.get(0).getAcceptNo();
        }
        int materialSeqNo = 1;
        if (StringUtils.isNotBlank(maxMaterialAcceptNo)) {
            //2023-0026-1
            String materialSeqNoStr = maxMaterialAcceptNo.substring(maxMaterialAcceptNo.lastIndexOf("-") + 1);
            materialSeqNo = Integer.parseInt(materialSeqNoStr) + 1;
            return first_part + "-" + materialSeqNo;
        } else {

            return first_part + "-" + materialSeqNo;
        }
    }

    /**
     * 用0填充编号
     *
     * @param sourceNumber
     * @return
     */
    private String fillByZero(int sourceNumber) {
        if (sourceNumber < 10) {
            return "000" + sourceNumber;
        } else if (sourceNumber < 100) {
            return "00" + sourceNumber;
        } else if (sourceNumber < 1000) {
            return "0" + sourceNumber;
        } else {
            return sourceNumber + "";
        }
    }

    /**
     * 检查编号是否被检材占用,如果被占用，返回可用的新编号，如果没被占用，返回传入编号
     *
     * @param _acceptNo
     * @return
     */
    public String checkAcceptNoIsUse(String _acceptNo) {
        List<EntrustmentIdentificationMaterial> materialList = this.list(Wrappers.<EntrustmentIdentificationMaterial>lambdaQuery()
                .like(EntrustmentIdentificationMaterial::getAcceptNo, _acceptNo));
        if (materialList.size() > 0) {
            //如果被占用，则编号自动+1
            String[] acceptArr = _acceptNo.split("-");
            int acceptSeq = Integer.parseInt(acceptArr[1]) + 1;
//            String acceptSeqStr = fillByZero(acceptSeq);
            String newAcceptNo = acceptArr[0] + "-" + acceptSeq;
            return checkAcceptNoIsUse(newAcceptNo);
        }
        return _acceptNo;
    }

    //同步大数据平台已受理编号的时候，需要设置检材的受理编号，因此这里专门写一个方法来处理大数据平台的检材受理编号
    @Override
    public String getThirdSysMaterialAcceptNo(String entrustAcceptNo) {
        //查看这个受理编号是否被使用
        List<Entrustment> entrustmentList = entrustmentService.list(Wrappers.<Entrustment>lambdaQuery().eq(Entrustment::getAcceptNo, entrustAcceptNo));
        if (entrustmentList.size() > 0) {
            log.info("受理编号：{} 已经被使用，程序终止", entrustAcceptNo);
            throw new RuntimeException("受理编号：" + entrustAcceptNo + "已经被使用，程序终止");
        }
        List<EntrustmentIdentificationMaterial> mList = this.list(Wrappers.<EntrustmentIdentificationMaterial>query()
                .like("accept_no", entrustAcceptNo));
        int maxMaterialAcceptNoSeq = 1;
        if (mList.size() > 0) {
            //取出最大编号
            List<EntrustmentIdentificationMaterial> maxList = mList.stream().sorted(comparing(EntrustmentIdentificationMaterial::getAcceptNo, (x, y) -> {
                int x1 = Integer.parseInt(x.substring(x.lastIndexOf("-") + 1));
                int y1 = Integer.parseInt(y.substring(y.lastIndexOf("-") + 1));
                return x1 < y1 ? 1 : -1;
            })).collect(Collectors.toList());
            String maxMaterialAcceptNo = maxList.get(0).getAcceptNo();
            String materialSeqNoStr = maxMaterialAcceptNo.substring(maxMaterialAcceptNo.lastIndexOf("-") + 1);
            maxMaterialAcceptNoSeq = Integer.parseInt(materialSeqNoStr) + 1;
        }
        String newMaterialAcceptNo = entrustAcceptNo + "-" + maxMaterialAcceptNoSeq;
        log.info("同步数据时，受理编号{}新生成的检材编号{}", entrustAcceptNo, newMaterialAcceptNo);
        return newMaterialAcceptNo;
    }

    //获取正常委托的受理编号
    @Override
    public String getNewMaterialAcceptNo(String entrustAcceptNo) {
        String maxMaterialAcceptNo = "";
        String first_part = entrustAcceptNo;
        //如果传入受理编号为空，只有同步数据使用这个方法时传入的受理编号才可能不为空
        if (!StringUtils.isNotBlank(entrustAcceptNo)) {
            //委托没受理号，可能是新的
            String newEntrustAcceptNo = entrustmentService.getNewAcceptNo();
            //检查这个编号是不是有 只受理了部分检材，而占据着这个编号，如果我们就需要往上加，直到没有使用的情况？？？？？
            String enableUseAcceptNo = checkAcceptNoIsUse(newEntrustAcceptNo);
            first_part = enableUseAcceptNo;
            //maxMaterialAcceptNo=baseMapper.getMaxMaterialAcceptNo(newEntrustAcceptNo);//根据委托的受理编号查出最大的检材编号
        }

        //这里需要判断委托下是否有检材已经被受理，如果有则
        List<EntrustmentIdentificationMaterial> mList = this.list(Wrappers.<EntrustmentIdentificationMaterial>query()
                .like("accept_no", first_part));
        //有受理编号的情况下，看看是否用这个受理编号受理过，如果没有就是1号
        if (mList.size() > 0) {
            List<EntrustmentIdentificationMaterial> maxList = mList.stream().sorted(comparing(EntrustmentIdentificationMaterial::getAcceptNo, (x, y) -> {
                int x1 = Integer.parseInt(x.substring(x.lastIndexOf("-") + 1));
                int y1 = Integer.parseInt(y.substring(y.lastIndexOf("-") + 1));
                return x1 < y1 ? 1 : -1;
            })).collect(Collectors.toList());
            maxMaterialAcceptNo = maxList.get(0).getAcceptNo();
        }
        int materialSeqNo = 1;
        if (StringUtils.isNotBlank(maxMaterialAcceptNo)) {
            //2023-0026-1
            String materialSeqNoStr = maxMaterialAcceptNo.substring(maxMaterialAcceptNo.lastIndexOf("-") + 1);
            materialSeqNo = Integer.parseInt(materialSeqNoStr) + 1;
            return first_part + "-" + materialSeqNo;
        } else {

            return first_part + "-" + materialSeqNo;
        }
        //
    }

    //2024-9-11 贵阳市局需求修改：已经将审核审批合为一步，因此这里只做审核操作，并且将检材一起审批完成
    @Override
    public EntrustmentIdentificationMaterial bizCheck_Apply(EntrustmentIdentificationMaterial identificationMaterial, Integer opCode, DLPUser dlpUser) {
        if (opCode == null) {
            throw new RuntimeException(String.format("审核结果必须提供 opCode"));
        }

        // 检查委托原来的状态
        EntrustmentIdentificationMaterial im = this.getById(identificationMaterial.getId());
        if (im == null) {
            throw new RuntimeException(String.format("没有找到 id 为 %s 的检材", identificationMaterial.getId()));
        }

        Entrustment entrustment = entrustmentService.getById(im.getEntrustmentId());
        if (entrustment == null) {
            throw new RuntimeException(String.format("没有找到 id 为 %s 的委托", im.getEntrustmentId()));
        }

        if (entrustment.getStatus() != EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_CHECK.getStatus()) {
            throw new RuntimeException("委托不在待审核状态");
        }

        if (!dlpUser.getId().equals(entrustment.getCheckClaimUser())) {
            String uName = this.getUserNameByEntrustUserID(entrustment.getCheckClaimUser());
            throw new RuntimeException(String.format("委托的审核任务是由其他人认领的。认领用户是: %s", uName));
        }

        //-------------------
        // 更新数据库表数据
        //-------------------
        im.setCheckPassed(opCode);
        im.setCheckTime(LocalDateTime.now());
        im.setApprovePassed(opCode);
        im.setApproveTime(LocalDateTime.now());

        UpdateWrapper<EntrustmentIdentificationMaterial> updateWrapper = new UpdateWrapper<EntrustmentIdentificationMaterial>();
        updateWrapper.eq("id", im.getId());        // 查询条件是 id 相等

        updateWrapper.set("check_passed", im.getCheckPassed());
        updateWrapper.set("check_time", im.getCheckTime());
        return getEntrustmentIdentificationMaterial(identificationMaterial, updateWrapper, im);

    }

    @Override
    public EntrustmentIdentificationMaterial bizApprove_Apply(EntrustmentIdentificationMaterial identificationMaterial, Integer opCode, DLPUser dlpUser) {

        if (opCode == null) {
            throw new RuntimeException(String.format("审批结果必须提供 opCode"));
        }

        // 检查委托原来的状态
        EntrustmentIdentificationMaterial im = this.getById(identificationMaterial.getId());
        if (im == null) {
            throw new RuntimeException(String.format("没有找到 id 为 %s 的检材", identificationMaterial.getId()));
        }

        Entrustment entrustment = entrustmentService.getById(im.getEntrustmentId());
        if (entrustment == null) {
            throw new RuntimeException(String.format("没有找到 id 为 %s 的委托", im.getEntrustmentId()));
        }

        if (entrustment.getStatus() != EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_APPROVE.getStatus()) {
            throw new RuntimeException("委托不在待审批状态");
        }

        if (!dlpUser.getId().equals(entrustment.getApproveClaimUser())) {
            throw new RuntimeException(String.format("委托的审批任务是由其他人认领的。认领用户是: %s", entrustment.getApproveClaimUser()));
        }


        //-------------------
        // 更新数据库表数据
        //-------------------
        im.setApprovePassed(opCode);
        im.setApproveTime(LocalDateTime.now());

        UpdateWrapper<EntrustmentIdentificationMaterial> updateWrapper = new UpdateWrapper<EntrustmentIdentificationMaterial>();
        updateWrapper.eq("id", im.getId());        // 查询条件是 id 相等

        return getEntrustmentIdentificationMaterial(identificationMaterial, updateWrapper, im);
    }

    /**
     * 更新检材是否审批通过
     * @param identificationMaterial
     * @param updateWrapper
     * @param im
     * @return
     */
    public EntrustmentIdentificationMaterial getEntrustmentIdentificationMaterial(EntrustmentIdentificationMaterial identificationMaterial, UpdateWrapper<EntrustmentIdentificationMaterial> updateWrapper, EntrustmentIdentificationMaterial im) {
        updateWrapper.set("approve_passed", im.getApprovePassed());
        updateWrapper.set("approve_time", im.getApproveTime());

        if (!this.update(null, updateWrapper)) {
            throw new RuntimeException("保存检材信息失败");
        }

        // 从数据库表中取出保存的委托对象, 后续的操作我们以此为准
        im = this.getById(identificationMaterial.getId());
        if (im == null) {
            throw new RuntimeException(String.format("没有找到 id 为 %s 的检材", identificationMaterial.getId()));
        }
        return im;
    }

    @Override
    public List<EntrustmentIdentificationMaterial> bizAccept_Save(List<EntrustmentIdentificationMaterial> materialList, DLPUser dlpUser) {
        boolean flag = false;
        for (EntrustmentIdentificationMaterial material : materialList) {
            if (material.getAcceptPassed() == 0) {
                flag = true;
            }
        }
        if (!flag) {
            throw new RuntimeException(String.format("检材均已受理，无法进行修改保存!"));
        }
        List<EntrustmentIdentificationMaterial> resultList = new ArrayList<>();
        for (EntrustmentIdentificationMaterial identificationMaterial : materialList) {

            // 检查委托原来的状态
            EntrustmentIdentificationMaterial im = this.getById(identificationMaterial.getId());
            if (im == null) {
                throw new RuntimeException(String.format("没有找到 id 为 %s 的检材", identificationMaterial.getId()));
            }

            if ((im.getAcceptPassed() != null) && (im.getAcceptPassed() != 0)) {
                continue;
//                throw new RuntimeException(String.format("检材只能在未受理状态才能保存"));
            }

            Entrustment entrustment = entrustmentService.getById(im.getEntrustmentId());
            if (entrustment == null) {
                throw new RuntimeException(String.format("没有找到 id 为 %s 的委托", im.getEntrustmentId()));
            }

            if (entrustment.getStatus() != EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_ACCEPT.getStatus()) {
                throw new RuntimeException("委托不在正在受理状态");
            }
            if (identificationMaterial.getSample1RepeatWeigh() != null) {
                im.setSample1RepeatWeigh(identificationMaterial.getSample1RepeatWeigh());
                im.setSample2RepeatWeigh(identificationMaterial.getSample2RepeatWeigh());
                this.saveRepWeigh(im, im.getSample1RepeatWeigh().doubleValue(), im.getSample2RepeatWeigh().doubleValue(), false, "");
            }


            //-------------------
            // 更新数据库表数据
            //-------------------
            im.setRemark(identificationMaterial.getRemark());
            im.setPack(identificationMaterial.getPack());
            // 如果之前没有生成过样本编号, 现在填写样本重量了, 那么就生成样本编号
            //if ((identificationMaterial.getSample1Present() != null) && identificationMaterial.getSample1Present()) {
            if (StrUtil.isBlank(identificationMaterial.getProvidedSample1No())) {
                im.setProvidedSample1No(sampleService.getNewProvidedSampleNo(im.getImNo(), 1));
            }
            //}
            if ((identificationMaterial.getProvidedSample2Present() != null) && identificationMaterial.getProvidedSample2Present()) {
                if (StrUtil.isBlank(identificationMaterial.getProvidedSample2No())) {
                    im.setProvidedSample2No(sampleService.getNewProvidedSampleNo(im.getImNo(), 2));
                }
            }
            // 如果之前没有生成过样本编号, 现在填写样本重量了, 那么就生成样本编号
            //if ((identificationMaterial.getSample1Present() != null) && identificationMaterial.getSample1Present()) {
            if (StrUtil.isBlank(identificationMaterial.getSample1No())) {
                im.setSample1No(sampleService.getNewSampleNo(im.getImNo(), 1));
            }
            //}
            if ((identificationMaterial.getSample2Present() != null) && identificationMaterial.getSample2Present()) {
                if (StrUtil.isBlank(identificationMaterial.getSample2No())) {
                    im.setSample2No(sampleService.getNewSampleNo(im.getImNo(), 2));
                }
            }

            if (!this.updateById(im)) {
                throw new RuntimeException("保存检材信息失败");
            }

            // 从数据库表中取出保存的委托对象, 后续的操作我们以此为准
            im = this.getById(identificationMaterial.getId());
            if (im == null) {
                throw new RuntimeException(String.format("没有找到 id 为 %s 的检材", identificationMaterial.getId()));
            }
            resultList.add(im);
        }
        return resultList;
    }

    @Override
    public EntrustmentIdentificationMaterial bizAccept_Apply(EntrustmentIdentificationMaterial identificationMaterial, Integer opCode, DLPUser dlpUser) {
        if (opCode == null) {
            throw new RuntimeException(String.format("受理结果必须提供 opCode"));
        }

        // 检查委托原来的状态
        EntrustmentIdentificationMaterial im = this.getById(identificationMaterial.getId());
        if (im == null) {
            throw new RuntimeException(String.format("没有找到 id 为 %s 的检材", identificationMaterial.getId()));
        }

        Entrustment entrustment = entrustmentService.getById(im.getEntrustmentId());
        if (entrustment == null) {
            throw new RuntimeException(String.format("没有找到 id 为 %s 的委托", im.getEntrustmentId()));
        }

        if (entrustment.getStatus() != EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_ACCEPT.getStatus()) {
            throw new RuntimeException("委托不在正在受理状态");
        }

        //-------------------
        // 更新数据库表数据
        //-------------------
        if (opCode == 1) {
            // 受理通过, 修改属性
            String entrustAcceptNo = com.baomidou.mybatisplus.core.toolkit.StringUtils.isNotBlank(entrustment.getAcceptNo()) ? entrustment.getAcceptNo() : "";
            String acceptNo = "";
            List<EntrustmentIdentificationMaterial> materialList = this.list(Wrappers.<EntrustmentIdentificationMaterial>lambdaQuery()
                    .eq(EntrustmentIdentificationMaterial::getEntrustmentId, im.getEntrustmentId())
                    .isNotNull(EntrustmentIdentificationMaterial::getAcceptNo));
            //2024-3-26 修改：我们已经不需要在受理检材时生成受理编号，我们这时会生成受理顺序号，检材编号到最后受理完成的时候再生成!
            if (entrustment.getDataSources() != 1) {
                if (materialList.size() > 0) {
                    //说明该委托下，已经有受理的检材了，我们需要取出最大的那个编号生成新的编号
                    entrustAcceptNo = materialList.get(0).getAcceptNo();
                    entrustAcceptNo = entrustAcceptNo.substring(0, entrustAcceptNo.lastIndexOf("-"));
                    log.info("该检材对应的委托下，已经有检材被受理，我们根据已受理的检材读取出的受理编号是{}", entrustAcceptNo);
                }
                acceptNo = this.getNewMaterialAcceptNo(entrustAcceptNo);
            } else {
                if (materialList.size() > 0) {
                    if (materialList.size() + 1 != im.getOrderNo()) {
                        throw new RuntimeException(String.format("请按照当前页面检材的顺序进行受理，因为这会涉及到同步到大数据平台中的检材顺序!"));
                    } else {
                        acceptNo = String.valueOf(materialList.size() + 1);
                    }
                } else {
                    acceptNo = "1";
                }
            }

            //设置受理编号
            im.setAcceptNo(acceptNo);
            im.setProvidedSample1No(identificationMaterial.getProvidedSample1No());
            im.setProvidedSample1FundQuantity(identificationMaterial.getProvidedSample1FundQuantity());
            im.setProvidedSample1Quantity(identificationMaterial.getProvidedSample1Quantity());

            im.setProvidedSample2Present(identificationMaterial.getProvidedSample2Present());
            im.setProvidedSample2No(identificationMaterial.getProvidedSample2No());
            im.setProvidedSample2FundQuantity(identificationMaterial.getProvidedSample2FundQuantity());
            im.setProvidedSample2Quantity(identificationMaterial.getProvidedSample2Quantity());

            im.setSplitedSample(identificationMaterial.getSplitedSample());

            im.setFundQuantity(identificationMaterial.getFundQuantity());
            im.setQuantity(identificationMaterial.getQuantity());
            im.setSample1No(identificationMaterial.getSample1No());
            im.setSample1FundQuantity(identificationMaterial.getSample1FundQuantity());
            im.setSample1Quantity(identificationMaterial.getSample1Quantity());
            im.setSample1BoxId(identificationMaterial.getSample1BoxId());

            im.setSample2No(identificationMaterial.getSample2No());
            im.setSample2FundQuantity(identificationMaterial.getSample2FundQuantity());
            im.setSample2Quantity(identificationMaterial.getSample2Quantity());
            im.setSample2BoxId(identificationMaterial.getSample2BoxId());

            SampleBox sb1 = null;
            SampleBox sb2 = null;
            // 如果之前没有生成过样本编号, 现在填写样本重量了, 那么就生成样本编号
            //if ((identificationMaterial.getSample1Present() != null) && (identificationMaterial.getSample1Present())) {
            //12-4日我们不再将承载物信息设置成必填了
//            if ((identificationMaterial.getSample1FundQuantity() == null) ||
//                    (identificationMaterial.getSample1FundQuantity().compareTo(0) == 0)) {
//                throw new RuntimeException(String.format("样本1的承载物数量不能为空, 也不能为 0"));
//            }
            if ((identificationMaterial.getSample1Quantity() == null) ||
                    (identificationMaterial.getSample1Quantity().equals(BigDecimal.ZERO))) {
                throw new RuntimeException(String.format("样本1的数量不能为空, 也不能为 0"));
            }
            if (StrUtil.isBlank(identificationMaterial.getSample1No())) {
                im.setSample1No(sampleService.getNewSampleNo(im.getImNo(), 1));
            }


            if ((identificationMaterial.getSample2Present() != null) && (identificationMaterial.getSample2Present())) {
                //12-4日我们不再将承载物信息设置成必填了
//                if ((identificationMaterial.getSample2FundQuantity() == null) ||
//                        (identificationMaterial.getSample2FundQuantity().compareTo(0) == 0)) {
//                    throw new RuntimeException(String.format("样本2的承载物数量不能为空, 也不能为 0"));
//                }
                if ((identificationMaterial.getSample2Quantity() == null) ||
                        (identificationMaterial.getSample2Quantity().compareTo(BigDecimal.ZERO) == 0)) {
                    throw new RuntimeException(String.format("样本2的数量不能为空, 也不能为 0"));
                }
                if (StrUtil.isBlank(identificationMaterial.getSample2No())) {
                    im.setSample2No(sampleService.getNewSampleNo(im.getImNo(), 2));
                }
            }

            im.setAcceptPassed(opCode);
            im.setAcceptTime(LocalDateTime.now());

            if (!this.updateById(im)) {
                throw new RuntimeException("保存检材信息失败");
            }
        } else {
            // 受理未通过, 不修改属性
            im.setAcceptPassed(opCode);
            im.setAcceptTime(LocalDateTime.now());
            im.setAcceptNo("");//如果拒绝受理
            if (!this.updateById(im)) {
                throw new RuntimeException("保存检材信息失败");
            }
        }
        // 从数据库表中取出保存的委托对象, 后续的操作我们以此为准
        im = this.getById(identificationMaterial.getId());
        if (im == null) {
            throw new RuntimeException(String.format("没有找到 id 为 %s 的检材", identificationMaterial.getId()));
        }
        return im;
    }

    @Override
    public EntrustmentIdentificationMaterial createIdentificationMaterialByEvidenceId(EntrustmentIdentificationMaterial identificationMaterial, DLPUser dlpUser) {

        String entrustmentId = identificationMaterial.getEntrustmentId();
        String evidenceId = identificationMaterial.getEvidenceId();
        Boolean copyAttachemnts = false;
        if (copyAttachemnts == null) {
            copyAttachemnts = false;
        }

        if (StrUtil.isBlank(entrustmentId)) {
            throw new RuntimeException(String.format("检材必须与某个委托关联, 必须提供 entrustmentId"));
        }
        if (StrUtil.isBlank(evidenceId)) {
            throw new RuntimeException(String.format("检材必须与某个物证关联, 必须提供 evidentceId"));
        }

        CaseEvidence ce = caseEvidenceService.getById(evidenceId);   // 取出对应的物证
        if (ce == null) {
            throw new RuntimeException(String.format("提供的 evidentceId [%s] 没有找到对应的物证", evidenceId));
        }

        identificationMaterial.setId(IdWorker.get32UUID().toUpperCase());
        identificationMaterial.setImNo(this.getNewIdentificationMaterialNo(ce.getEvidenceNo()));
        //设置一些初始属性
        identificationMaterial.setCheckPassed(0);
        identificationMaterial.setApprovePassed(0);
        identificationMaterial.setAcceptPassed(0);
        //设置序号，这里我们按先后顺序，给插入的检材排一个序号
        identificationMaterial.setOrderNo(getWtOrderNo(identificationMaterial.getEntrustmentId()));

        //保存采样人
        saveCollectors(identificationMaterial, dlpUser);

        //如果在创建检材这
        if (StrUtil.isBlank(identificationMaterial.getProvidedSample1No())) {
            identificationMaterial.setProvidedSample1No(sampleService.getNewProvidedSampleNo(identificationMaterial.getImNo(), 1));
        }
        if ((identificationMaterial.getProvidedSample2Present() != null) && identificationMaterial.getProvidedSample2Present()) {
            //如果委托单位分样了
            if (StrUtil.isBlank(identificationMaterial.getProvidedSample2No())) {
                identificationMaterial.setProvidedSample2No(sampleService.getNewProvidedSampleNo(identificationMaterial.getImNo(), 2));
            }
            //受理的时候应该有2个样
            identificationMaterial = settingAcceptSampleInfoDivide(identificationMaterial);
        } else {
            //委托单位没分样
            identificationMaterial = settingAcceptSampleInfoNoDivide(identificationMaterial);
        }
        //默认肯定有一个是分析样是永远存在的，添加的时候，先将这个样本生成出来,所以受理时候的分样信息有一个是存在的，同理如果送检时候的分样信息，也是默认有一个存在的，这个在分样的时候，通过接口调用产生
        //这里判断委托单位是否分样
        //identificationMaterial.setSample1No(sampleService.getNewSampleNo(identificationMaterial.getImNo(),1));

        identificationMaterial.setCreateBy(dlpUser.getId());
        identificationMaterial.setCreateTime(LocalDateTime.now());

        //判断检材的重量不能大于物证的重量   暂不判断，因为可能单位不统一
        if (this.save(identificationMaterial)) {
            // 新增检材记录成功
            try {
                if (copyAttachemnts) {
                    List<String> fileList = ossFile.fileList(OSSDirectoryConstants.ENTRUSTMENT_DIRECTORY + "/" + identificationMaterial.getCaseId() + "/" + identificationMaterial.getEvidenceId());
                    for (String fileName : fileList) {
                        String srcFileName = OSSDirectoryConstants.ENTRUSTMENT_DIRECTORY + "/" + identificationMaterial.getCaseId() + "/" + identificationMaterial.getEvidenceId() + "/" + fileName;
                        String destFileName = OSSDirectoryConstants.ENTRUSTMENT_DIRECTORY + "/" + identificationMaterial.getEntrustmentId() + "/" + identificationMaterial.getId() + "/" + fileName;
                        ossFile.fileCopy(srcFileName, destFileName);
                    }
                }
            } catch (Exception e) {
                System.out.println(String.format("复制物证附件到新建的检材附件目录出错: %s", e.getMessage()));
            }
            return identificationMaterial;
        } else return null;
    }

    @Override
    public EntrustmentIdentificationMaterial putUpdateById(EntrustmentIdentificationMaterial identificationMaterial, DLPUser dlpUser) {


        if (StrUtil.isNotBlank(identificationMaterial.getAcceptNo())) {
            throw new RuntimeException(String.format("当前检材已经受理了，不允许再进行修改"));
        }

        Entrustment entrustment = entrustmentService.getById(identificationMaterial.getEntrustmentId());

        if (entrustment.getDataSources() == 1) {
            EntrustOfThirdSys entrustOfThirdSys = synchronizeDataService.getOne(new LambdaQueryWrapper<EntrustOfThirdSys>().eq(EntrustOfThirdSys::getEntrustMainId, entrustment.getId()));
            EntrustMaterialOfThirdSys entrustMaterialOfThirdSys = synchronizeMaterialVoService.getById(identificationMaterial.getId());
            List<EntrustMaterialOfThirdSys> list = synchronizeMaterialVoService.list(new LambdaQueryWrapper<EntrustMaterialOfThirdSys>().eq(EntrustMaterialOfThirdSys::getEntrustId, entrustOfThirdSys.getId()));
            entrustMaterialOfThirdSys.setOrder_index(((Integer) (list.size() + 1)).toString());
            entrustMaterialOfThirdSys.setName(identificationMaterial.getName());
            String unitByZhCn = ConvertUtils.getUnitByZhCn(identificationMaterial.getUnit());
            entrustMaterialOfThirdSys.setUnit(unitByZhCn);
            entrustMaterialOfThirdSys.setSampleUnit(unitByZhCn);
            entrustMaterialOfThirdSys.setColorType(identificationMaterial.getColor());
            entrustMaterialOfThirdSys.setShapeType(entrustmentMapper.getTypeForDictionary(identificationMaterial.getType()));
            entrustMaterialOfThirdSys.setPackageType(entrustmentMapper.getTypeForDictionary(identificationMaterial.getPack()));
            entrustMaterialOfThirdSys.setAmount(identificationMaterial.getQuantity());
            List<DrugLite> candidateDrugs = identificationMaterial.getCandidateDrugs();

            entrustMaterialOfThirdSys.setTargetObjectTypeList(JSON.toJSONString(candidateDrugs.stream().map(DrugLite::getName).collect(Collectors.toList())));
            entrustMaterialOfThirdSys.setAnalysisType(AnalysisOptionEnums.fromCode(identificationMaterial.getAnalysisOption()).getEnglishName());
            synchronizeMaterialVoService.updateById(entrustMaterialOfThirdSys);
        }

        if (entrustment.getStatus() != EntrustmentStatusConstants.ENTRUSTMENT_STATUS_CREATED.getStatus() && !dlpUser.isStaff()) {
            throw new RuntimeException(String.format("当前委托不在可以修改的状态"));
        }

        if (StrUtil.isBlank(identificationMaterial.getId())) {
            throw new RuntimeException(String.format("检材信息中没有检材标识 id"));
        }
        if (StrUtil.isBlank(identificationMaterial.getCaseId())) {
            throw new RuntimeException(String.format("检材必须与某个案件关联, 必须提供 caseId"));
        }
        if (StrUtil.isBlank(identificationMaterial.getEntrustmentId())) {
            throw new RuntimeException(String.format("检材必须与某个委托关联, 必须提供 entrustmentId"));
        }
        //现在检材不一定会绑定物证了 12-1
//        if (StrUtil.isBlank(identificationMaterial.getEvidenceId())) {
//            throw new RuntimeException(String.format("检材必须与某个物证关联, 必须提供 evidentceId"));
//        }

        EntrustmentIdentificationMaterial im = this.getById(identificationMaterial.getId());
        if (im == null) {
            throw new RuntimeException(String.format("不存在 id 为 %s 的检材", identificationMaterial.getId()));
        }

        if ((im.getCheckPassed() != null && im.getCheckPassed() == 1) && !dlpUser.isStaff()) {
            throw new RuntimeException(String.format("已审核的检材不能修改"));
        }
        if ((im.getApprovePassed() != null && im.getApprovePassed() == 1) && !dlpUser.isStaff()) {
            throw new RuntimeException(String.format("已审批的检材不能修改"));
        }
        if ((im.getAcceptPassed() != null && im.getAcceptPassed() == 1) && !dlpUser.isStaff()) {
            throw new RuntimeException(String.format("已受理的检材不能修改"));
        }

        identificationMaterial.setCheckPassed(0);
        identificationMaterial.setApprovePassed(0);
        identificationMaterial.setAcceptPassed(0);
        identificationMaterial.setSample1RepeatWeigh(identificationMaterial.getQuantity());
        identificationMaterial.setSample2RepeatWeigh(null);

        //-- 更新采集员表信息 ----------------
        this.saveCollectors(identificationMaterial, dlpUser);
        //--------------------------------

        // 如果之前没有生成过样本编号, 现在填写样本重量了, 那么就生成样本编号
        //if ((identificationMaterial.getSample1Present() != null) && identificationMaterial.getSample1Present()) {
        if (StrUtil.isBlank(identificationMaterial.getProvidedSample1No())) {
            identificationMaterial.setProvidedSample1No(sampleService.getNewSampleNo(im.getImNo(), 1));
        }


        //}

        if ((identificationMaterial.getProvidedSample2Present() != null) && identificationMaterial.getProvidedSample2Present()) {
            identificationMaterial.setSample2Present(true);
            if (identificationMaterial.getProvidedSample2Quantity() != null) {
                identificationMaterial.setSample2Quantity(identificationMaterial.getProvidedSample2Quantity());
            }
            if (StrUtil.isBlank(identificationMaterial.getProvidedSample2No())) {
                identificationMaterial.setProvidedSample2No(sampleService.getNewSampleNo(im.getImNo(), 2));
            }
            identificationMaterial.setSample1Quantity(identificationMaterial.getProvidedSample1Quantity());
            identificationMaterial = this.settingAcceptSampleInfoDivide(identificationMaterial);
        } else {
            //委托单位没分样,就按照Quantity赋值
            identificationMaterial = this.settingAcceptSampleInfoNoDivide(identificationMaterial);
            identificationMaterial.setProvidedSample1Quantity(identificationMaterial.getQuantity());
            identificationMaterial.setSample1Quantity(identificationMaterial.getQuantity());
            identificationMaterial.setSample2Present(false);

            //因为有可能用户先分样了，后面又取消分样了，我们得把样本2的编号去除掉
            if (StrUtil.isNotBlank(identificationMaterial.getProvidedSample2No()) || StrUtil.isNotBlank(identificationMaterial.getSample2No())) {
                identificationMaterial.setProvidedSample2No("");
                identificationMaterial.setSample2No("");
            }


        }

        //这里要区分一下，前端只能传入一个值，所以我们需要将这个值赋值给sample2Quantity
        identificationMaterial.setCreateBy(null);
        identificationMaterial.setCreateTime(null);
        identificationMaterial.setUpdateBy(dlpUser.getId());
        identificationMaterial.setUpdateTime(LocalDateTime.now());
        identificationMaterial.setPackName(entrustmentMapper.getTypeForDictionary(identificationMaterial.getPack()));
        return this.updateById(identificationMaterial) ? identificationMaterial : null;
    }


    @Override
    public void saveCollectors(EntrustmentIdentificationMaterial material, DLPUser dlpUser) {
        Taker taker1 = new Taker();
        taker1.setOwnerUserId(dlpUser.getId());
        taker1.setName(material.getTake1Name());
        taker1.setPosition(material.getTake1Position());
        taker1.setCert(material.getTake1Cert());
        taker1.setIdnum(material.getTake1Id());
        taker1.setPhone(material.getTake1Phone());
        takerService.renew(taker1);
        Taker taker2 = new Taker();
        taker2.setOwnerUserId(dlpUser.getId());
        taker2.setName(material.getTake2Name());
        taker2.setPosition(material.getTake2Position());
        taker2.setCert(material.getTake2Cert());
        taker2.setIdnum(material.getTake2Id());
        taker2.setPhone(material.getTake2Phone());
        takerService.renew(taker2);
    }

    @Override
    public EntrustmentIdentificationMaterial settingAcceptSampleInfoDivide(EntrustmentIdentificationMaterial material) {
        material.setSample1No(sampleService.getNewSampleNo(material.getImNo(), 1));
        material.setSample1Quantity(material.getProvidedSample1Quantity());
        material.setSample1FundQuantity(material.getProvidedSample1FundQuantity());

        material.setSample2No(sampleService.getNewSampleNo(material.getImNo(), 2));
        material.setSample2Quantity(material.getProvidedSample2Quantity());
        material.setSample2FundQuantity(material.getProvidedSample2FundQuantity());
        return material;
    }

    @Override
    //设置送检单位初始分样信息
    public EntrustmentIdentificationMaterial settingProviderSampleInfo(EntrustmentIdentificationMaterial material) {
        material.setProvidedSample1No(sampleService.getNewProvidedSampleNo(material.getImNo(), 1));
        material.setProvidedSample1Quantity(material.getQuantity());
        material.setProvidedSample1FundQuantity(material.getFundQuantity());
        return material;
    }

    @Override
    public EntrustmentIdentificationMaterial settingAcceptSampleInfoNoDivide(EntrustmentIdentificationMaterial material) {
        material.setSample1No(sampleService.getNewSampleNo(material.getImNo(), 1));
        //material.setSample1Quantity(material.getQuantity());
        material.setSample1Quantity(material.getProvidedSample1Quantity());//这里应该使用送检单位送检的样本重量
        material.setSample1FundQuantity(material.getFundQuantity());
        return material;
    }

    private int getWtOrderNo(String entrustId) {
        List<EntrustmentIdentificationMaterial> materialList = this.list(Wrappers.<EntrustmentIdentificationMaterial>query()
                .eq("entrustment_id", entrustId));
        int count = materialList.size();
        int newNo = count + 1;
        return newNo;
    }

    @Override
    public EntrustmentIdentificationMaterial deleteById(String id) {
        if (StrUtil.isBlank(id)) {
            throw new RuntimeException(String.format("必须把检材 id 作为路径的一部分提供!"));
        }
        EntrustmentIdentificationMaterial entrustmentIdentificationMaterial = this.getById(id);
        if (entrustmentIdentificationMaterial == null) {
            throw new RuntimeException(String.format("不存在 id 为 %s 的检材", id));
        }

        List<String> attList = ossFile.fileList(OSSDirectoryConstants.ENTRUSTMENT_DIRECTORY + "/" + entrustmentIdentificationMaterial.getEntrustmentId() + "/" + id);
        long attCount = attList.size();
        if (attCount > 0) {
            throw new RuntimeException(String.format("这个检材下有 %d 个附件, 必须先删除全部附件后才能删除检材物证!", attCount));
        }
        if (this.removeById(id)) {
            return entrustmentIdentificationMaterial;
        } else {
            return null;
        }
    }

    @Override
    public boolean saveRepWeigh(EntrustmentIdentificationMaterial entrustmentIdentificationMaterial, double sample1RepeatWeigh, double sample2RepeatWeigh, boolean isUseBalance, String sampleFlag) {
        BigDecimal data1 = new BigDecimal(sample1RepeatWeigh);
        BigDecimal data2 = new BigDecimal(!Double.isNaN(sample2RepeatWeigh) ? sample2RepeatWeigh : 0);
//        EntrustmentIdentificationMaterial entrustmentIdentificationMaterial = this.getById(id);
        entrustmentIdentificationMaterial.setSample1RepeatWeigh(data1);
        entrustmentIdentificationMaterial.setSample2RepeatWeigh(data2);
        //设置样本的重量
        //如果没有原质量，我们就把复称的质量来设置原质量，如果有原质量，就啥都不干
        if (entrustmentIdentificationMaterial.getSample1Quantity() == null || entrustmentIdentificationMaterial.getSample1Quantity().compareTo(BigDecimal.ZERO) <= 0) {
            entrustmentIdentificationMaterial.setSample1Quantity(data1);
        }
        if (entrustmentIdentificationMaterial.getSample2Quantity() == null || entrustmentIdentificationMaterial.getSample2Quantity().compareTo(BigDecimal.ZERO) <= 0) {
            entrustmentIdentificationMaterial.setSample2Quantity(data2);
            entrustmentIdentificationMaterial.setSample2FundQuantity(entrustmentIdentificationMaterial.getFundQuantity());
        }
        //设置检材质量
        //如果是小于0.说明是未称量，那么我们复称的时候，就把称量的值拿他保存，也说明可能是其他的单位，比如是毫升，等单位

        entrustmentIdentificationMaterial.setQuantity(entrustmentIdentificationMaterial.getQuantity().compareTo(BigDecimal.ZERO) == -1 ? new BigDecimal(sample1RepeatWeigh) : entrustmentIdentificationMaterial.getQuantity());

        boolean ret = this.updateById(entrustmentIdentificationMaterial);
        if (isUseBalance) {
            //说明使用了 电子天平称量，这里我们需要生成使用记录
            BalanceUseRecord balanceUseRecord = new BalanceUseRecord();
            balanceUseRecord.setId(IdWorker.get32UUID());
            balanceUseRecord.setUseDate(LocalDate.now());
            balanceUseRecord.setUserId(SecurityUtils.getCurrentUserId());
            balanceUseRecord.setRemark("受理复秤");
            balanceUseRecord.setEquipmentId("");
            balanceUseRecord.setEquipmentNumber("NADL-Shaanxi-A-010");
            balanceUseRecord.setSampleName(entrustmentIdentificationMaterial.getName());
            balanceUseRecord.setSampleNumber(entrustmentIdentificationMaterial.getImNo());
            balanceUseRecord.setUserName(SecurityUtils.getUser().getName());
            if (sampleFlag.equals("1")) {
                balanceUseRecord.setWeighingMass(new BigDecimal(sample1RepeatWeigh));
            }
            if (sampleFlag.equals("2")) {
                balanceUseRecord.setWeighingMass(new BigDecimal(sample2RepeatWeigh));
            }
            List<BalanceUseRecord> balanceUseRecordList = new ArrayList<>();
            balanceUseRecordList.add(balanceUseRecord);
            log.info("保存天平使用记录{}", balanceUseRecord);
            remoteEquipmentService.addUseRecord(balanceUseRecordList);
        }
        log.info("保存成功 {}");

        return ret;

    }

    @Override
    public EntrustmentIdentificationMaterial settingRetained(String id, int flag) {
        EntrustmentIdentificationMaterial entrustmentIdentificationMaterial = this.getById(id);
        if (flag == 1) {
            entrustmentIdentificationMaterial.setSample2Present(true);
            //应该设置样本2的编号
            entrustmentIdentificationMaterial.setSample2No(sampleService.getNewSampleNo(entrustmentIdentificationMaterial.getImNo(), 2));
        } else {
            //如果传回-1的时候，表示删掉了，因此我们清空留存样的值,清除掉样品2的属性值
            entrustmentIdentificationMaterial.setSample2Present(false);
            entrustmentIdentificationMaterial.setSample2RepeatWeigh(new BigDecimal(0));
            entrustmentIdentificationMaterial.setSample2Quantity(new BigDecimal(0));
            entrustmentIdentificationMaterial.setSample2No("");
        }
        this.updateById(entrustmentIdentificationMaterial);
        return entrustmentIdentificationMaterial;

    }


    @Override
    @Transactional
    public List<EntrustmentIdentificationMaterial> createNewIm(List<EntrustmentIdentificationMaterial> identificationMaterialList, DLPUser dlpUser) {

        Entrustment entrustment = entrustmentService.getById(identificationMaterialList.get(0).getEntrustmentId());
        if (!dlpUser.isStaff() && entrustment.getStatus() != EntrustmentStatusConstants.ENTRUSTMENT_STATUS_CREATED.getStatus()) {
            throw new RuntimeException(String.format("你已提交过该委托，无法再添加检材信息!"));
        }
        // 记录当前委托的检材数量
        Integer currentEntrustMaterialCount = (int) this.count(Wrappers.<EntrustmentIdentificationMaterial>lambdaQuery()
                .eq(EntrustmentIdentificationMaterial::getEntrustmentId, entrustment.getId()));
        for (EntrustmentIdentificationMaterial identificationMaterial : identificationMaterialList) {
            if (StringUtils.isNotBlank(identificationMaterial.getId()) && StringUtils.isNotBlank(identificationMaterial.getSample1No())) {
                identificationMaterial = this.putUpdateById(identificationMaterial, dlpUser);
            } else {
                String id = IdWorker.get32UUID().toUpperCase();
                if (entrustment.getDataSources() == 1) {
                    saveEntrustMaterialToThirdSys(identificationMaterial, entrustment, id);
                }

                String entrustmentId = identificationMaterial.getEntrustmentId();
                // 校验案件信息是否合法
                CaseEvent cj = validateCaseInfo(identificationMaterial);

                ////若提前创建好了物证，则关联通过物证编号关联检材编号即可；
                setMaterialIdentificationNo(identificationMaterial, cj);
                Boolean copyAttachemnts = false;
                if (copyAttachemnts == null) {
                    copyAttachemnts = false;
                }


                if (StrUtil.isBlank(entrustmentId)) {
                    throw new RuntimeException(String.format("检材必须与某个委托关联, 必须提供 entrustmentId"));
                }

                identificationMaterial.setId(id);
                //设置一些初始属性
                identificationMaterial.setCheckPassed(0);
                identificationMaterial.setApprovePassed(0);
                identificationMaterial.setAcceptPassed(0);

                identificationMaterial.setPackName(identificationMaterial.getPack());
                Integer entrustmentType = entrustment.getEntrustmentType();
                //检材继承委托类型
                if (entrustmentType == 0) {
                    identificationMaterial.setTypeName("常规毒品");
                } else if (entrustmentType == 1) {
                    identificationMaterial.setTypeName("生物样本");
                }
//            identificationMaterial.setTypeName(entrustmentMapper.getTypeForDictionary(identificationMaterial.getType()));
                identificationMaterial.setFormName(identificationMaterial.getForm());
                //设置序号，这里我们按先后顺序，给插入的检材排一个序号
                identificationMaterial.setOrderNo(getWtOrderNo(identificationMaterial.getEntrustmentId()));
                //如果传来了样本1的质量，我们要将它赋给Sample1Quantity
                if (identificationMaterial.getSample1Quantity() == null) {
                    identificationMaterial.setSample1Quantity(identificationMaterial.getProvidedSample1Quantity());
                }
                //保存采样人
                saveCollectors(identificationMaterial, dlpUser);

                List<EntrustmentIdentificationMaterial> list = this.list(new LambdaQueryWrapper<EntrustmentIdentificationMaterial>().eq(EntrustmentIdentificationMaterial::getProvidedSample1No, identificationMaterial.getProvidedSample1No()));
                //如果在创建检材这
                if (StrUtil.isBlank(identificationMaterial.getProvidedSample1No()) || (list != null && list.size() > 0)) {
                    identificationMaterial.setProvidedSample1No(sampleService.getNewProvidedSampleNo(identificationMaterial.getImNo(), 1));
                }
                if ((identificationMaterial.getProvidedSample2Present() != null) && identificationMaterial.getProvidedSample2Present()) {
                    //如果委托单位分样了
                    //如果委托单位分样了
                    if (StrUtil.isBlank(identificationMaterial.getProvidedSample2No())) {
                        identificationMaterial.setProvidedSample2No(sampleService.getNewProvidedSampleNo(identificationMaterial.getImNo(), 2));
                    }
                    //受理的时候应该有2个样
                    identificationMaterial = settingAcceptSampleInfoDivide(identificationMaterial);
                    //如果分样了,并且传入了样本2的值，那么我们将这个值要赋给sample2Quantity，以便受理的时候使用
                    if (identificationMaterial.getProvidedSample2Quantity() != null) {
                        identificationMaterial.setSample2Quantity(identificationMaterial.getProvidedSample2Quantity());
                    }
                } else {
                    //委托单位没分样
                    identificationMaterial = settingAcceptSampleInfoNoDivide(identificationMaterial);
                }
                //默认肯定有一个是分析样是永远存在的，添加的时候，先将这个样本生成出来,所以受理时候的分样信息有一个是存在的，同理如果送检时候的分样信息，也是默认有一个存在的，这个在分样的时候，通过接口调用产生
                //这里判断委托单位是否分样
                //identificationMaterial.setSample1No(sampleService.getNewSampleNo(identificationMaterial.getImNo(),1));
                // 初始化委托序号
                currentEntrustMaterialCount++;
                identificationMaterial.setImEntrustNumber(currentEntrustMaterialCount.toString());
                identificationMaterial.setCreateBy(dlpUser.getId());
                identificationMaterial.setCreateTime(LocalDateTime.now());
                identificationMaterial.setAcceptNo(null);
                identificationMaterial.setSample1RepeatWeigh(identificationMaterial.getQuantity());
                identificationMaterial.setSample2RepeatWeigh(null);
                identificationMaterial.setColor("");


                //判断检材的重量不能大于物证的重量   暂不判断，因为可能单位不统一
                if (this.save(identificationMaterial)) {
                    // 新增检材记录成功
                    try {
                        if (copyAttachemnts) {
                            List<String> fileList = ossFile.fileList(OSSDirectoryConstants.ENTRUSTMENT_DIRECTORY + "/" + identificationMaterial.getCaseId() + "/" + identificationMaterial.getEvidenceId());
                            for (String fileName : fileList) {
                                String srcFileName = OSSDirectoryConstants.ENTRUSTMENT_DIRECTORY + "/" + identificationMaterial.getCaseId() + "/" + identificationMaterial.getEvidenceId() + "/" + fileName;
                                String destFileName = OSSDirectoryConstants.ENTRUSTMENT_DIRECTORY + "/" + identificationMaterial.getEntrustmentId() + "/" + identificationMaterial.getId() + "/" + fileName;
                                ossFile.fileCopy(srcFileName, destFileName);
                            }
                        }
                    } catch (Exception e) {
                        System.out.println(String.format("复制物证附件到新建的检材附件目录出错: %s", e.getMessage()));
                    }
                }
            }
        }
        List<EntrustmentIdentificationMaterial> list = this.list(Wrappers.<EntrustmentIdentificationMaterial>lambdaQuery()
                .eq(EntrustmentIdentificationMaterial::getEntrustmentId, entrustment.getId())
                .orderByAsc(EntrustmentIdentificationMaterial::getOrderNo));
        entrustment.setEntrustRequirement(entrustmentService.buildEntrustReq(list));
        entrustmentService.updateById(entrustment);
        return identificationMaterialList;
    }


    @Override//打印小标签模板的方法
    public List<String> printLabel(List<PrintDTO> printDTOList) {

        List<Map<String, Object>> maps = new ArrayList<>();
        String templateFileName = "(小)受理时打印的检材条码模板.vm";
        for (PrintDTO printDTO : printDTOList) {
            String id = printDTO.getId();
            EntrustmentIdentificationMaterial identificationMaterial = this.getById(id);
            Map<String, Object> data = new HashMap<>();
            CaseEvent caseEvent = caseEventService.getById(identificationMaterial.getCaseId());
            Entrustment entrustment = entrustmentService.getById(identificationMaterial.getEntrustmentId());
            data.put("identificationMaterial", identificationMaterial);
            data.put("caseEvent", caseEvent);
            data.put("entrustment", entrustment);
            maps.add(data);
        }
        return remoteTemplate2htmlService.getManyHtml(templateFileName, maps);
    }

    @Override
    public List<String> printManyLabel(List<PrintDTO> printDTOList) {
        //判断类型，打印小标签还是大标签
        Integer type = printDTOList.get(0).getType();

        List<String> htmlList = new ArrayList<>();

        List<Map<String, Object>> maps = new ArrayList<>();

        //这里区分打印的是分析样还是留存样，因为调用的模板不一样，所以需要创建两个集合进行分别打印
        List<PrintDTO> printDTOA = new ArrayList<>();
        List<PrintDTO> printDTOB = new ArrayList<>();

        for (PrintDTO printDTO : printDTOList) {
            if (printDTO.getSample().equals("A")) {
                printDTOA.add(printDTO);
            } else if (printDTO.getSample().equals("B")) {
                printDTOB.add(printDTO);
            }
        }
        if (type == 1) {//区分是打印大标签还是小标签，1：大标签  0：小标签

            for (PrintDTO printDTO : printDTOA) {

                String id = printDTO.getId();

                //把数据填入上下文
                EntrustmentIdentificationMaterial im = this.getById(id);
                if (im == null) {
                    throw new RuntimeException(String.format("没有找到 id 为 %s 的检材", id));
                }

                Entrustment entrustment = entrustmentService.getById(im.getEntrustmentId());
                if (entrustment == null) {
                    throw new RuntimeException(String.format("没有找到 id 为 %s 的委托", im.getEntrustmentId()));
                }

                CaseEvent ce = caseEventService.getById(im.getCaseId());
                if (ce == null) {
                    throw new RuntimeException(String.format("没有找到 id 为 %s 的案件", im.getCaseId()));
                }

//                CaseEvidence evidence = caseEvidenceService.getById(im.getEvidenceId());
//                if (evidence == null) {
//                    throw new RuntimeException(String.format("没有找到 id 为 %s 的物证", im.getEvidenceId()));
//                }

                Map<String, Object> data = new HashMap<>();
                data.put("identificationMaterial", im);
                data.put("caseEvent", ce);
                data.put("entrustment", entrustment);
//                data.put("evidence", evidence);

                maps.add(data);
//                String templateFileName = AppStartupRunner.getCfg(CommonConstants.DLP_CODE_ENTRUSTMENT_LABEL_TEMPLATE_IM_SAMPLE1);
                String templateFileName = "(大)受理时打印的检材条码模板.vm";
                List<String> htmlA = remoteTemplate2htmlService.getManyHtml(templateFileName, maps);
                htmlList.addAll(htmlA);
            }

            for (PrintDTO printDTO : printDTOB) {

                String id = printDTO.getId();

                //把数据填入上下文
                EntrustmentIdentificationMaterial im = this.getById(id);
                if (im == null) {
                    throw new RuntimeException(String.format("没有找到 id 为 %s 的检材", id));
                }

                Entrustment entrustment = entrustmentService.getById(im.getEntrustmentId());
                if (entrustment == null) {
                    throw new RuntimeException(String.format("没有找到 id 为 %s 的委托", im.getEntrustmentId()));
                }

                CaseEvent ce = caseEventService.getById(im.getCaseId());
                if (ce == null) {
                    throw new RuntimeException(String.format("没有找到 id 为 %s 的案件", im.getCaseId()));
                }

//                CaseEvidence evidence = caseEvidenceService.getById(im.getEvidenceId());
//                if (evidence == null) {
//                    throw new RuntimeException(String.format("没有找到 id 为 %s 的物证", im.getEvidenceId()));
//                }

                Map<String, Object> data = new HashMap<>();
                data.put("identificationMaterial", im);
                data.put("caseEvent", ce);
                data.put("entrustment", entrustment);
//                data.put("evidence", evidence);

                maps.add(data);
                String templateFileName = AppStartupRunner.getCfg(CommonConstants.DLP_CODE_ENTRUSTMENT_LABEL_TEMPLATE_IM_SAMPLE2);
                List<String> htmlB = remoteTemplate2htmlService.getManyHtml(templateFileName, maps);
                htmlList.addAll(htmlB);
            }
            return htmlList;
        } else {
            //打印小标签
            List<String> htmlA = printLabel(printDTOA);
            List<String> htmlB = printLabel(printDTOB);
            htmlList.addAll(htmlA);
            htmlList.addAll(htmlB);
            return htmlList;
        }
    }

    @Override
    public String printMaterialArchives(String entrustmentId) throws Exception {

        String applyFileName = "检材样本档案.docx";
        String path = "document/accept/" + entrustmentId;
        String finalPath = "document/accept/" + entrustmentId + "/" + applyFileName;
        List<String> fileList = ossFile.fileList(path);
        for (String file : fileList) {
            if (file.equals(applyFileName)) {
                return finalPath;
            }
        }

        List<EntrustmentIdentificationMaterial> materialList = this.list(Wrappers.<EntrustmentIdentificationMaterial>lambdaQuery().eq(EntrustmentIdentificationMaterial::getEntrustmentId, entrustmentId));
        for (EntrustmentIdentificationMaterial material : materialList) {
            material.setPrintAcceptTime(LocalDateTimeUtil.format(material.getAcceptTime(), "yyyy-MM-dd"));
            material.setDescription(material.getOrderNo() + "号检材");
        }
        Collections.sort(materialList, new Comparator<EntrustmentIdentificationMaterial>() {
            @Override
            public int compare(EntrustmentIdentificationMaterial o1, EntrustmentIdentificationMaterial o2) {
                String[] o1AcceptNo = o1.getAcceptNo().split("-");
                String[] o2AcceptNo = o2.getAcceptNo().split("-");
                return Integer.compare(Integer.parseInt(o1AcceptNo[o1AcceptNo.length - 1]), Integer.parseInt(o2AcceptNo[o2AcceptNo.length - 1]));
            }
        });
        int index = 0;//需要构建的空白的参数，用来填充表格
        if (materialList.size() < 18) {//这份文件的行数为18
            index = 18 - materialList.size();
            for (int i = 0; i < index; i++) {
                EntrustmentIdentificationMaterial entrustmentIdentificationMaterial = getEntrustmentIdentificationMaterial();
                materialList.add(entrustmentIdentificationMaterial);
            }
            //如果大于18条数据了 证明不止一页了，那我们看看剩下的是否填充满了一页，如果没有就构建数据
        } else if (materialList.size() > 18) {
            index = materialList.size() % 18;
            if (index != 0) {
                for (int i = 0; i < 18 - index; i++) {
                    EntrustmentIdentificationMaterial entrustmentIdentificationMaterial = getEntrustmentIdentificationMaterial();
                    materialList.add(entrustmentIdentificationMaterial);
                }
            }
        }

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ossFile.fileGet("template" + "/" + "检材样本档案.docx", bos);
        byte[] templateArray = bos.toByteArray();
        ByteArrayInputStream bis = new ByteArrayInputStream(templateArray);
        bos.close();
        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
        ConfigureBuilder builder = Configure.builder().buildGramer("${", "}").useSpringEL(false);
        builder.bind("voList", policy).build();
        XWPFTemplate template = XWPFTemplate.compile(bis, builder.build()).render(
                new HashMap<String, Object>() {{
                    put("voList", materialList);
                }}

        );
        bis.close();
        org.apache.commons.io.output.ByteArrayOutputStream fosWord = new org.apache.commons.io.output.ByteArrayOutputStream();
        template.write(fosWord);
        template.close();

        //------------
        ByteArrayInputStream fisWord = new ByteArrayInputStream(fosWord.toByteArray());
        fosWord.close();
        boolean ret = ossFile.fileSave(finalPath, fisWord);
        if (ret) {
            return path;
        } else {
            return null;
        }
    }

    private static EntrustmentIdentificationMaterial getEntrustmentIdentificationMaterial() {
        EntrustmentIdentificationMaterial entrustmentIdentificationMaterial = new EntrustmentIdentificationMaterial();
        entrustmentIdentificationMaterial.setPrintAcceptTime("");
        entrustmentIdentificationMaterial.setAcceptNo("");
        entrustmentIdentificationMaterial.setTypeName("");
        entrustmentIdentificationMaterial.setFormName("");
        entrustmentIdentificationMaterial.setPackName("");
        entrustmentIdentificationMaterial.setDescription("");
        return entrustmentIdentificationMaterial;
    }

    //用作于处理一些打印委托书或鉴定事项确认书时的字段类型转换
    @Override
    public void conformityDrugs(List<EntrustmentIdentificationMaterial> list) {
        if (list != null && list.size() > 0) {
            for (EntrustmentIdentificationMaterial material : list) {
                Integer analysisOption = material.getAnalysisOption();
                material.setQuantity(material.getQuantity().setScale(2, BigDecimal.ROUND_HALF_UP));

                material.setAnalysisOptionValue(AnalysisOptionEnums.fromCode(analysisOption).getChineseName());
                material.setPrintDrawTime(LocalDateTimeUtil.format(material.getDrawTime(), "yyyy-MM-dd"));
                List<DrugLite> candidateDrugs = material.getCandidateDrugs();
                String drugsValue = "";
                if (candidateDrugs == null || candidateDrugs.size() == 0) {
                    return;
                }
                for (int i = 0; i < candidateDrugs.size(); i++) {
                    String toJSONString = JSONObject.toJSONString(candidateDrugs.get(i));
                    DrugLite drugLite = JSONObject.parseObject(toJSONString, DrugLite.class);
                    if (i == 0) {
                        drugsValue = drugLite.getName();
                    } else {
                        drugsValue += "、" + drugLite.getName();
                    }
                }
                material.setDrugsValue(drugsValue);
            }
        }
    }

    /**
     * 将委托鉴定材料保存到第三方系统
     *
     * @param identificationMaterial 委托鉴定材料对象
     * @param entrustment          委托对象
     * @param id                   材料唯一标识
     */
    private void saveEntrustMaterialToThirdSys(EntrustmentIdentificationMaterial identificationMaterial, Entrustment entrustment, String id) {
        EntrustOfThirdSys entrustOfThirdSys = synchronizeDataService.getOne(new LambdaQueryWrapper<EntrustOfThirdSys>().eq(EntrustOfThirdSys::getEntrustMainId, entrustment.getId()));
        EntrustMaterialOfThirdSys entrustMaterialOfThirdSys = new EntrustMaterialOfThirdSys();
        entrustMaterialOfThirdSys.setEntrustId(entrustOfThirdSys.getId());
        entrustMaterialOfThirdSys.setId(id);
        List<EntrustMaterialOfThirdSys> list = synchronizeMaterialVoService.list(new LambdaQueryWrapper<EntrustMaterialOfThirdSys>().eq(EntrustMaterialOfThirdSys::getEntrustId, entrustOfThirdSys.getId()));
        entrustMaterialOfThirdSys.setOrder_index(((Integer) (list.size() + 1)).toString());
        entrustMaterialOfThirdSys.setName(identificationMaterial.getName());
        String unitByZhCn = ConvertUtils.getUnitByZhCn(identificationMaterial.getUnit());
        entrustMaterialOfThirdSys.setUnit(unitByZhCn);
        entrustMaterialOfThirdSys.setSampleUnit(unitByZhCn);
        entrustMaterialOfThirdSys.setColorType(identificationMaterial.getColor());
        entrustMaterialOfThirdSys.setShapeType(entrustmentMapper.getTypeForDictionary(identificationMaterial.getType()));
        entrustMaterialOfThirdSys.setPackageType(identificationMaterial.getPackName());
        entrustMaterialOfThirdSys.setAmount(identificationMaterial.getQuantity());
        List<DrugLite> candidateDrugs = identificationMaterial.getCandidateDrugs();

        entrustMaterialOfThirdSys.setTargetObjectTypeList(JSON.toJSONString(candidateDrugs.stream().map(DrugLite::getName).collect(Collectors.toList())));
        entrustMaterialOfThirdSys.setAnalysisType(AnalysisOptionEnums.fromCode(identificationMaterial.getAnalysisOption()).getEnglishName());
        synchronizeMaterialVoService.save(entrustMaterialOfThirdSys);
    }

    /**
     * 设置委托鉴定材料的鉴定编号
     *
     * @param identificationMaterial 委托鉴定材料对象
     * @param cj                   案件事件对象
     */
    private void setMaterialIdentificationNo(EntrustmentIdentificationMaterial identificationMaterial, CaseEvent cj) {
        if (StrUtil.isNotBlank(identificationMaterial.getEvidenceId())) {
            CaseEvidence caseEvidence = caseEvidenceService.getById(identificationMaterial.getEvidenceId());
            identificationMaterial.setImNo(this.getNewIdentificationMaterialNo(caseEvidence.getEvidenceNo()));

        } else {
            String newEvidenceCode = caseEvidenceService.getNewEvidenceCode(cj.getCaseNo());
            String materialNo = this.getNewIdentificationMaterialNo(newEvidenceCode);
            identificationMaterial.setImNo(materialNo);
        }
    }

    /**
     * 校验案件信息是否合法
     * @param identificationMaterial
     * @return
     */
    private CaseEvent validateCaseInfo(EntrustmentIdentificationMaterial identificationMaterial) {
        if (StrUtil.isBlank(identificationMaterial.getCaseId())) {
            throw new RuntimeException(String.format("检材必须与某个案件关联, 必须提供 caseId"));
        }
        CaseEvent cj = caseEventService.getById(identificationMaterial.getCaseId());
        if (cj == null) {
            throw new RuntimeException(String.format("不存在 id 为 %s 的案件", identificationMaterial.getCaseId()));
        }
        if (StrUtil.isBlank(cj.getCaseNo())) {
            throw new RuntimeException(String.format("对应的案件资料不完整, 不存在案件编号。请先完善案件资料"));
        }
        return cj;
    }
}
