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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.config.ConfigureBuilder;
import com.deepoove.poi.data.PictureType;
import com.deepoove.poi.data.Pictures;
import com.deepoove.poi.plugin.table.MultipleRowTableRenderPolicy;
import digital.laboratory.platform.common.core.constant.CommonConstants;
import digital.laboratory.platform.common.core.constant.OSSDirectoryConstants;
import digital.laboratory.platform.common.core.exception.CheckedException;
import digital.laboratory.platform.common.core.exception.ValidateCodeException;
import digital.laboratory.platform.common.core.util.ClassUtils;
import digital.laboratory.platform.common.core.util.R;
import digital.laboratory.platform.common.feign.RemoteGenerateWordService;
import digital.laboratory.platform.common.feign.RemoteWord2PDFService;
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.constant.EntrustMarkConstants;
import digital.laboratory.platform.entrustment.convert.DrugLiteConvert;
import digital.laboratory.platform.entrustment.dto.EntrustmentDTO;
import digital.laboratory.platform.entrustment.entity.*;
import digital.laboratory.platform.entrustment.enums.AnalysisOptionEnums;
import digital.laboratory.platform.entrustment.enums.EntrustAlterApplyStatus;
import digital.laboratory.platform.entrustment.enums.EntrustmentStatusConstants;
import digital.laboratory.platform.entrustment.handler.AppStartupRunner;
import digital.laboratory.platform.entrustment.mapper.EntrustmentMapper;
import digital.laboratory.platform.entrustment.misc.ProcessFlowMapper;
import digital.laboratory.platform.entrustment.service.*;
import digital.laboratory.platform.entrustment.vo.EntrustmentIdentificationMaterialVO;
import digital.laboratory.platform.entrustment.vo.EntrustmentVO;
import digital.laboratory.platform.entrustment.vo.MaterialListForBookVo;
import digital.laboratory.platform.sewage.dto.StatisticsDiffStatusJobDTO;
import digital.laboratory.platform.sewage.entity.UpdateInfo;
import digital.laboratory.platform.sewage.feign.RemoteSewageJobService;
import digital.laboratory.platform.sewage.utils.QRCodeUtils;
import digital.laboratory.platform.sys.entity.Deliverer;
import digital.laboratory.platform.sys.entity.DrugLite;
import digital.laboratory.platform.sys.entity.SysOrg;
import digital.laboratory.platform.sys.entity.SysUser;
import digital.laboratory.platform.sys.entity.entrustment.Sample;
import digital.laboratory.platform.sys.feign.*;
import digital.laboratory.platform.sys.vo.entrustment.MarkersVO;
import feign.Response;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.activation.MimetypesFileTypeMap;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;
import java.security.Principal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * 委托服务实现类
 * <p>
 * =====================================================================================================================
 * 这个类与 Controller 类似乎功能差不多。我们原则上规定:
 * 本类的功能主要从技术角度考虑, 而 Controller 类主要从业务角度考虑。
 * 本类的功能主要是涉及 Entrustment 实体本身, 而 Controller 类则是综合的。
 * 例如, 进入到下一环节这个功能, 在本类中只考虑 Entrustment 本身的数据更新, Controller 类应该考虑更多的业务上的综合变化(如其他数据的变化)
 * <p>
 * 流程的管理被看作是 Entrustment 的一部分, 也在此处处理。Controller 不用关心流程
 * =====================================================================================================================
 *
 * @author Zhang Xiaolong created at  2022-03-22
 * @describe 委托服务实现类
 */
@Slf4j
@Service
public class EntrustmentServiceImpl extends ServiceImpl<EntrustmentMapper, Entrustment> implements EntrustmentService {
    @Resource
    private RemoteSewageJobService remoteSewageJobService;
    @Resource
    private EntrustAlterApplyService entrustAlterApplyService;
    @Resource
    private RemoteUserService remoteUserService;
    @Resource
    private CaseEventService caseEventService;
    @Resource
    private CaseEvidenceService caseEvidenceService;
    @Resource
    private EntrustmentIdentificationMaterialService entrustmentIdentificationMaterialService;
    @Resource
    private SynchronizeDataService synchronizeDataService;
    @Resource
    private SynchronizeMaterialVoService synchronizeMaterialVoService;
    @Resource
    private RemoteGenerateWordService remoteGenerateWordService;
    @Resource
    private RemoteSampleService remoteSampleService;
    @Resource
    private OssFile ossFile;

    @Resource
    private RemoteDeliverService remoteDeliverService;
    @Resource
    private RemoteOrgService remoteOrgService;

    @Resource
    private RemoteWord2PDFService remoteWord2PDFService;

    @Resource
    private IdentificationService identificationService;

    @Resource
    private SampleService sampleService;

    @Resource
    private RemoteHairJobService remoteHairJobService;

    @Resource
    private RemoteAcceptanceService remoteAcceptanceService;

    @Resource
    private RemoteFeatureAnalysis remoteFeatureAnalysis;

    @Resource
    private EntrustApproveRecordService entrustApproveRecordService;

    @Resource
    private CommonFeignService commonFeignService;


//	/**
//	 * 审核人员由委托创建者选择。如果 true, 前台在委托提交审核前, 弹出界面让委托人选择审核者; 如果 false, 由系统自动选择审核者。
//	 * 如果 singleOperateUser 为 true, 表示只能有一个候选; singleOperateUser 为 false 表示可以有多个候选。
//	 * singleOperateUser 决定了委托人选择审核者时是单选还是多选, 如果由系统自动选, 有多个待选用户时, 随机选择一个
//	 */
//	@Value("${dlp.entrustment.clientChoiceCheckers}")
//	private boolean clientChoiceCheckers;
//	/**
//	 * 如果多人审核, 审核候选人之一需要进行一个“领取任务”操作, 先占有这个任务, 此后, 其他候选人无法再“领取”该任务。已经领取任务的人, 可以进行一些处理后, 决定通过或不通过该任务
//	 */
//	@Value("${dlp.entrustment.singleOperateUser}")
//	private boolean singleOperateUser;          // 为 true, 表示审核审批候选人只有一个
//	@Value("${dlp.entrustment.processDefinitionId}")
//	private String processDefinitionId;         // 委托受理流程的 流程定义Id


    //	/**
//	 * ## 委托编码
//	 * 用于标识每一次委托。
//	 * 有可能一个案件会有多次委托鉴定, 所以在案件编码后加4位作为顺序号。
//	 *
//	 * ```
//	 * WT <案件编码后 22 位> <顺序号4位>
//	 * 例如:
//	 * WT 5201010400002020030002 0002
//	 * 合计 28 位
//	 * ```
//	 * @param caseNo
//	 * @return
//	 */
//	@Override
//	public String getNewEntrustmentNo(String caseNo) {
//		String prefix = CommonConstants.CODE_PREFIX_ENTRUSTMENT + StrUtil.removePrefixIgnoreCase(caseNo, CommonConstants.CODE_PREFIX_CASE);
//
//		int newCount = 1;
//
//		// 根据前缀查询最大委托编码
//		String maxno = entrustmentMapper.getMaxEntrustmentNo(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("%06d", newCount);
//
//		return newCode;
//	}
    //新委托编号规则
    //2023-07-09 调整检材编号规则，规则为年份+委托流水号，流水号为4位，不需要用0补充不足的位数，中间用 “-”相连接
    //2024-9-9 贵阳市局需求，不需要用0补位了
    @Override
    public String getNewEntrustmentNo() {
        LocalDateTime date = LocalDateTime.now();
        String prefix = CommonConstants.CODE_PREFIX_ENTRUSTMENT;
        String splitSymbol = "-";
        String first_part = prefix + splitSymbol + date.getYear();
        String maxNo = this.getBaseMapper().getMaxEntrustmentNoNew(first_part);
        String newWtNO;
        if (StringUtils.isNotBlank(maxNo)) {
            maxNo = maxNo.substring(maxNo.lastIndexOf("-") + 1);
            int newCount = Integer.parseInt(maxNo) + 1;
//            String second_part = fillByZero(newCount);
            newWtNO = first_part + splitSymbol + newCount;
        } else {
            newWtNO = first_part + splitSymbol + "1";
        }
        return newWtNO;
    }

    //根据年份获得委托编号
    public String getNewEntrustNoByYear(String year) {
        String prefix = CommonConstants.CODE_PREFIX_ENTRUSTMENT;
        String splitSymbol = "-";
        String first_part = prefix + splitSymbol + year;
        String maxNo = this.getBaseMapper().getMaxEntrustmentNoNew(first_part);
        String newWtNO;
        if (StringUtils.isNotBlank(maxNo)) {
            maxNo = maxNo.substring(maxNo.lastIndexOf("-") + 1);
            int newCount = Integer.parseInt(maxNo) + 1;
            String second_part = fillByZero(newCount);
            newWtNO = first_part + splitSymbol + second_part;
        } else {
            newWtNO = first_part + splitSymbol + "0001";
        }
        return newWtNO;
    }
    //获取案前送检的委托受理编号

    @Override
    public String getNewEntrustAcceptNoForBeforeCase() {
        String prefix = CommonConstants.CODE_PREFIX_ACCEPT_BEFORE_CASE;
        LocalDateTime date = LocalDateTime.now();
        String splitSymbol = "-";
        int current_year = date.getYear();
        String first_part = prefix + current_year;
        String maxAcceptNo = this.getBaseMapper().getMaxEntrustAcceptNo(first_part);
        String newAcceptNo;
        if (StringUtils.isNotBlank(maxAcceptNo)) {
            //判断跨年的情况，如果跨年肯定现在年份和之前年份不一样，如果是新的一年编号应该从新编号
            String seqNo = maxAcceptNo.substring(maxAcceptNo.lastIndexOf("-") + 1);
            int newCount = Integer.parseInt(seqNo) + 1;
            String second_part;
            second_part = fillByZero(newCount);
            newAcceptNo = first_part + splitSymbol + second_part;
        } else {
            //说明库里一条没有，则从1开始的编号
            newAcceptNo = first_part + splitSymbol + "0001";
        }
        return newAcceptNo;
    }

    //获取正常送检的委托受理编号
    @Override
    public String getNewAcceptNo() {
        LocalDateTime date = LocalDateTime.now();
        String prefix = CommonConstants.CODE_PREFIX_ACCEPT;
        String splitSymbol = "-";
        int current_year = date.getYear();
        String first_part = prefix + current_year;
        String maxAcceptNo = this.getBaseMapper().getMaxEntrustAcceptNo(first_part);

        String newAcceptNo;
        if (StringUtils.isNotBlank(maxAcceptNo)) {
            //判断跨年的情况，如果跨年肯定现在年份和之前年份不一样，如果是新的一年编号应该从新编号
            String seqNo = maxAcceptNo.substring(maxAcceptNo.lastIndexOf("-") + 1);
            int newCount = Integer.parseInt(seqNo) + 1;
//            String second_part = "";
//            second_part = fillByZero(newCount);
            newAcceptNo = first_part + splitSymbol + newCount;
        } else {
            //说明库里一条没有，则从1开始的编号
            newAcceptNo = first_part + splitSymbol + "1";
        }
        return newAcceptNo;
    }

    /**
     * 用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 + "";
        }
    }

    @Override
    public IPage<EntrustmentVO> getEntrustmentVOPage(IPage<Entrustment> page, QueryWrapper<Entrustment> qw) {
        IPage<EntrustmentVO> r = baseMapper.getEntrustmentVOPage(page, qw);

        for (EntrustmentVO evo : r.getRecords()) {
            int status = evo.getStatus();
            String statusDesc = EntrustmentStatusConstants.getStatusDescription(status);
            evo.setStatusDescription(statusDesc);

            int prevStatus = evo.getPreviousStatus();
            String prevStatusDesc = EntrustmentStatusConstants.getStatusDescription(prevStatus);
            evo.setPreviousStatusDescription(prevStatusDesc);
        }
        return r;
    }

    @Override
    public List<EntrustmentVO> getEntrustmentVOList(QueryWrapper<Entrustment> qw) {
        List<EntrustmentVO> r = baseMapper.getEntrustmentVOList(qw);

        for (EntrustmentVO evo : r) {
            evo.setStatusDescription(EntrustmentStatusConstants.getStatusDescription(evo.getStatus()));
            evo.setPreviousStatusDescription(EntrustmentStatusConstants.getStatusDescription(evo.getPreviousStatus()));
        }
        return r;
    }

    @Override
    public EntrustmentVO getEntrustmentVOById(String id) {
        EntrustmentVO evo = baseMapper.getEntrustmentVOById(id);
        evo.setHappenTime(LocalDateTimeUtil.format(caseEventService.getById(evo.getCaseId()).getHappenTime(), "yyyy年MM月dd日"));
        evo.setStatusDescription(EntrustmentStatusConstants.getStatusDescription(evo.getStatus()));
        evo.setPreviousStatusDescription(EntrustmentStatusConstants.getStatusDescription(evo.getPreviousStatus()));
        return evo;
    }


    @Override
    public long countByCaseId(String caseId) {
        return baseMapper.selectCount(Wrappers.<Entrustment>query()
                .eq(StrUtil.isNotBlank(caseId), "case_id", caseId)
        );

    }

    @Override
    public void Entrustment2Word(EntrustmentVO ev) throws IOException {
        XWPFTemplate template = XWPFTemplate.compile("jdwts.docx").render(ev);

        FileOutputStream out = new FileOutputStream("out_example_jdwts.docx");
        template.write(out);

        out.flush();
        out.close();
        template.close();
    }

    /**
     * 清除案件送检受理的数据
     */
    @Override
    public void initCaseSendAccept() {
        List<CaseEvent> caseEventList = caseEventService.list();
        List<Entrustment> entrustmentList = this.list();
        List<EntrustOfThirdSys> entrustOfThirdSysList = synchronizeDataService.list();
        for (CaseEvent caseEvent : caseEventList) {
            caseEvidenceService.remove(Wrappers.<CaseEvidence>query().eq("case_id", caseEvent.getId()));
            caseEventService.removeById(caseEvent);
            System.out.println("删除案件-----" + caseEvent.getCaseName());
        }
        for (Entrustment entrustment : entrustmentList) {
            entrustmentIdentificationMaterialService.remove(Wrappers.<EntrustmentIdentificationMaterial>query().eq("entrustment_id", entrustment.getId()));
            this.removeById(entrustment);
            System.out.println("删除委托-----" + entrustment.getId());
        }
        //第三方系统的数据，也清理掉
        entrustOfThirdSysList.forEach(item -> {
            synchronizeMaterialVoService.remove(Wrappers.<EntrustMaterialOfThirdSys>query()
                    .eq("entrust_id", item.getId()));
            synchronizeDataService.removeById(item);
            System.out.println("删除第三方委托" + item.getId());
        });

    }

    @Override
    public Boolean generateIdentifyItemsBook(String entrustId) {
        Entrustment entrustment = this.getOne(Wrappers.<Entrustment>query().eq("id", entrustId));
        // 标记该委托是否已经受理
        int isAccepted = entrustment.getStatus().compareTo(EntrustmentStatusConstants.ENTRUSTMENT_STATUS_ACCEPTED.getStatus());
        List<EntrustmentIdentificationMaterial> materialList = entrustmentIdentificationMaterialService.list(Wrappers.<EntrustmentIdentificationMaterial>lambdaQuery()
                .eq(EntrustmentIdentificationMaterial::getEntrustmentId, entrustId)
                .orderByAsc(isAccepted != -1, EntrustmentIdentificationMaterial::getAcceptNo)
                .orderByAsc(isAccepted == -1, EntrustmentIdentificationMaterial::getOrderNo));
        if (isAccepted != -1) {
            // 受理过的才进行排序，否则采用检材编号排序
            Collections.sort(materialList, new Comparator<EntrustmentIdentificationMaterial>() {
                @Override
                public int compare(EntrustmentIdentificationMaterial o1, EntrustmentIdentificationMaterial o2) {
                    return Integer.parseInt(o1.getAcceptNo().split("-")[2]) - Integer.parseInt(o2.getAcceptNo().split("-")[2]);
                }
            });
        }
        CaseEvent caseEvent = caseEventService.getOne(Wrappers.<CaseEvent>query()
                .eq("id", entrustment.getCaseId()));
        String entrustmentNo = entrustment.getEntrustmentNo();
        String templatePath = OSSDirectoryConstants.IDENTIFY_BOOK_DIRECTORY + "/" + entrustment.getId() + "/" + "鉴定事项确认书-" + entrustmentNo;
        String templateName = AppStartupRunner.getCfg(CommonConstants.DLP_CODE_ENTRUSTMENT_IDENTIFY_ITEMS_CONFIRM_LETTER_TEMPLATE);
        String originalFilename = "鉴定事项确认书-" + entrustmentNo;
        String fileType = ".docx";
        String QRContent = entrustmentNo;
        List<String> listNameCollection = new ArrayList<>();
        listNameCollection.add("materialList");
        listNameCollection.add("drugList");
        listNameCollection.add("materialAList");
        listNameCollection.add("materialRList");
        //把筛查物列表转为一行字符串
        entrustmentIdentificationMaterialService.conformityDrugs(materialList);
        Map<String, Object> data = generateIdentifyItemsData(caseEvent, entrustment, materialList, isAccepted);
        R ret = remoteGenerateWordService.generateWord(templateName, originalFilename, templatePath, fileType, QRContent, listNameCollection, false, data);
        if (ret.getCode() == 0) {
            System.out.println("鉴定事项书生成完毕...........................");
            return true;
        } else {
            return false;
        }
    }
    //下面是生成鉴定事项确认书需要的一系列方法

    /**
     * 构造鉴定事项确认书的数据
     *
     * @param caseEvent
     * @param entrustment
     * @param materialList
     * @param isAccepted   -1 未受理，0 1 受理之后的状态
     * @return
     */
    private Map<String, Object> generateIdentifyItemsData(CaseEvent caseEvent, Entrustment entrustment, List<EntrustmentIdentificationMaterial> materialList, int isAccepted) {
        Map<String, Object> dm = new HashMap<>();
        //构建案件部分需要的参数值
        dm.put("caseName", caseEvent.getCaseName());
        dm.put("caseNo", caseEvent.getThirdPartySysNo());
        dm.put("caseBrief", caseEvent.getCaseBrief());
        //构造委托部分需要的数据
        dm.put("clientOrgName", entrustment.getClientOrgName());//委托单位
        // 如果受理编号不为空，则生成[xxxx]x号，比如2025-8 -》 [2025]8号
        if (StrUtil.isNotBlank(entrustment.getAcceptNo())) {
            List<String> split = StrUtil.split(entrustment.getAcceptNo(), "-");
            dm.put("identificationNo", String.format("[%s]%s号", split.get(0), split.get(1)));//受理编号
        }
//        dm.put("identificationNo", entrustment.getAcceptNo());//受理编号
        dm.put("year", entrustment.getEntrustmentTime() != null ? entrustment.getEntrustmentTime().getYear() : LocalDate.now().getYear());

        dm.put("materialDes", buildMaterialDes(materialList));//检材描述
        dm.put("identifyReq", entrustment.getEntrustRequirement());//鉴定要求
        dm.put("identifyMethod", "委托鉴定单位未指定");//鉴定方法
        dm.put("oldIdentfyStatus", entrustment.getOldIdentificationResult());//原鉴定情况
        dm.put("identitfyLimit", "鉴定受理之日起15个工作日（检材疑难、复杂或数量较大的，或另有规定的除外）。");//鉴定时限
        dm.put("giveWay", changePublishWayToZhCn(entrustment.getReportReceiveMode()));//文书方法方式
        dm.put("disposalWay", getMaterialDisposalWay());//检材处置方式
        dm.put("deliverStatement", "本人及所属委托鉴定单位忠于案（事）件事实，保证检材及相关资料真实、合法，如有虚假，由本人及所属委托鉴定单位承担相关法律责任。");//送检人声明
        dm.put("sendDate", LocalDateTimeUtil.format(entrustment.getDeliverTime(), "yyyy年MM月dd日"));//送检日期
        dm.put("identityStatement", "本鉴定机构工作遵循公正独立、程序规范、方法科学、结论准确的原则，严格履行质量承诺。");//鉴定机构声明
        dm.put("materialList", getMaterialBookVoList(materialList));//检材列表
        //设置取样方法
        dm.put("samplingMethod", getSamplingMethod(materialList));
        dm.put("drugList", getDrugNameList(materialList));//毒品筛查列表
        //构建送检人1的信息
        dm.put("deliverer1Name", entrustment.getDeliverer1Name());//姓名
        dm.put("deliverer1Position", entrustment.getDeliverer1Position());//职务
        dm.put("deliverer1Cert", entrustment.getDeliverer1Cert());//证件类型
        dm.put("deliverer1Id", entrustment.getDeliverer1Id());//证件号码
        dm.put("deliverer1Phone", entrustment.getDeliverer1Phone());//电话号码
        //构建送检人2的信息
        dm.put("deliverer2Name", entrustment.getDeliverer2Name());//姓名
        dm.put("deliverer2Position", entrustment.getDeliverer2Position());//职务
        dm.put("deliverer2Cert", entrustment.getDeliverer2Cert());//证件类型
        dm.put("deliverer2Id", entrustment.getDeliverer2Id());//证件号码
        dm.put("deliverer2Phone", entrustment.getDeliverer2Phone());//电话号码

        //设置流转单得属性值
        dm.put("materialACount", getCountForAnyRet(materialList, "A").size());//分析样检材总的份数
        dm.put("materialRCount", getCountForAnyRet(materialList, "R").size());//留存样检材总的份数

        dm.put("materialAList", getCountForAnyRet(materialList, "A"));//留存样检材总的份数
        dm.put("materialRList", getCountForAnyRet(materialList, "R"));//留存样检材总的份数

        dm.put("materialMount", getAllMaterialMount(materialList, "A"));//检材总的质量-分析样
        dm.put("materialMount1", getAllMaterialMount(materialList, "R"));//检材总的质量-留存样
        // 填充受理数据
        if (isAccepted != -1) {
            R<SysUser> sysUserR = remoteUserService.innerGetById(entrustment.getAcceptUser());
            String acceptName = sysUserR.getData().getName();
            dm.put("acceptDate", LocalDateTimeUtil.format(entrustment.getAcceptTime(), "yyyy年MM月dd日"));//受理日期
            dm.put("acceptName", acceptName);
            dm.put("ac_yy", entrustment.getAcceptTime().getYear());//受理年
            dm.put("ac_mm", entrustment.getAcceptTime().getMonthValue());//受理月
            dm.put("ac_day", entrustment.getAcceptTime().getDayOfMonth());//受理日
        }
        dm.put("value1", "☑");//受理日
        //条形码  因为调用feign接口的原因，图片传输过程中会受影响，这里改为在生成的地方再生成
        return dm;
    }


    //文书发放方式转中文
    private String changePublishWayToZhCn(String flag) {
        String ret;
        switch (flag) {
            case "0":
                ret = "自取";
                break;
            case "2":
                ret = "邮政专递EMS(到付)";
                break;
            case "3":
                ret = "机要寄递";
                break;
            default:
                ret = "未指定方式";
                break;
        }
        return ret;
    }

    /**
     * 分别求分析样是多少份，留存样是多少份
     *
     * @param materialList
     * @param flag
     * @return
     */
    private List<EntrustmentIdentificationMaterial> getCountForAnyRet(List<EntrustmentIdentificationMaterial> materialList, String flag) {
        List<EntrustmentIdentificationMaterial> anList = materialList.stream().filter(item -> {
            //不能使用复称的值来判断分析样了，因为有可能不复称
//			if(item.getSample1RepeatWeigh()!=null&&item.getSample1RepeatWeigh().compareTo(BigDecimal.ZERO)>0)
//			{
//				return true;
//			}else {
//				return false;
//			}
            if (item.getSample1Quantity() != null && item.getSample1Quantity().compareTo(BigDecimal.ZERO) > 0) {
                return true;
            } else {
                return false;
            }
        }).collect(Collectors.toList());
        List<EntrustmentIdentificationMaterial> rtList = materialList.stream().filter(item -> {
//			if(item.getSample2RepeatWeigh()!=null&&item.getSample2RepeatWeigh().compareTo(BigDecimal.ZERO)>0)
//			{
//				return true;
//			}else {
//				return false;
//			}
            if (item.getSample2Quantity() != null && item.getSample2Quantity().compareTo(BigDecimal.ZERO) > 0) {
                return true;
            } else {
                return false;
            }
        }).collect(Collectors.toList());
        if (flag.equals("A")) {
            return anList;
        } else {
            return rtList;
        }
    }

    //返回取样方法的描述
    private String getSamplingMethod(List<EntrustmentIdentificationMaterial> materialList) {
        int anCount = getCountForAnyRet(materialList, "A").size();
        int reCount = getCountForAnyRet(materialList, "R").size();
        String ret;
        if (anCount > 0 & reCount > 0) {
            ret = "将检材分装为分析样、留存样";
        } else if (anCount > 0) {
            ret = "检材全部为分析样";
        } else {
            ret = "检材全部为留存样";
        }
        return ret;
    }

    /**
     * 构造封装质量
     *
     * @param materialList
     * @param flag
     * @return
     */
    private BigDecimal getAllMaterialMount(List<EntrustmentIdentificationMaterial> materialList, String flag) {
        BigDecimal mount1 = new BigDecimal(0);
        BigDecimal mount2 = new BigDecimal(0);
        for (EntrustmentIdentificationMaterial item : materialList) {
            //如果有复称质量，取复称质量，如果没有就取sample的质量
            if (item.getSample1RepeatWeigh() != null) {
                mount1 = mount1.add(item.getSample1RepeatWeigh());
                //如果单位不是克或者毫克，就无法统计总质量
            } else {
                if (item.getUnit().equals("克")) {
                    mount1 = mount1.add(item.getSample1Quantity());
                }
                if (item.getUnit().equals("毫克")) {
                    mount1 = mount1.add(item.getSample1Quantity().multiply(new BigDecimal(1000)));
                }
            }
            if (item.getSample2RepeatWeigh() != null) {
                mount2 = mount2.add(item.getSample2RepeatWeigh());
            } else {
                if (item.getUnit().equals("克")) {
                    mount2 = mount2.add(item.getSample2Quantity());
                }
                if (item.getUnit().equals("毫克")) {
                    mount2 = mount2.add(item.getSample2Quantity().multiply(new BigDecimal(1000)));
                }
            }
        }
        if (flag.equals("A"))//分析样
        {
            return mount1;
        } else if (flag.equals("R"))//留存样
        {
            return mount2;
        } else {
            return mount1.add(mount2);//分析样+留存样
        }
    }

    //构造鉴定事项确认书文书中的检材列表
    private List<MaterialListForBookVo> getMaterialBookVoList(List<EntrustmentIdentificationMaterial> materialList) {
        List<MaterialListForBookVo> materialListForBookVoList = new ArrayList<>();
        materialList.forEach(item -> {
            MaterialListForBookVo eg = getMaterialListForBookVo(item);
            materialListForBookVoList.add(eg);
        });
        return materialListForBookVoList;
    }

    private MaterialListForBookVo getMaterialListForBookVo(EntrustmentIdentificationMaterial item) {
        MaterialListForBookVo eg = new MaterialListForBookVo();
        eg.setAcceptNo(item.getAcceptNo());
        eg.setIndexNo(item.getShortNameDes() + "检材");
        eg.setMaterialName(item.getName());
        // 先暂时去掉这个功能，他们可能
        //eg.setFormName(StringUtils.isNotBlank(item.getColor()) ? item.getColor() + item.getFormName() : "" + item.getFormName());
        eg.setFormName(item.getFormName());
        eg.setSpecies(item.getTypeName());
        eg.setPackComplete(item.getPackComplete());
        eg.setDrugsValue(item.getDrugsValue());
        eg.setRtSampleQuantity(item.getRtSampleQuantity());
        eg.setRemark(item.getRemark());
        eg.setOrderNo(item.getOrderNo());
        BigDecimal totalSampleMass = calculateTotalSampleMass(item, eg);

        // 根据 totalSampleMass 大小来决定保留的小数位数
        if (totalSampleMass.compareTo(new BigDecimal(100)) >= 0) {
            // 如果 totalSampleMass 大于 100，保留 1 位小数
            eg.setTotalSampleDes(totalSampleMass.setScale(1, BigDecimal.ROUND_HALF_UP) + item.getUnit());
        } else {
            // 否则保留 2 位小数
            eg.setTotalSampleDes(totalSampleMass.setScale(2, BigDecimal.ROUND_HALF_UP) + item.getUnit());
        }
        return eg;
    }

    private BigDecimal calculateTotalSampleMass(EntrustmentIdentificationMaterial item, MaterialListForBookVo eg) {
        BigDecimal totalSampleMass = BigDecimal.ZERO;
        //因为现在有的检材可以不用复称，例如送来的一支电子烟，所以我们用送检的数量与单位进行描述即可
        if (item.getSample1RepeatWeigh() == null || item.getSample1RepeatWeigh().compareTo(BigDecimal.ZERO) == 0) {
            eg.setAnalysisSampleDes(item.getSample1Quantity() + item.getUnit());
            totalSampleMass = item.getSample1Quantity();
            if (item.getSample2Present()) {
                eg.setRetainedSampleDes(item.getSample2Quantity() + item.getUnit());
                totalSampleMass.add(item.getSample2Quantity());
            } else {
                eg.setRetainedSampleDes(new BigDecimal(0) + item.getUnit());
            }
//                eg.setTotalSampleDes(totalSampleMass.setScale(2, BigDecimal.ROUND_HALF_UP) + item.getUnit());
        } else {
            eg.setAnalysisSampleDes(item.getSample1RepeatWeigh() + item.getUnit());
            eg.setRetainedSampleDes(item.getSample2RepeatWeigh() + item.getUnit());
//                eg.setTotalSampleDes(
//                        (item.getSample1RepeatWeigh() == null ? new BigDecimal(0) : item.getSample1RepeatWeigh())
//                        .add(
//                                item.getSample2RepeatWeigh() == null ? new BigDecimal(0) : item.getSample2RepeatWeigh()
//                        )
//                        .setScale(2, BigDecimal.ROUND_HALF_UP)
//                        + "克"
//                );
            totalSampleMass = (item.getSample1RepeatWeigh() == null ? BigDecimal.ZERO : item.getSample1RepeatWeigh())
                    .add(item.getSample2RepeatWeigh() == null ? BigDecimal.ZERO : item.getSample2RepeatWeigh());
        }
        return totalSampleMass;
    }
    //构造鉴定委托书文书中的检材列表

    //检材处置方式
    private List<String> getMaterialDisposalWay() {
        List<String> retList = new ArrayList<>();
        retList.add("1.将体外检材（缴获物）分装为分析样（用于鉴定）和留存样（封存备查），并保证该两份样本之间的一致性。检材不足或不能分装时全部取为分析样，无留存样。");
        retList.add("2.除非特别约定，体内检材（生物样本）不分装，全部取为分析样，无留存样。");
        retList.add("3.鉴定完毕后检材不退回，委托鉴定单位需要保留物证时请勿全部送检。");
        return retList;
    }

    /**
     * 构建检材描述和鉴定要求
     *
     * @param materialList
     * @return
     */
    @Override
    public String buildMaterialDes(List<EntrustmentIdentificationMaterial> materialList) {
        //形状+包装
        Map<String, List<EntrustmentIdentificationMaterial>> retGroup = materialList.stream().collect(Collectors.groupingBy(item -> item.getFormName() + item.getPackName()));
        StringBuffer retSb = new StringBuffer();
        retGroup.forEach((k, v) -> {
            EntrustmentIdentificationMaterial materialObj = v.get(0);
            String typeName;
            if (materialObj.getTypeName().equals("inVitro")) {
                typeName = "常规毒品";
            } else if (materialObj.getTypeName().equals("inVivo")) {
                typeName = "生物样本";
            } else {
                typeName = "其他样本";
            }
            String des = materialObj.getColor() + materialObj.getFormName() + typeName + v.size() + "份," + materialObj.getPackName() + "包装";
            retSb.append(des).append(",");
        });
        retSb.delete(retSb.length() - 1, retSb.length());
        return retSb.toString();
    }

    //构建鉴定要求  //返回鉴定要求//设置为接口方法，其他地方可能会使用
    @Override
    public String buildIdentfyReq(List<EntrustmentIdentificationMaterial> materialList) {
        Map<String, List<EntrustmentIdentificationMaterial>> retGroup = materialList.stream().collect(Collectors.groupingBy(item -> item.getAnalysisOption() + "_" + getDrugNameMsg(item.getCandidateDrugs())));
        List<String> desList = new ArrayList<>();
        StringBuffer retSb = new StringBuffer();
        retGroup.forEach((k, v) -> {
            retSb.append(getNameDesStr(v)).append(",");
        });
        retSb.delete(retSb.length() - 1, retSb.length());
        return retSb.toString();
    }

    @Override
    public String buildEntrustReq(List<EntrustmentIdentificationMaterial> materialList) {
        StringBuilder retSb = new StringBuilder();
        if (materialList.size() == 1) {
            EntrustmentIdentificationMaterial material = materialList.get(0);
            retSb.append("对检材中是否含有")
                    .append(
                            DrugLiteConvert.joiningDrugListNameToStr(material.getCandidateDrugs(), "、")
                    )
                    .append("成分进行")
                    .append(AnalysisOptionEnums.fromCode(material.getAnalysisOption()).getChineseName())
                    .append("检测");
        } else {
            Map<String, List<EntrustmentIdentificationMaterial>> retGroup = materialList
                    .stream()
                    .collect(
                            Collectors.groupingBy(item ->
                                            item.getAnalysisOption() +
                                                    "_" +
                                                    DrugLiteConvert.joiningDrugListNameToStr(item.getCandidateDrugs(), ""),
                                    LinkedHashMap::new, // 返回有序map
                                    Collectors.toList())
                    );
            if (retGroup.keySet().size() == 1) {
                EntrustmentIdentificationMaterial material = materialList.get(0);
                retSb.append("对1号至")
                        .append(materialList.size())
                        .append("号检材中是否含有")
                        .append(DrugLiteConvert.joiningDrugListNameToStr(material.getCandidateDrugs(), "、"));
                retSb.append("成分进行")
                        .append(AnalysisOptionEnums.fromCode(material.getAnalysisOption()).getChineseName())
                        .append("检测");
                return retSb.toString();
            } else {
                //先给group排一个序
                List<Map.Entry<String, List<EntrustmentIdentificationMaterial>>> orderedDataList =
                        orderAnalysisOptionAndDrug(retGroup);
                //开始构建
                for (Map.Entry<String, List<EntrustmentIdentificationMaterial>> mapping : orderedDataList) {
                    retSb.append(getNameDesStrForEntrust(mapping.getValue())).append(",");
                }
                retSb.delete(retSb.length() - 1, retSb.length());
            }
        }
        return retSb.toString();
    }

    //对分析项目+目标物的组合进行排序，优先描述小的
    private List<Map.Entry<String, List<EntrustmentIdentificationMaterial>>> orderAnalysisOptionAndDrug(Map<String, List<EntrustmentIdentificationMaterial>> targetMapData) {
        List<Map.Entry<String, List<EntrustmentIdentificationMaterial>>> retList =
                new ArrayList<Map.Entry<String, List<EntrustmentIdentificationMaterial>>>(targetMapData.entrySet());
        Collections.sort(retList, new Comparator<Map.Entry<String, List<EntrustmentIdentificationMaterial>>>() {
            @Override
            public int compare(Map.Entry<String, List<EntrustmentIdentificationMaterial>> o1,
                               Map.Entry<String, List<EntrustmentIdentificationMaterial>> o2) {
                //我们将这个数组进行排序，选出时间最早的
                EntrustmentIdentificationMaterial m1 = getMinMaterial(o1.getValue()).get(0);
                EntrustmentIdentificationMaterial m2 = getMinMaterial(o2.getValue()).get(0);
                return m1.getCreateTime().compareTo(m2.getCreateTime());
            }
        });
        return retList;
    }

    //对检材排序，找出最早录入的
    private List<EntrustmentIdentificationMaterial> getMinMaterial(List<EntrustmentIdentificationMaterial> targetList) {
        Collections.sort(targetList, new Comparator<EntrustmentIdentificationMaterial>() {
            @Override
            public int compare(EntrustmentIdentificationMaterial o1, EntrustmentIdentificationMaterial o2) {
                return o1.getCreateTime().compareTo(o2.getCreateTime());
            }
        });
        return targetList;
    }

    private String getDrugNameMsg(List<DrugLite> drugLites) {
        StringBuilder sb = new StringBuilder();
        for (DrugLite lite : drugLites) {
            DrugLite drugLite = (DrugLite) JSONObject.toJavaObject(JSONObject.parseObject(JSONObject.toJSONString(lite)), DrugLite.class);
            sb.append(drugLite.getName());
        }
        return sb.toString();
    }

    public String getNameDesStr(List<EntrustmentIdentificationMaterial> targetList) {
        //格式
        //对 xx号，xx号检材中的xx1、xx2进行 xx 分析,
        //对1号、2号检材中的海洛因、甲基苯丙胺进行定量分析
        // 1.定性，2.定量 3.定性定量 4.关联性性 5.其他
        StringBuffer sbMaterialName = new StringBuffer();
        StringBuffer sbDrugDes = new StringBuffer();
        StringBuffer sbAnalysisDes = new StringBuffer();
        int executeCount = 0;
        for (EntrustmentIdentificationMaterial materialObj : targetList) {
            sbMaterialName.append(materialObj.getShortNameDes()).append(",");
            //只执行一次且执行一次
            if (executeCount == 0) {
                List<DrugLite> drugLiteList = DrugLiteConvert.convertDirtyLiteByJSON(materialObj.getCandidateDrugs());
                drugLiteList.forEach(item -> {
                    sbDrugDes.append(item.getName()).append("、");
                });
                sbDrugDes.delete(sbDrugDes.length() - 1, sbDrugDes.length());//删除多余的连接号
                sbAnalysisDes.append(AnalysisOptionEnums.fromCode(materialObj.getAnalysisOption()).getChineseName());
            }
            executeCount++;
        }
        sbMaterialName.delete(sbMaterialName.length() - 1, sbMaterialName.length());
        String req1 = "对" + sbMaterialName.toString() + "检材中的";
        String req2 = sbDrugDes.toString();
        String req3 = "进行" + sbAnalysisDes.toString() + "分析";
        return req1 + req2 + req3;
    }

    public String getNameDesStrForEntrust(List<EntrustmentIdentificationMaterial> targetList) {
        //格式
        //对 xx号，xx号检材中的xx1、xx2进行 xx 分析,
        //对1号、2号检材中的海洛因、甲基苯丙胺进行定量分析
        // 1.定性，2.定量 3.定性定量 4.关联性性 5.其他
        StringBuffer sbMaterialName = new StringBuffer();
        StringBuffer sbDrugDes = new StringBuffer();
        StringBuffer sbAnalysisDes = new StringBuffer();
        int executeCount = 0;
        for (EntrustmentIdentificationMaterial materialObj : targetList) {
            sbMaterialName.append(materialObj.getOrderNo1()).append(",");
            //只执行一次且执行一次
            if (executeCount == 0) {
//                String drugToString = JSONArray.toJSONString(materialObj.getCandidateDrugs());
                List<DrugLite> drugLiteList = DrugLiteConvert.convertDirtyLiteByJSON(materialObj.getCandidateDrugs());
                drugLiteList.forEach(item -> {
                    sbDrugDes.append(item.getName()).append("、");
                });
                sbDrugDes.delete(sbDrugDes.length() - 1, sbDrugDes.length());//删除多余的连接号
                sbAnalysisDes.append(AnalysisOptionEnums.fromCode(materialObj.getAnalysisOption()).getChineseName());
            }
            executeCount++;
        }

        sbMaterialName.delete(sbMaterialName.length() - 1, sbMaterialName.length());
        String req1 = "对" + sbMaterialName.toString() + "中是否含有";
        String req2 = sbDrugDes.toString();
        // 20250107 自动生成的鉴定要求，去掉分析两个字现在是定性分析检测
        String req3 = "成分进行" + sbAnalysisDes.toString() + "检测";
        return req1 + req2 + req3;
    }

    /**
     * 获取毒品筛查列表
     *
     * @param targetList
     * @return
     */
    private List<DrugLite> getDrugNameList(List<EntrustmentIdentificationMaterial> targetList) {
        List<DrugLite> retList;
        List<DrugLite> allDrugLite = new ArrayList<>();
        targetList.forEach(item -> {
            String drugToString = JSONArray.toJSONString(item.getCandidateDrugs());
            List<DrugLite> drugLiteList = JSONArray.parseArray(drugToString, DrugLite.class);
            drugLiteList.forEach(drugLite -> {
                allDrugLite.add(drugLite);
            });
        });
        retList = allDrugLite.stream().filter(distinctKey(i -> i.getName())).collect(Collectors.toList());
        return retList;
    }

    /**
     * 获取文书名称
     *
     * @param entrustId
     * @param whatBook  entrust-委托书  identItemBook-鉴定事项确认书  identfyBook-鉴定书
     * @param docType   该参数只有用于委托书上
     * @return
     */
    @Override
    public String getBookNameByEntrustId(String entrustId, String whatBook, String docType) {
        //先判断需要的文书是否在OSS上存在，如果存在，直接返回地址，如果不存在，则需要生成
        String retBookName = "";
        Entrustment entrustment = this.getById(entrustId);
        switch (whatBook) {
            case "entrust":
                retBookName = OSSDirectoryConstants.DOCUMENT_ENTRUSTMENT_DIRECTORY + "/" + entrustId + "/" + "鉴定委托书-" + entrustment.getEntrustmentNo() + ("docx".equals(docType) ? ".docx" : ".pdf");
                break;
            case "identItemBook":
                retBookName = OSSDirectoryConstants.IDENTIFY_BOOK_DIRECTORY + "/" + entrustment.getId() + "/" + "鉴定事项确认书-" + entrustment.getEntrustmentNo() + ".docx";
                break;
            case "identfyBook":
                retBookName = OSSDirectoryConstants.IDENTIFY_BOOK_DIRECTORY + "/" + entrustment.getId() + "/" + "鉴定文书-" + entrustment.getAcceptNo() + ".docx";
                break;
        }
        try {
            if (!ossFile.objectExist(retBookName) || entrustment.getStatus() <= EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_ACCEPT.getStatus()) {
                //不存在就生成一个
                if ((whatBook.equals("identItemBook") || whatBook.equals("identfyBook")) && this.generateIdentifyItemsBook(entrustId)) {
                    return retBookName;
                } else if (whatBook.equals("entrust") && GenerateEntrustmentLetterPDF(this.getEntrustmentVOById(entrustId))) {
                    return retBookName;
                } else {
                    throw new RuntimeException("生成文书【" + retBookName + "】书失败:" + entrustId);
                }
            }
        } catch (Exception exception) {
            exception.printStackTrace();
            throw new RuntimeException("生成鉴定书失败:" + exception.getMessage());
        }
        return retBookName;
    }

    /**
     * 检验完成
     *
     * @param entrustId
     * @return
     */
    @Override
    public boolean testsFinish(String entrustId) {
        Entrustment entrustment = this.baseMapper.selectOne(Wrappers.<Entrustment>query()
                .eq("id", entrustId));
        entrustment.setStatus(EntrustmentStatusConstants.ENTRUSTMENT_STATUS_TEST_FINISH.getStatus());
        return this.updateById(entrustment);
    }

    /**
     * 获取委托书各状态的数量
     *
     * @param statues
     */
    @Override
    public Integer getEntrustStatusCount(List<Integer> statues, DLPUser dlpUser) {
        if (dlpUser.isStaff()) {
            return this.list(Wrappers.<Entrustment>query().in("status", statues)).size();
        } else {
            String orgId = dlpUser.getOrgId();
            return this.list(Wrappers.<Entrustment>query()
                    .in("status", statues)
                    .eq("client_org_id", orgId)).size();
        }

    }

    @Override
    public Boolean checkDeliverPhoto(String entrustId) {
        String path = OSSDirectoryConstants.DOCUMENT_ACCEPT_DIRECTORY + "/" + entrustId + "/" + OSSDirectoryConstants.DOCUMENT_ACCEPT_DIRECTORY_DELIVER;
        List<String> fileList = ossFile.fileList(path);
        if (fileList.size() > 0) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public Boolean getDeliverMergePhoto(String entrustId, String acceptNo, String caseName, String deliverer1Name, String deliverer2Name) {
        //String path=OSSDirectoryConstants.DOCUMENT_ACCEPT_DIRECTORY+"/"+entrustId+"/"+OSSDirectoryConstants.DOCUMENT_ACCEPT_DIRECTORY_DELIVER;
        //先判断如果没有生成，我们就生成，如果生成了，我们就直接取
        return remoteGenerateWordService.genDeliverCertPhoto(entrustId, acceptNo, caseName, deliverer1Name, deliverer2Name);
    }


    @Override
    public Boolean historyDataToTransSys(String status, List<String> entrustIds) {
        log.info("参数：status={} entrustIds={}", status, entrustIds);
        List<Entrustment> historyEntrustList = this.list(Wrappers.<Entrustment>lambdaQuery()
                .eq(Entrustment::getStatus, status)
                //.eq(Entrustment::getDataSources, 1)
                .in(Entrustment::getId, entrustIds));
        System.out.println("本次同步历史数据：" + historyEntrustList.size() + "条");
        log.info("本次同步历史数据：{} 条", historyEntrustList.size());
        List<Sample> saveToTransObj = new ArrayList<>();
        historyEntrustList.forEach(item -> {
            //我们需要查出该委托对应的受理检材
            List<EntrustmentIdentificationMaterial> materialList = entrustmentIdentificationMaterialService
                    .list(Wrappers.<EntrustmentIdentificationMaterial>lambdaQuery()
                            .eq(EntrustmentIdentificationMaterial::getEntrustmentId, item.getId()));
            materialList.forEach(material -> {
                //将检材构建为sample对象，并传递到流转系统
                saveToTransObj.add(genSampleObject(material));
            });
            item.setIsTrans(1);//流转后，转变为10
        });
        System.out.println("本次检材数量：" + saveToTransObj.size() + "个");
        log.info("本次检材数量：{} 条", saveToTransObj.size());
        R r = remoteSampleService.enterSample(saveToTransObj);
        log.info("更新委托的状态：{} 条", historyEntrustList.size());
        this.updateBatchById(historyEntrustList);

        return true;
    }

    //检查委托下的检材是否复秤
    @Override
    public boolean checkRepeatWeigh(Entrustment _entrustment) {
        List<EntrustmentIdentificationMaterial> materialList = entrustmentIdentificationMaterialService.list(Wrappers.<EntrustmentIdentificationMaterial>lambdaQuery()
                .eq(EntrustmentIdentificationMaterial::getEntrustmentId, _entrustment.getId())
                .in(EntrustmentIdentificationMaterial::getUnit, "克", "毫克"));
        List<EntrustmentIdentificationMaterial> noWeighMaterialList = new ArrayList<>();
        materialList.forEach(item -> {

            if (item.getSample1RepeatWeigh() != null) {
                if (item.getSample1RepeatWeigh().compareTo(BigDecimal.ZERO) <= 0) {
                    noWeighMaterialList.add(item);
                }
            } else {
                noWeighMaterialList.add(item);
            }
            if (item.getProvidedSample2Present()) {
                //
                if (item.getSample2RepeatWeigh() != null) {
                    if (item.getSample2RepeatWeigh().compareTo(BigDecimal.ZERO) <= 0) {
                        noWeighMaterialList.add(item);
                    }
                } else {
                    noWeighMaterialList.add(item);
                }
            }
        });
        if (noWeighMaterialList.size() > 0) {
            return true;
        } else return false;
    }
    //

    @Override
    public Boolean updateImportData(String flag) {
        List<EntrustOfThirdSys> thirdSysList = synchronizeDataService.list();
        List<EntrustMaterialOfThirdSys> thirdMaterialList = synchronizeMaterialVoService.list();
        List<CaseEvent> caseUpdateList = new ArrayList<>();
        List<Entrustment> entrustUpdateList = new ArrayList<>();
        List<EntrustmentIdentificationMaterial> materialUpdateList = new ArrayList<>();

        if (flag.equals("0")) {
            thirdSysList.forEach(item -> {
                Entrustment entrustObj = this.getById(item.getEntrustMainId());
                entrustObj.setDeliverer1Phone(item.getDeliverer1Phone());
                entrustObj.setDeliverer2Phone(item.getDeliverer2Phone());
                CaseEvent caseEventObj = caseEventService.getById(entrustObj.getCaseId());
                caseEventObj.setCaseBrief(item.getCaseRemark());
                caseEventObj.setThirdPartySysNo(item.getCaseCode());
                caseUpdateList.add(caseEventObj);
                entrustUpdateList.add(entrustObj);
                //更新检材的数据
            });
            log.info("共计更新案件案情简要信息{}条", caseUpdateList.size());
            log.info("共计更新送检人电话信息{}条", entrustUpdateList.size());
            caseEventService.updateBatchById(caseUpdateList);
            this.updateBatchById(entrustUpdateList);
        }
        if (flag.equals("1")) {
            thirdMaterialList.forEach(item -> {
                EntrustmentIdentificationMaterial materialObj = entrustmentIdentificationMaterialService.getById(item.getId());
                if (item.getAmount() != null) {
                    materialObj.setSample1Quantity(item.getAmount());
                } else {
                    materialObj.setSample1Quantity(item.getAnalysisSampleAmount());
                }
                materialUpdateList.add(materialObj);
                //materialObj.setSample2Quantity(item.getRetainedSampleAmount());
            });
            log.info("共计更新检材信息 {} 条", materialUpdateList.size());
            entrustmentIdentificationMaterialService.updateBatchById(materialUpdateList);
        }

        return true;
    }

    private Sample genSampleObject(EntrustmentIdentificationMaterial material) {
        Sample sample1 = new Sample();
        sample1.setId(IdWorker.get32UUID().toUpperCase());
        sample1.setIdentificationMaterialId(material.getId());
        sample1.setSource("entrustment-history");
        //sample1.setSampleNo(entrustmentIdentificationMaterial.getSample1No());
        sample1.setSampleNo(material.getAcceptNo());
        sample1.setCandidateDrugs(material.getCandidateDrugs());
        sample1.setFundName(material.getFundName());
        sample1.setFundQuantity(material.getSample1FundQuantity());
        sample1.setFundUnit(material.getFundUnit());
        sample1.setQuantity(material.getSample1Quantity());
        sample1.setUnit(material.getUnit());
        //sample1.setAdditionalProperties(material.getAdditionalProperties());
        sample1.setDrawWay(material.getDrawWay());
        sample1.setBoxId(material.getSample1BoxId());
        //sample1.setSampleType(sb1.getSampleType());
        sample1.setStorageMethod(material.getStorageMethod());
        sample1.setAcceptTime(material.getAcceptTime());

        sample1.setSampleType("A");//设置类型
        sample1.setEntrustmentId(material.getEntrustmentId()); //设置任务ID
        sample1.setHolder("1");//设置一个初始化账户
        sample1.setOrgId("0");//机构默认为分中心
        sample1.setName(material.getName());
        sample1.setAcceptNo(material.getAcceptNo());
        return sample1;
    }

    private <T> Predicate<T> distinctKey(Function<? super T, ?> key) {
        Map<Object, Boolean> map = new ConcurrentHashMap<>();
        return t -> map.putIfAbsent(key.apply(t), Boolean.TRUE) == null;
    }

    @Override
    public Entrustment bizSubmitter_Save(Entrustment entrust, DLPUser dlpUser) {

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

        if (entrustment.getStatus() != EntrustmentStatusConstants.ENTRUSTMENT_STATUS_CREATED.getStatus()) {
            throw new RuntimeException("委托已经提交, 不能再进行修改");
        }

        System.out.println(String.format("保存委托, entrust.getCandidateDrugs()=%s", entrust.getCandidateDrugs()));


        //-- 更新送检员表的信息
        if (org.apache.commons.lang3.StringUtils.isNotBlank(entrust.getDeliverer1Name())) {
            Deliverer deliverer1 = getDeliverer1(entrust, dlpUser);
            remoteDeliverService.renew(deliverer1);
        }
        if (org.apache.commons.lang3.StringUtils.isNotBlank(entrust.getDeliverer2Name())) {
            Deliverer deliverer2 = getDeliverer2(entrust, dlpUser);
            remoteDeliverService.renew(deliverer2);
        }

        //-------------------

        if (dlpUser.isStaff() && dlpUser.HasPermission("EntrustmentAidInput")) {
            // 是代录员, clientOrgId 由用户提供
        } else {
            // 不是代录, clientOrgId 被系统强制指定为用户所属机构 id
            entrust.setClientOrgId(dlpUser.getOrgId());
        }
        //-------------------
        // 更新数据库表数据
        //-------------------
        UpdateWrapper<Entrustment> updateWrapper = new UpdateWrapper<Entrustment>();
        updateWrapper.eq("id", entrust.getId());        // 查询条件是 id 相等

        updateWrapper.set("client_org_id", entrust.getClientOrgId());
        updateWrapper.set("client_org_name", entrust.getClientOrgName());
        updateWrapper.set("client_address", entrust.getClientAddress());
        updateWrapper.set("client_postcode", entrust.getClientPostcode());
        updateWrapper.set("client_tel", entrust.getClientTel());
        updateWrapper.set("client_fax", entrust.getClientFax());
        updateWrapper.set("identification_domain", entrust.getIdentificationDomain());
        updateWrapper.set("identification_org_name", entrust.getIdentificationOrgName());
        updateWrapper.set("qualitative_analysis", entrust.getQualitativeAnalysis());
        updateWrapper.set("quantitative_analysis", entrust.getQuantitativeAnalysis());
        updateWrapper.set("other_identification_requests", entrust.getOtherIdentificationRequests());
        //updateWrapper.set("candidate_drugs", entrust.getCandidateDrugs(), "javaType=String,jdbcType=VARCHAR,typeHandler=digital.laboratory.platform.entrustment.config.StringListJsonHandler");
        updateWrapper.set("candidate_drugs", entrust.getCandidateDrugs(), "typeHandler=com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler");
        updateWrapper.set("is_client_specified_method", entrust.getIsClientSpecifiedMethod());
        updateWrapper.set("client_specified_method", entrust.getClientSpecifiedMethod());
        updateWrapper.set("destructive_analysis", entrust.getDestructiveAnalysis());
        updateWrapper.set("other_identification_notes", entrust.getOtherIdentificationNotes());
        updateWrapper.set("reidentification", entrust.getReidentification());
        updateWrapper.set("old_identification_org_name", entrust.getOldIdentificationOrgName());
        updateWrapper.set("old_identification_document", entrust.getOldIdentificationDocument());
        updateWrapper.set("old_identification_result", entrust.getOldIdentificationResult());
        updateWrapper.set("reidentification_reason", entrust.getReidentificationReason());
        updateWrapper.set("avoid_identifier", entrust.getAvoidIdentifier(), "typeHandler=com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler");
        updateWrapper.set("specified_identifier", entrust.getSpecifiedIdentifier());
        updateWrapper.set("other_agreement", entrust.getOtherAgreement());

        updateWrapper.set("identification_id", entrust.getIdentificationId());

        updateWrapper.set("report_receive_mode", entrust.getReportReceiveMode());
        updateWrapper.set("sample_receive_mode", entrust.getSampleReceiveMode());

        updateWrapper.set("comments", entrust.getComments());

//		updateWrapper.set("deliverer1_user_id", entrust.getDeliverer1UserId());
        updateWrapper.set("deliverer1_name", entrust.getDeliverer1Name());
        updateWrapper.set("deliverer1_position", entrust.getDeliverer1Position());
        updateWrapper.set("deliverer1_cert", entrust.getDeliverer1Cert());
        updateWrapper.set("deliverer1_id", entrust.getDeliverer1Id());
        updateWrapper.set("deliverer1_phone", entrust.getDeliverer1Phone());

//		updateWrapper.set("deliverer2_user_id", entrust.getDeliverer2UserId());
        updateWrapper.set("deliverer2_name", entrust.getDeliverer2Name());
        updateWrapper.set("deliverer2_position", entrust.getDeliverer2Position());
        updateWrapper.set("deliverer2_cert", entrust.getDeliverer2Cert());
        updateWrapper.set("deliverer2_id", entrust.getDeliverer2Id());
        updateWrapper.set("deliverer2_phone", entrust.getDeliverer2Phone());
        updateWrapper.set("entrustment_type", entrust.getEntrustmentType());//委托类型: 0=正常司法鉴定委托, 1=案前委托

//		updateWrapper.set("process_info", entrustment.getProcessInfo(), "typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler");
        updateWrapper.set("process_info", entrustment.getProcessInfo(), "typeHandler=com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler");

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

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

        System.out.println("AppStartupRunner.getCfg(CommonConstants.DLP_CODE_IDENTIFY_ITEMS_DEFINE_AT)=" + AppStartupRunner.getCfg(CommonConstants.DLP_CODE_IDENTIFY_ITEMS_DEFINE_AT));
        System.out.println("other str=========entrustment");
        if (StrUtil.equalsIgnoreCase(AppStartupRunner.getCfg(CommonConstants.DLP_CODE_IDENTIFY_ITEMS_DEFINE_AT), "entrustment")) {

            // 检验目的(药品筛选清单)定义在委托上
            // 我们复制一份到检材上, 以后可以从检材带入到实验室的样本中
            UpdateWrapper<EntrustmentIdentificationMaterial> imUpdateWrapper = new UpdateWrapper<EntrustmentIdentificationMaterial>();
            imUpdateWrapper.eq("entrustment_id", entrustment.getId());        // 查询条件是 entrustment_id 相等
            imUpdateWrapper.set("candidate_drugs", entrustment.getCandidateDrugs(), "typeHandler=com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler");
            entrustmentIdentificationMaterialService.update(null, imUpdateWrapper);
        }
        return entrustment;
    }

    @Override
    public Entrustment bizSubmitter_Apply(Entrustment entrust, DLPUser dlpUser) {
        Entrustment result;
        String oldUserId = SecurityUtils.getCurrentUserId();
        System.out.println(String.format("Old user id=%s", oldUserId));

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

        if (entrustment.getStatus() != EntrustmentStatusConstants.ENTRUSTMENT_STATUS_CREATED.getStatus()) {
            throw new CheckedException("委托已经提交, 无须再次提交");
        }

        if (dlpUser.isStaff() && dlpUser.HasPermission("EntrustmentAidInput")) {
            // 是代录员, clientOrgId 由用户提供
            if (StrUtil.isEmpty(entrust.getClientOrgId())) {
                throw new CheckedException("代录委托必须录入委托单位数据");
            }
        }

        //---- 也许有新的修改, 先保存一下
        Entrustment saveResult = bizSubmitter_Save(entrust, dlpUser);
        if (saveResult == null) {
            //-- 保存失败
            result = saveResult;
        } else {// 如果不由客户选择审核候选人, 系统自动把符合条件的员工都作为审核候选人
            if (!StrUtil.equalsIgnoreCase("1", AppStartupRunner.getCfg(CommonConstants.DLP_CODE_ENTRUSTMENT_CLIENT_CHOICE_CHECKERS))) {
//                List<SysUser> users = this.taskAvailableUserList_Check();
                List<SysUser> users = commonFeignService.remoteGetUsersByPermission(CommonConstants.ORG_TREE_ROOT_ID, CollUtil.newArrayList("EntrustmentCheck"));
                String candidateUser = "";
                for (SysUser u : users) {
                    if (candidateUser.length() > 0) {
                        candidateUser += ",";
                    }
                    candidateUser += u.getUserId();
                }
                entrustment.setCheckCandidateUser(candidateUser);       // 不使用用户提交的候选人名单
            } else {
                if (StrUtil.isBlank(entrust.getCheckCandidateUser())) {
                    throw new CheckedException("必须提供审批候选人名单");
                }

                entrustment.setCheckCandidateUser(entrust.getCheckCandidateUser());       // 使用用户提交的候选人名单
            }//		entrustment.setSubmitter(SecurityUtils.getCurrentUserId());
            entrustment.setSubmitter(dlpUser.getId());
            entrustment.setSubmitTime(LocalDateTime.now());
            entrustment.setPreviousStatus(entrustment.getStatus());       // 可能是从其他环节转过来的, 一旦提交, 保存上一个状态
//entrustment.setStatus(EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_CHECK_CLAIM.getStatus());
            entrustment.setStatus(ProcessFlowMapper.getNextStatus(entrustment.getStatus(), 1));
            List<UpdateInfo> pis = entrustment.getProcessInfo();
            if (pis == null) {
                pis = new ArrayList<UpdateInfo>();
            }
            UpdateInfo pi = new UpdateInfo(dlpUser.getId(),
                    dlpUser.getName(),
                    dlpUser.getOrgId(),
                    dlpUser.getOrgName(),
                    "已提交",
                    1, entrustment.getStatus(), true);
            pis.add(pi);
            entrustment.setProcessInfo(pis);
            //-- 更新送检员表的信息
            if (StringUtils.isNotBlank(entrust.getDeliverer1Name())) {
                Deliverer deliverer1 = getDeliverer1(entrust, dlpUser);
                remoteDeliverService.renew(deliverer1);
            } else {
                throw new CheckedException("送检人信息不能为空！");
            }
            if (StringUtils.isNotBlank(entrust.getDeliverer2Name())) {
                Deliverer deliverer2 = getDeliverer2(entrust, dlpUser);
                remoteDeliverService.renew(deliverer2);
            } else {
                throw new CheckedException("送检人信息不能为空！");
            }
            entrustment.setDeliverer1Id(entrust.getDeliverer1Id());
            entrustment.setDeliverer1Cert(entrust.getDeliverer1Cert());
            entrustment.setDeliverer1Name(entrust.getDeliverer1Name());
            entrustment.setDeliverer1Phone(entrust.getDeliverer1Phone());
            entrustment.setDeliverer1Position(entrust.getDeliverer1Position());
            entrustment.setDeliverer2Id(entrust.getDeliverer2Id());
            entrustment.setDeliverer2Cert(entrust.getDeliverer2Cert());
            entrustment.setDeliverer2Name(entrust.getDeliverer2Name());
            entrustment.setDeliverer2Phone(entrust.getDeliverer2Phone());
            entrustment.setDeliverer2Position(entrust.getDeliverer2Position());
// 更新数据库表数据
//-------------------
//提交审核的时候设置委托的编号  xy add
            CaseEvent caseEvent = caseEventService.getById(entrustment.getCaseId());//String entrustNewNo=entrustmentService.getNewEntrustmentNo(caseEvent.getCaseNo());
            String entrustNewNo = this.getNewEntrustmentNo();
            entrustment.setEntrustmentNo(entrustNewNo);//提交审核的时候，我们生成鉴定要求
            List<EntrustmentIdentificationMaterial> materialList = entrustmentIdentificationMaterialService.list(Wrappers.<EntrustmentIdentificationMaterial>query()
                    .eq("entrustment_id", entrustment.getId())
                    .orderByAsc("create_time"));
            if (materialList == null || materialList.size() == 0) {
                throw new CheckedException("请至少添加一个检材后再提交!");
            }
            if (StrUtil.isBlank(entrust.getEntrustRequirement())) {
                entrustment.setEntrustRequirement(this.buildEntrustReq(materialList));
            } else {
                entrustment.setEntrustRequirement(entrust.getEntrustRequirement());
            }
            this.updateById(entrustment);
            result = entrustment;
        }
        return result;
    }

    @Override
    @Transactional
    public Entrustment bizChecker_Claim(Entrustment entrust, DLPUser dlpUser) {
        // 检查委托原来的状态
        Entrustment entrustment = this.getById(entrust.getId());
        if (entrustment == null) {
            throw new RuntimeException(String.format("没有找到 id 为 %s 的委托", entrust.getId()));
        }

        if (entrustment.getStatus() != EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_CHECK_CLAIM.getStatus()) {
            // 已经有人认领这个审核任务了
            throw new RuntimeException(String.format("委托不在待审核状态, 审核任务认领人: %s", entrustment.getCheckClaimUser()));
        }

        String checkCandidateUsers[] = entrustment.getCheckCandidateUser().split(",");
        boolean currentUserIsCandidate = false;
        for (String candidateUser : checkCandidateUsers) {
            if (candidateUser.equals(dlpUser.getId())) {
                currentUserIsCandidate = true;
                break;
            }
        }
        if (!currentUserIsCandidate) {
            throw new RuntimeException("您不是候选审核用户, 无权进行审核");
        }

        // 检查一下流程实例创建没有。刚创建的委托只有提交时才创建流程实例, 其他环节流转过来的委托在之前已经创建过了
		/*
		if (StrUtil.isBlank(entrustment.getProcessInstanceId())) {
			throw new RuntimeException("系统错误, 这个委托没有对应的流程实例");
		}
		*/


        entrustment.setCheckClaimUser(dlpUser.getId());
        entrustment.setCheckClaimTime(LocalDateTime.now());
        entrustment.setPreviousStatus(entrustment.getStatus());       // 可能是从其他环节转过来的, 一旦提交, 保存上一个状态
        entrustment.setStatus(EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_CHECK.getStatus());

        //-------------------
        // 更新数据库表数据
        //-------------------
        UpdateWrapper<Entrustment> updateWrapper = new UpdateWrapper<Entrustment>();
        updateWrapper.eq("id", entrustment.getId());        // 查询条件是 id 相等

        updateWrapper.set("check_claim_user", entrustment.getCheckClaimUser());
        updateWrapper.set("check_claim_time", entrustment.getCheckClaimTime());
        updateWrapper.set("status", entrustment.getStatus());
        updateWrapper.set("previous_status", entrustment.getPreviousStatus());

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

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

    /*
    2024-9-11修改：贵阳市局只需要一层审核，因此我们默认把审批过程也加入到审核过程中，然后去除审批过程中的pi对象记录
     */
    @Override
    @Transactional
    public Entrustment bizChecker_Apply(Entrustment entrust, Integer opCode, DLPUser dlpUser) {
        if (opCode == null) {
            throw new RuntimeException("审核结果必须提供 opCode");
        }

        if (StrUtil.isBlank(entrust.getCheckComments())) {
            throw new RuntimeException("必须提供审核意见");
        }

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

        // 这里修改一下，我们要去掉委托认领的功能，所以只要用户是在审核列表中的，就可以进行审核操作
        if (!entrustment.getCheckCandidateUser().contains(dlpUser.getId())) {
            throw new RuntimeException("你不在可以审核的用户列表当中!");
        }
//        if (!dlpUser.getId().equals(entrustment.getCheckClaimUser())) {
//            throw new RuntimeException(String.format("委托的审核任务是由其他人认领的。认领用户是: %s", entrustment.getCheckClaimUser()));
//        }

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

        // 检查检材的审核状态
        if (opCode == 1) {
            List<EntrustmentIdentificationMaterial> imList = entrustmentIdentificationMaterialService.list(Wrappers.<EntrustmentIdentificationMaterial>query()
                    .eq("entrustment_id", entrustment.getId()));
            for (EntrustmentIdentificationMaterial im : imList) {
                if ((im.getCheckPassed() == null) || (im.getCheckPassed() == 0)) {
                    throw new RuntimeException("有检材还没有审核");
                } else if (im.getCheckPassed() == -1) {
                    throw new RuntimeException("有检材审核没有通过");
                } else if (im.getCheckPassed() != 1) {
                    // 审核状态不是 null/-1/0/1, 这个状态很奇怪
                    throw new RuntimeException("有检材审核状态不正确");
                }
            }
        }

        // 是否由审核人选择审批人, 系统自动把符合条件的员工都作为审批候选人
        if (!StrUtil.equalsIgnoreCase("1", AppStartupRunner.getCfg(CommonConstants.DLP_CODE_ENTRUSTMENT_CHECKER_CHOICE_APPROVERS))) {
//            List<SysUser> users = this.taskAvailableUserList_Approve();
            List<SysUser> users = commonFeignService.remoteGetUsersByPermission(CommonConstants.ORG_TREE_ROOT_ID, CollUtil.newArrayList("EntrustmentApprove"));
            String candidateUser = "";
            for (SysUser u : users) {
                if (candidateUser.length() > 0) {
                    candidateUser += ",";
                }
                candidateUser += u.getUserId();
            }
            entrustment.setApproveCandidateUser(candidateUser);       // 不使用用户提交的候选人名单
        } else {
            if (StrUtil.isBlank(entrust.getApproveCandidateUser())) {
                throw new RuntimeException("必须提供审批候选人名单");
            }
            entrustment.setApproveCandidateUser(entrust.getApproveCandidateUser());       // 使用用户提交的候选人名单
        }

        // 审核任务已经提交了, 转到新的环节
        int newStatus = -1;     // 新的状态(环节)
        String currentAcceptNo = "";

        newStatus = ProcessFlowMapper.getNextStatus(entrustment.getStatus(), opCode);

        if (opCode == 1 && StrUtil.isBlank(entrustment.getAcceptNo())) {
            // 20250114 贵阳需求，审核通过后就生成受理编号
            String yearStr = String.valueOf(LocalDateTime.now().getYear());
            String maxEntrustAcceptNo = baseMapper.getMaxEntrustAcceptNo(yearStr);
            currentAcceptNo = yearStr + "-" + (StrUtil.isBlank(maxEntrustAcceptNo) ? "1" : (Integer.parseInt(maxEntrustAcceptNo) + 1));
        }

        if (newStatus == EntrustmentStatusConstants.ENTRUSTMENT_STATUS_CREATED.getStatus()) {
            EntrustmentIdentificationMaterial im = new EntrustmentIdentificationMaterial();
            im.setCheckPassed(0);
            im.setApprovePassed(0);
            im.setAcceptPassed(0);
            im.setAcceptNo(null);
            entrustmentIdentificationMaterialService.setEntrustmentIdentificationMaterialStatusByEntrustment(im, entrustment.getId());
        }


        //退回后需标记
        if (opCode == -1) {
            entrustment.setReturnOrNot(-1);
        }

        //-------------------
        // 更新数据库表数据
        //-------------------
//        entrustment.setDestructiveAnalysis(entrust.getDestructiveAnalysis());
//        entrustment.setOtherIdentificationNotes(entrust.getOtherIdentificationNotes());
        //entrustment.setOtherAgreement(entrust.getOtherAgreement());
//        entrustment.setAvoidIdentifier(entrust.getAvoidIdentifier());
//        entrustment.setComments(entrust.getComments());

//        entrustment.setCheckUser(dlpUser.getId());
//        entrustment.setCheckTime(LocalDateTime.now());
//        entrustment.setCheckComments(entrust.getCheckComments());
//        entrustment.setCheckTimes(entrustment.getCheckTimes() + 1);   // 审核次数加 1
//        entrustment.setPreviousStatus(entrustment.getStatus());       // 可能是从其他环节转过来的, 一旦提交, 保存上一个状态
//        entrustment.setStatus(newStatus);           // 新的状态(环节), 可能会是审批或提交前

        List<UpdateInfo> pis = entrustment.getProcessInfo();
        if (pis == null) {
            pis = new ArrayList<UpdateInfo>();
        }
        if (opCode == 1) {
            UpdateInfo pi = new UpdateInfo(dlpUser.getId(),
                    dlpUser.getName(),
                    dlpUser.getOrgId(),
                    dlpUser.getOrgName(),
                    "已审核",
                    opCode, entrustment.getStatus(), true);

            pis.add(pi);
        } else {
            UpdateInfo pi = new UpdateInfo(dlpUser.getId(),
                    dlpUser.getName(),
                    dlpUser.getOrgId(),
                    dlpUser.getOrgName(),
                    "审核不通过",
                    opCode, entrustment.getStatus(), false, entrust.getCheckComments());
            entrustApproveRecordService.saveRecord(entrust, pi);
            pis.add(pi);
        }
//        entrustment.setProcessInfo(pis);

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

        updateWrapper.set("destructive_analysis", entrust.getDestructiveAnalysis());
        updateWrapper.set("other_identification_notes", entrust.getOtherIdentificationNotes());
        updateWrapper.set("other_agreement", entrustment.getOtherAgreement());
        updateWrapper.set("avoid_identifier", entrust.getAvoidIdentifier(), "typeHandler=com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler");
        updateWrapper.set("comments", entrust.getComments());
        updateWrapper.set("return_or_not", entrustment.getReturnOrNot());

        updateWrapper.set("check_user", dlpUser.getId());
        updateWrapper.set("check_time", LocalDateTime.now());
        updateWrapper.set("check_comments", entrust.getCheckComments());
        updateWrapper.set("check_times", entrustment.getCheckTimes() + 1); // 审核次数加 1
        updateWrapper.set("approve_candidate_user", entrustment.getApproveCandidateUser());
        updateWrapper.set("status", newStatus); // 新的状态(环节), 可能会是审批或提交前
        updateWrapper.set("previous_status", entrustment.getStatus()); // 可能是从其他环节转过来的, 一旦提交, 保存上一个状态
//		updateWrapper.set("process_info", entrustment.getProcessInfo(), "javaType=String,jdbcType=VARCHAR,typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler");
        updateWrapper.set("process_info", pis, "javaType=String,jdbcType=VARCHAR,typeHandler=com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler");
        updateWrapper.set(StrUtil.isNotBlank(currentAcceptNo), "accept_no", currentAcceptNo);
        if (!this.update(null, updateWrapper)) {
            throw new RuntimeException("保存委托信息失败");
        }
        if (opCode == 1) {
            this.bizApprover_Claim(entrust, dlpUser);
            this.bizApprover_Apply(entrust, 1, dlpUser);
        }
        // 从数据库表中取出保存的委托对象, 后续的操作我们以此为准
        entrustment = this.getById(entrust.getId());
        if (entrustment == null) {
            throw new RuntimeException(String.format("没有找到 id 为 %s 的委托", entrust.getId()));
        }
        //让第三方系统完成审核-----------------------------------------------------------------------------开始
        try {
            if (entrustment.getDataSources() == 1) {
                if (opCode == 1) {
                    boolean ret = auditEntrustDataOfThirdSys("Province", entrustment.getId(), "/api/identify/entrust/{entrustId}/provinceAudit", "success", "");
                    if (!ret) {
                        throw new RuntimeException();
                    }
                } else if (opCode == -1) {
                    boolean ret = auditEntrustDataOfThirdSys("Province", entrustment.getId(), "/api/identify/entrust/{entrustId}/provinceAudit", "fail", entrust.getCheckComments());
                    if (!ret) {
                        throw new RuntimeException();
                    }
                } else {
                    System.out.println("不支持的审核类型参数");
                }
            }
        } catch (Exception e) {
//            throw new RuntimeException(String.format("同步大数据平台审核出错，此次审核失败"));
        }

        return entrustment;
    }

    @Override
    @Transactional
    public Entrustment bizApprover_Claim(Entrustment entrust, DLPUser dlpUser) {
        // 检查委托原来的状态
        Entrustment entrustment = this.getById(entrust.getId());
        if (entrustment == null) {
            throw new RuntimeException(String.format("没有找到 id 为 %s 的委托", entrust.getId()));
        }

        if (entrustment.getStatus() != EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_APPROVE_CLAIM.getStatus()) {
            // 已经有人认领这个审批任务了
            throw new RuntimeException(String.format("委托不在待审批状态, 审批任务认领人: %s", entrustment.getApproveClaimUser()));
        }

        String approveCandidateUsers[] = StringUtils.isNotBlank(entrustment.getApproveCandidateUser()) ? entrustment.getApproveCandidateUser().split(",") : new String[]{};

        boolean currentUserIsCandidate = false;
        for (String candidateUser : approveCandidateUsers) {
            if (candidateUser.equals(dlpUser.getId())) {
                currentUserIsCandidate = true;
                break;
            }
        }
        if (!currentUserIsCandidate) {
            throw new RuntimeException("您不是候选审批用户, 无权进行审批");
        }

        // 检查一下流程实例创建没有。刚创建的委托只有提交时才创建流程实例, 其他环节流转过来的委托在之前已经创建过了
		/*
		if (StrUtil.isBlank(entrustment.getProcessInstanceId())) {
			throw new RuntimeException("系统错误, 这个委托没有对应的流程实例");
		}
		*/
        entrustment.setApproveClaimUser(dlpUser.getId());
        entrustment.setApproveClaimTime(LocalDateTime.now());
        entrustment.setPreviousStatus(entrustment.getStatus());       // 可能是从其他环节转过来的, 一旦提交, 保存上一个状态
        entrustment.setStatus(EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_APPROVE.getStatus());

        //-------------------
        // 更新数据库表数据
        //-------------------
        UpdateWrapper<Entrustment> updateWrapper = new UpdateWrapper<Entrustment>();
        updateWrapper.eq("id", entrustment.getId());        // 查询条件是 id 相等

        updateWrapper.set("approve_claim_user", entrustment.getApproveClaimUser());
        updateWrapper.set("approve_claim_time", entrustment.getApproveClaimTime());
        updateWrapper.set("status", entrustment.getStatus());
        updateWrapper.set("previous_status", entrustment.getPreviousStatus());

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

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

    @Override
    @Transactional
    public Entrustment bizApprover_Apply(Entrustment entrust, Integer opCode, DLPUser dlpUser) {

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

//        if (StrUtil.isBlank(entrust.getApproveComments())) {
//            throw new RuntimeException(String.format("必须提供审批意见"));
//        }

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

        if (!entrustment.getCheckCandidateUser().contains(dlpUser.getId())) {
            throw new RuntimeException("你不在可以审批的用户列表当中!");
        }
//        if (!dlpUser.getId().equals(entrustment.getApproveClaimUser())) {
//            throw new RuntimeException(String.format("委托的审批任务是由其他人认领的。认领用户是: %s", entrustment.getCheckClaimUser()));
//        }

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

        // 检查检材的审批状态, 只有opCode==1才检查检材, 其他操作为回退, 不用管检材状态
        if (opCode == 1) {
            List<EntrustmentIdentificationMaterial> imList = entrustmentIdentificationMaterialService.list(Wrappers.<EntrustmentIdentificationMaterial>query()
                    .eq("entrustment_id", entrustment.getId()));
            for (EntrustmentIdentificationMaterial im : imList) {
                if ((im.getApprovePassed() == null) || (im.getApprovePassed() == 0)) {
                    throw new RuntimeException("有检材还没有审批, 要先审批全部检材, 才能审批委托");
                } else if (im.getApprovePassed() == -1) {
                    throw new RuntimeException("有检材审批没有通过, 只有全部检材都审批通过, 才能审批委托");
                } else if (im.getApprovePassed() != 1) {
                    // 审核状态不是 null/-1/0/1, 这个状态很奇怪
                    throw new RuntimeException("有检材审批状态不正确");
                }
            }
        }
        // 审批任务已经提交了, 转到新的环节
        int newStatus = -1;     // 新的状态(环节)
        {
            newStatus = ProcessFlowMapper.getNextStatus(entrustment.getStatus(), opCode);
            if (newStatus == EntrustmentStatusConstants.ENTRUSTMENT_STATUS_CREATED.getStatus()) {
                EntrustmentIdentificationMaterial im = new EntrustmentIdentificationMaterial();
                im.setCheckPassed(0);
                im.setApprovePassed(0);
                im.setAcceptPassed(0);
                entrustmentIdentificationMaterialService.setEntrustmentIdentificationMaterialStatusByEntrustment(im, entrustment.getId());
            } else if (newStatus == EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_CHECK.getStatus()) {
                EntrustmentIdentificationMaterial im = new EntrustmentIdentificationMaterial();
                im.setCheckPassed(0);
                im.setApprovePassed(0);
                im.setAcceptPassed(0);
                entrustmentIdentificationMaterialService.setEntrustmentIdentificationMaterialStatusByEntrustment(im, entrustment.getId());
            }
        }
        //审批失败，需标记退回
        if (opCode == -2) {
            entrustment.setReturnOrNot(-1);
        }

        //-------------------
        // 更新数据库表数据
        //-------------------
        entrustment.setApproveUser(dlpUser.getId());
        entrustment.setApproveTime(LocalDateTime.now());
        entrustment.setApproveComments(entrust.getApproveComments());
        entrustment.setApproveTimes(entrustment.getApproveTimes() + 1);   // 审核次数加 1
        entrustment.setPreviousStatus(entrustment.getStatus());       // 可能是从其他环节转过来的, 一旦提交, 保存上一个状态
        entrustment.setStatus(newStatus);           // 新的状态(环节), 可能会是审批或提交前

        this.updateById(entrustment);

        // 从数据库表中取出保存的委托对象, 后续的操作我们以此为准
        //entrustment = entrustmentService.getById(entrust.getId());
        if (entrustment == null) {
            throw new RuntimeException(String.format("没有找到 id 为 %s 的委托", entrust.getId()));
        }
        //第三方系统审批---------------------------------------------开始
        //需要判断是第三方系统的数据才可以做第三方的同步
        try {
            if (entrustment.getDataSources() == 1) {
                if (opCode == 1) {
                    boolean ret = auditEntrustDataOfThirdSys("SubCenter", entrustment.getId(), "/api/identify/entrust/{entrustId}/acceptAudit", "success", "");
                    if (!ret) {
                        log.info("审批回写大数据平台数据未成功!{}", entrustment);
                    }

                } else if (opCode == -1) {
                    boolean ret = auditEntrustDataOfThirdSys("SubCenter", entrustment.getId(), "/api/identify/entrust/{entrustId}/acceptAudit", "fail", entrustment.getApproveComments());
                    if (!ret) {
                        throw new RuntimeException();
                    }
                } else {
                    System.out.println("不支持的审批类型参数");
                }
            }

        } catch (Exception e) {
//            throw new RuntimeException(String.format("同步大数据平台审批出错，此次审批失败!"));
        } finally {
            if (entrustment.getDataSources() == 1 && opCode == 1) {
                //将数据提升为待受理状态
                this.specialApprove(entrustment);
            }
        }
        //第三方系统审批---------------------------------------------结束
        return entrustment;
    }

    @Override
    public Entrustment bizConfirm_Apply(Entrustment entrust, Integer opCode, DLPUser dlpUser) {
        if (opCode == null) {
            throw new RuntimeException(String.format("送检确认必须提供 opCode"));
        }

        if (StrUtil.isBlank(entrust.getDeliverConfirmComments())) {
            throw new RuntimeException(String.format("必须提供送检确认意见"));
        }

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

        if (entrustment.getStatus() != EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_CONFIRM.getStatus()) {
            return null;
        }

        if (!dlpUser.isStaff()) {
            // 不是分中心用户, 是普通用户, 必须是本单位的人才能确认送检
            if (!StrUtil.equalsIgnoreCase(entrustment.getClientOrgId(), dlpUser.getOrgId())) {
                throw new RuntimeException("您只能对自己所在机构的委托进行送检确认");
            }
        }


        // 送检确认任务已经提交了, 转到新的环节
        int newStatus = -1;     // 新的状态(环节)
        {
            newStatus = ProcessFlowMapper.getNextStatus(entrustment.getStatus(), opCode);
            if (newStatus == EntrustmentStatusConstants.ENTRUSTMENT_STATUS_CREATED.getStatus()) {
                EntrustmentIdentificationMaterial im = new EntrustmentIdentificationMaterial();
                im.setCheckPassed(0);
                im.setApprovePassed(0);
                im.setAcceptPassed(0);
                entrustmentIdentificationMaterialService.setEntrustmentIdentificationMaterialStatusByEntrustment(im, entrustment.getId());
            }
        }

        //-------------------
        // 更新数据库表数据
        //-------------------
        entrustment.setDeliverConfirmUser(dlpUser.getId());
        entrustment.setDeliverConfirmTime(LocalDateTime.now());
        entrustment.setDeliverConfirmComments(entrust.getDeliverConfirmComments());
        entrustment.setPreviousStatus(entrustment.getStatus());       // 可能是从其他环节转过来的, 一旦提交, 保存上一个状态
        entrustment.setStatus(newStatus);           // 新的状态(环节), 可能会是审批或提交前

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

        updateWrapper.set("deliver_confirm_user", entrustment.getDeliverConfirmUser());
        updateWrapper.set("deliver_confirm_time", entrustment.getDeliverConfirmTime());
        updateWrapper.set("deliver_confirm_comments", entrustment.getDeliverConfirmComments());
        updateWrapper.set("status", entrustment.getStatus());
        updateWrapper.set("previous_status", entrustment.getPreviousStatus());
//		updateWrapper.set("process_info", entrustment.getProcessInfo(), "javaType=String,jdbcType=VARCHAR,typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler");
        updateWrapper.set("process_info", entrustment.getProcessInfo(), "javaType=String,jdbcType=VARCHAR,typeHandler=com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler");

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

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

    @Override
    public Entrustment bizDeliver_Save(Entrustment entrust, DLPUser dlpUser) {

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

        if (entrustment.getStatus() != EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_DELIVER.getStatus()) {
            throw new RuntimeException("委托不在待送检状态");
        }

        if (!StrUtil.equalsIgnoreCase(entrustment.getClientOrgId(), dlpUser.getOrgId())) {
            throw new RuntimeException("您只能对自己所在机构的委托进行送检");
        }
        //-- 更新送检员表的信息
        remoteDeliverService.renew(getDeliverer1(entrust, dlpUser));

        remoteDeliverService.renew(getDeliverer2(entrust, dlpUser));
        //-------------------


        //-------------------
        // 更新数据库表数据
        //-------------------
        // entrustment.setDeliverer1UserId(entrust.getDeliverer1UserId());
        entrustment.setDeliverer1Name(entrust.getDeliverer1Name());
        entrustment.setDeliverer1Position(entrust.getDeliverer1Position());
        entrustment.setDeliverer1Cert(entrust.getDeliverer1Cert());
        entrustment.setDeliverer1Id(entrust.getDeliverer1Id());
        entrustment.setDeliverer1Phone(entrust.getDeliverer1Phone());
        // entrustment.setDeliverer2UserId(entrust.getDeliverer2UserId());
        entrustment.setDeliverer2Name(entrust.getDeliverer2Name());
        entrustment.setDeliverer2Position(entrust.getDeliverer2Position());
        entrustment.setDeliverer2Cert(entrust.getDeliverer2Cert());
        entrustment.setDeliverer2Id(entrust.getDeliverer2Id());
        entrustment.setDeliverer2Phone(entrust.getDeliverer2Phone());

        UpdateWrapper<Entrustment> updateWrapper = getEntrustDeliverUpdateWrapper(entrustment);

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

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

    /**
     * 设置送检信息
     *
     * @param entrustment
     * @return
     */
    private static UpdateWrapper<Entrustment> getEntrustDeliverUpdateWrapper(Entrustment entrustment) {
        UpdateWrapper<Entrustment> updateWrapper = new UpdateWrapper<Entrustment>();
        updateWrapper.eq("id", entrustment.getId());        // 查询条件是 id 相等

        // updateWrapper.set("deliverer1_user_id", entrustment.getDeliverer1UserId());
        updateWrapper.set("deliverer1_name", entrustment.getDeliverer1Name());
        updateWrapper.set("deliverer1_position", entrustment.getDeliverer1Position());
        updateWrapper.set("deliverer1_cert", entrustment.getDeliverer1Cert());
        updateWrapper.set("deliverer1_id", entrustment.getDeliverer1Id());
        updateWrapper.set("deliverer1_phone", entrustment.getDeliverer1Phone());

        // updateWrapper.set("deliverer2_user_id", entrustment.getDeliverer2UserId());
        updateWrapper.set("deliverer2_name", entrustment.getDeliverer2Name());
        updateWrapper.set("deliverer2_position", entrustment.getDeliverer2Position());
        updateWrapper.set("deliverer2_cert", entrustment.getDeliverer2Cert());
        updateWrapper.set("deliverer2_id", entrustment.getDeliverer2Id());
        updateWrapper.set("deliverer2_phone", entrustment.getDeliverer2Phone());
        return updateWrapper;
    }

    /*
    2024-9-11 贵阳市局修改需求：由于在送检提交时就已经填写了送检人信息，因此在送检提交时只改变状态，记录一下送检时间即可。
     */
    @Override
    public Entrustment bizDeliver_Apply(Entrustment entrust, Integer opCode, DLPUser dlpUser) {

        if (opCode == null) {
            throw new RuntimeException(String.format("送检操作必须提供 opCode"));
        }

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

        if (entrustment.getStatus() != EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_DELIVER.getStatus()) {
            throw new RuntimeException("委托不在待送检状态");
        }

        if (!dlpUser.isStaff()) {
            if (!StrUtil.equalsIgnoreCase(entrustment.getClientOrgId(), dlpUser.getOrgId())) {
                throw new RuntimeException("您只能对自己所在机构的委托进行送检");
            }
        }

        // 送检任务已经提交了, 转到新的环节
        int newStatus = ProcessFlowMapper.getNextStatus(entrustment.getStatus(), opCode);     // 新的状态(环节)

        entrustment.setDeliverTime(LocalDateTime.now());
        entrustment.setDeliverSubmitter(dlpUser.getId());

        List<UpdateInfo> pis = entrustment.getProcessInfo();
        if (pis == null) {
            pis = new ArrayList<UpdateInfo>();
        }

        UpdateInfo pi = new UpdateInfo(dlpUser.getId(),
                dlpUser.getName(),
                dlpUser.getOrgId(),
                dlpUser.getOrgName(),
                "已送检",
                opCode, entrustment.getStatus(), true);

        pis.add(pi);
        entrustment.setProcessInfo(pis);

        entrustment.setPreviousStatus(entrustment.getStatus());       // 可能是从其他环节转过来的, 一旦提交, 保存上一个状态
        entrustment.setStatus(newStatus);           // 新的状态(环节), 可能会是受理

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


        updateWrapper.set("deliver_time", entrustment.getDeliverTime());
        updateWrapper.set("entrustment_time", entrust.getEntrustmentTime());
        updateWrapper.set("deliver_submitter", entrustment.getDeliverSubmitter());

        updateWrapper.set("status", entrustment.getStatus());
        updateWrapper.set("previous_status", entrustment.getPreviousStatus());
//		updateWrapper.set("process_info", entrustment.getProcessInfo(), "javaType=String,jdbcType=VARCHAR,typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler");
        updateWrapper.set("process_info", entrustment.getProcessInfo(), "javaType=String,jdbcType=VARCHAR,typeHandler=com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler");

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

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

    @Override
    public String bizGetPDFEntrustmentLetter(String id, HttpServletRequest theHttpServletRequest, HttpServletResponse httpServletResponse) {

        System.out.println("bizGenerateEntrustmentWord.................");
        Principal principal = theHttpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();

        EntrustmentVO ev = getEntrustmentVOAndVaildData(id, dlpUser);
        String entrustmentLetterFileName = "鉴定委托书" + "-" + ev.getEntrustmentNo();
        // 转换临时目录中的 word 文档为 PDF
        String pdfFilePath = OSSDirectoryConstants.DOCUMENT_ENTRUSTMENT_DIRECTORY + "/" + ev.getId() + "/" + entrustmentLetterFileName + ".docx";
        try {
            //这里加一下判断条件，由于贵阳市局这里的情况是审核的时候就需要查看委托书，所以为了保证每一次提交过来的委托都是最新的，所以在受理通过以前应该每次查看都是重新生成
            if (!ossFile.objectExist(pdfFilePath) || ev.getStatus() <= EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_ACCEPT.getStatus()) {
                GenerateEntrustmentLetterPDF(ev);
                return pdfFilePath;
            }
            return pdfFilePath;
//            ossFile.fileGet(pdfFilePath, httpServletResponse.getOutputStream());
//            httpServletResponse.setContentType(new MimetypesFileTypeMap().getContentType(entrustmentLetterFileName));
        } catch (Exception e) {
            System.out.println(String.format("minioFile objectExist() Exception. %s", e.getLocalizedMessage()));
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取委托vo类，并验证数据是否合法
     *
     * @param id
     * @param dlpUser
     * @return
     */
    private EntrustmentVO getEntrustmentVOAndVaildData(String id, DLPUser dlpUser) {
        EntrustmentVO ev = this.getEntrustmentVOById(id);
        if (ev == null) {
            throw new RuntimeException(String.format("没有找到 id 为 %s 的委托", id));
        }

        if (ev.getStatus() < EntrustmentStatusConstants.ENTRUSTMENT_STATUS_CREATED.getStatus()) {
            throw new RuntimeException("委托状态必须在委托创建之后才能打印鉴定委托书");
        }

        if (!dlpUser.isStaff()) {
            if (!StrUtil.equalsIgnoreCase(ev.getClientOrgId(), dlpUser.getOrgId())) {
                throw new RuntimeException("您只能打印自己所在机构的委托");
            }
        }
        return ev;
    }

    /**
     * 生成鉴定委托书
     *
     * @return
     */
    private boolean GenerateEntrustmentLetterPDF(EntrustmentVO ev) throws Exception {
        System.out.println("bizGenerateEntrustmentWord.................");

        //try {
        //---------------
        // 构造对象 Map
        //Map<String, Object> dm = BeanMap.create(ev);    //ClassUtils.objectToMap(ev);
        Map<String, Object> dm = ClassUtils.objectToMap(ev);
        if (ev.getEntrustmentTime() == null) {
            ev.setEntrustmentTime(LocalDateTime.now());
            UpdateWrapper<Entrustment> updateWrapper = new UpdateWrapper<Entrustment>();
            updateWrapper.eq("id", ev.getId());        // 查询条件是 id 相等

            updateWrapper.set("entrustment_time", ev.getEntrustmentTime());

            if (!this.update(null, updateWrapper)) {
                throw new RuntimeException("保存委托日期失败");
            }
        }
        // 如果受理编号不为空，则生成[xxxx]x号，比如2025-8 -》 [2025]8号
        if (StrUtil.isNotBlank(ev.getAcceptNo())) {
            List<String> split = StrUtil.split(ev.getAcceptNo(), "-");
            dm.put("acceptNo", String.format("[%s]%s号", split.get(0), split.get(1)));
        }
        String oldIdentificationResult = ev.getOldIdentificationResult();
        String oldIdentification = "";
        switch (oldIdentificationResult) {
            case "首次鉴定":
                oldIdentification = "☑首次鉴定；□补充鉴定；□重新鉴定";
                break;
            case "补充鉴定":
                oldIdentification = "□首次鉴定；☑补充鉴定；□重新鉴定";
                break;
            case "重新鉴定":
                oldIdentification = "□首次鉴定；□补充鉴定；☑重新鉴定";
                break;
        }
        dm.put("oldIdentification", oldIdentification);
        dm.put("entrustmentTime", LocalDateTimeUtil.format(ev.getEntrustmentTime(), "yyyy年MM月dd日"));
        dm.put("year", ev.getEntrustmentTime().getYear());
        List<EntrustmentIdentificationMaterialVO> ems = entrustmentIdentificationMaterialService.getEntrustmentIdentificationMaterialVOList(Wrappers.<EntrustmentIdentificationMaterial>query()
                .eq("entrustment_id", ev.getId()).orderByAsc("im_no"));

        for (EntrustmentIdentificationMaterialVO eim : ems) {
            if (StrUtil.isEmpty(eim.getFormName())) {    // 如果找不到编码, 则是直接写的名字
                eim.setFormName(eim.getForm());
            }
        }
        //编码转换---
        dm.put("identificationMaterials", ems);

        SysOrg org = remoteOrgService.getById(ev.getClientOrgId()).getData();
        dm.put("clientOrg", ClassUtils.objectToMap(org));

        List<EntrustmentIdentificationMaterial> materialList = entrustmentIdentificationMaterialService.list(
                Wrappers.<EntrustmentIdentificationMaterial>query()
                        .eq("entrustment_id", ev.getId())
                        .orderByAsc("order_no")
        );
        entrustmentIdentificationMaterialService.conformityDrugs(materialList);
        //设置检材描述
        dm.put("materialDes", this.buildMaterialDes(materialList));
        //设置鉴定要求
        //dm.put("identifyReq",entrustmentService.buildIdentfyReq(materialList));
        dm.put("identifyReq", ev.getEntrustRequirement());
        //设置检材列表, 对检材的重量进行处理  小于100的保留两位小数，100以上保留一位小数
        BigDecimal compareNumber = new BigDecimal(100);
        for (EntrustmentIdentificationMaterial entrustmentIdentificationMaterial : materialList) {
            BigDecimal quantity = entrustmentIdentificationMaterial.getQuantity();
            if (quantity.compareTo(compareNumber) >= 0) {
                entrustmentIdentificationMaterial.setQuantity(quantity.setScale(1, BigDecimal.ROUND_HALF_UP));
            } else {
                entrustmentIdentificationMaterial.setQuantity(quantity.setScale(2, BigDecimal.ROUND_HALF_UP));
            }
        }
        dm.put("materialList", materialList);
        // QR Code
//			BufferedImage bufferedImage = QRCodeUtils.genQRCode(ev.getEntrustmentNo(), 100, 100);
//			dm.put("EntrustmentNoQRCode", Pictures.ofBufferedImage(bufferedImage, PictureType.PNG)
//					.size(100, 100).create());
        BufferedImage bufferedImage = QRCodeUtils.getBarCode128Image(ev.getEntrustmentNo(), 280, 30);
        dm.put("EntrustmentNoQRCode", Pictures.ofBufferedImage(bufferedImage, PictureType.PNG)
                .size(280, 30).fitSize().create());

        //-----------------------------
        // 生成 word 版本的
        String entrustmentLetterFileName = "鉴定委托书-" + ev.getEntrustmentNo();

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ossFile.fileGet(OSSDirectoryConstants.TEMPLATE_DIRECTORY + "/" + AppStartupRunner.getCfg(CommonConstants.DLP_CODE_ENTRUSTMENT_LETTER_TEMPLATE), bos);

        byte[] templateArray = bos.toByteArray();
        ByteArrayInputStream bis = new ByteArrayInputStream(templateArray);
        bos.close();
        //处理要循环的表格
        MultipleRowTableRenderPolicy policy = new MultipleRowTableRenderPolicy();
        // 现在 bis 是模板的 InputStream
        ConfigureBuilder builder = Configure.builder().buildGramer("${", "}").useSpringEL(false);
        builder.bind("materialList", policy);
        XWPFTemplate template = XWPFTemplate.compile(bis, builder.build()).render(dm);
        bis.close();

        ByteArrayOutputStream fosWord = new ByteArrayOutputStream();
        template.write(fosWord);
        template.close();

        //------------
        ByteArrayInputStream fisWord = new ByteArrayInputStream(fosWord.toByteArray());


        boolean fileSave = ossFile.fileSave(OSSDirectoryConstants.DOCUMENT_ENTRUSTMENT_DIRECTORY + "/" + ev.getId() + "/" + entrustmentLetterFileName + ".docx", fisWord);
        fosWord.close();
        fisWord.close();
        System.out.println(String.format("转换为 Word 结束"));
        return fileSave;
    }


    public boolean auditEntrustDataOfThirdSys(String userFlag, String entrustId, String dataPath, String result, String reMark) throws Exception {
        EntrustOfThirdSys entrustOfThirdSys = synchronizeDataService.getThirdSysEntrustByMainId(entrustId);
        if (entrustOfThirdSys == null) {
            throw new RuntimeException(String.format("没有找到 id 为 %s 的委托", entrustId));
        }

        String thirdSysEntrustID = entrustOfThirdSys.getId();
        String auditOrAccept = "Audit";
        Boolean ret = synchronizeDataService.auditEntrustByProvinceOrCenter(userFlag, dataPath, thirdSysEntrustID, result, reMark, auditOrAccept);
        System.out.println("第三方数据推送结果:" + ret);
        return ret;
    }


    //特殊审批委托
    public void specialApprove(Entrustment entrustment) {
        //将审批状态直接提升为待受理状态
        entrustment.setStatus(EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_ACCEPT.getStatus());
        entrustment.setPreviousStatus(EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_CONFIRM.getStatus());
        this.updateById(entrustment);
    }

    //受理第三方委托
    public boolean acceptThirdSysEntrust(String dataPath, Entrustment selfEntrust) throws Exception {
        EntrustOfThirdSys entrustOfThirdSys = synchronizeDataService.getThirdSysEntrustByMainId(selfEntrust.getId());
        if (entrustOfThirdSys == null) {
            throw new RuntimeException(String.format("没有找到 id 为 %s 的委托", selfEntrust.getId()));
        }
        return synchronizeDataService.subCenterAccept(dataPath, selfEntrust, entrustOfThirdSys);
    }

    @Override
    public Entrustment bizAccept_Save(Entrustment entrust, DLPUser dlpUser) {
        // 检查委托原来的状态
        Entrustment entrustment = this.getById(entrust.getId());
        if (entrustment == null) {
            throw new RuntimeException(String.format("没有找到 id 为 %s 的委托", entrust.getId()));
        }

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

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

        //-------------------
        // 更新数据库表数据
        //-------------------

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

        updateWrapper.set("destructive_analysis", entrust.getDestructiveAnalysis());
        updateWrapper.set("other_identification_notes", entrust.getOtherIdentificationNotes());
        updateWrapper.set("avoid_identifier", entrust.getAvoidIdentifier(), "typeHandler=com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler");
        updateWrapper.set("other_agreement", entrust.getOtherAgreement());
        updateWrapper.set("comments", entrust.getComments());

        updateWrapper.set("accept_user", null); // 之前可能受理过, 现在后悔了, 置 null
        updateWrapper.set("accept_time", null);
        updateWrapper.set("accept_comments", entrust.getAcceptComments());


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

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

    @Override
    @GlobalTransactional
    public Entrustment bizAccept_Apply(Entrustment entrust, Integer opCode, DLPUser dlpUser) {
        // 20250114 贵阳禁毒需求，受理编号在提交审核时就生成
//        String newEntrustAcceptNo = "";
        if (opCode == null) {
            throw new RuntimeException(String.format("受理必须提供 opCode"));
        }

        if (StrUtil.isBlank(entrust.getAcceptComments())) {
            throw new RuntimeException(String.format("必须提供受理意见"));
        }

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

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

        if (entrustment.getStatus() != EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_ACCEPT.getStatus()) {
            throw new RuntimeException("委托不在正在受理状态");
        }
        if (opCode < 0) {
            List<EntrustmentIdentificationMaterial> list = entrustmentIdentificationMaterialService.list(new LambdaQueryWrapper<EntrustmentIdentificationMaterial>().eq(EntrustmentIdentificationMaterial::getEntrustmentId, entrustment.getId()));
            for (EntrustmentIdentificationMaterial entrustmentIdentificationMaterial : list) {
                entrustmentIdentificationMaterial.setAcceptNo(null);
            }
            entrustmentIdentificationMaterialService.updateBatchById(list);
        }

        if (opCode > 0) {
            //检查检材是否复秤，不复秤不能受理
            boolean b = this.checkRepeatWeigh(entrustment);
            if (b) {
                throw new RuntimeException(String.format("有未复秤的样本，请给样本复秤"));
            }
            // 如果是确认受理, 需要检材全部都确认受理
            // 检查检材的受理状态
            List<EntrustmentIdentificationMaterial> imList = entrustmentIdentificationMaterialService.list(Wrappers.<EntrustmentIdentificationMaterial>query()
                    .eq("entrustment_id", entrustment.getId()));

            //检查检材受理编号前半段是否一致
            //3-26修改：因为我们无需在受理完成前生成检材编号了，所以不用这个校验
//            Map<String, List<EntrustmentIdentificationMaterial>> tempMap = imList.stream().collect(Collectors.groupingBy(item -> item.getAcceptNo().substring(0, item.getAcceptNo().lastIndexOf("-"))));
//            if (tempMap.size() > 1) {
//                throw new RuntimeException("检材受理编号不一致，请检查");
//            }

            for (EntrustmentIdentificationMaterial im : imList) {
                if (im.getSample2Present() != null && im.getSample2Present()) {
                    if ((im.getSample1RepeatWeigh() != null && im.getSample1RepeatWeigh().compareTo(BigDecimal.ZERO) != 0) && (im.getSample2RepeatWeigh() == null || im.getSample2RepeatWeigh().compareTo(BigDecimal.ZERO) == 0)) {
                        throw new RuntimeException("有检材存在留存样，只复称了分析样，要全部复称才能受理委托");
                    }

                    if ((im.getSample2RepeatWeigh() != null && im.getSample2RepeatWeigh().compareTo(BigDecimal.ZERO) != 0) && (im.getSample1RepeatWeigh() == null || im.getSample2RepeatWeigh().compareTo(BigDecimal.ZERO) == 0)) {
                        throw new RuntimeException("有检材只复称了留存样，要全部复称才能受理委托");
                    }
                }

                if ((im.getAcceptPassed() == null) || (im.getAcceptPassed() == 0)) {
                    throw new RuntimeException("有检材还没有受理, 要先受理全部检材, 才能受理委托");
                } else if (im.getAcceptPassed() == -1) {
                    throw new RuntimeException("有检材受理没有通过, 只有全部检材都受理通过, 才能受理委托");
                } else if (im.getAcceptPassed() != 1) {
                    // 审核状态不是 null/-1/0/1, 这个状态很奇怪
                    throw new RuntimeException("有检材受理状态不正确");
                }
            }
            //从检材中取出委托的受理号
//            String materialAcceptNo = imList.get(0).getAcceptNo(); 20250114
//            // 3-26 如果是大数据平台同步的委托，那么我们在受理完成的时候先生成一个空的受理编号，最后在同步大数据平台信息的时候会把这个编号赋值过去
////            newEntrustAcceptNo = materialAcceptNo.substring(0, materialAcceptNo.lastIndexOf("-"));
//            entrustmentIdentificationMaterialService.getNewIdentificationMaterialNo(newEntrustAcceptNo);
//            if (entrustment.getDataSources() != 1) {
//                newEntrustAcceptNo = materialAcceptNo.substring(0, materialAcceptNo.lastIndexOf("-"));
//            } else {
//                newEntrustAcceptNo = "acceptNo";
//            }
        }
        int newStatus = ProcessFlowMapper.getNextStatus(entrustment.getStatus(), opCode);

        //--------------------------
        // 创建鉴定
        //--------------------------
        if (opCode == 1) {
            if (StrUtil.isBlank(entrustment.getIdentificationId())) {
                // 鉴定Id 是空, 说明不是补充委托, 是新的鉴定
                Identification identification = new Identification();
                identification.setId(IdWorker.get32UUID().toUpperCase());
                identification.setIdentificationNo(identificationService.getNewIdentificationNo());
                identificationService.save(identification);
                //entrustment.setAcceptNo(identificationService.getNewIdentificationNo());//设置鉴定编号就是受理编号
                //给这个委托书设置鉴定ID
                entrustment.setIdentificationId(identification.getId());
            }
        }

        if (newStatus == EntrustmentStatusConstants.ENTRUSTMENT_STATUS_CREATED.getStatus()) {
            EntrustmentIdentificationMaterial im = new EntrustmentIdentificationMaterial();
            im.setCheckPassed(0);
            im.setApprovePassed(0);
            im.setAcceptPassed(0);
            im.setAcceptNo(null);
            entrustmentIdentificationMaterialService.setEntrustmentIdentificationMaterialStatusByEntrustment(im, entrustment.getId());
        }

        //-------------------
        // 更新数据库表数据
        //-------------------
        entrustment.setDestructiveAnalysis(entrust.getDestructiveAnalysis());
        entrustment.setOtherIdentificationNotes(entrust.getOtherIdentificationNotes());
        entrustment.setAvoidIdentifier(entrust.getAvoidIdentifier());
        //entrustment.setOtherAgreement(entrust.getOtherAgreement());
        entrustment.setComments(entrust.getComments());

        entrustment.setAcceptUser(dlpUser.getId());
        entrustment.setAcceptTime(LocalDateTime.now());
        entrustment.setAcceptComments(entrust.getApproveComments());
        entrustment.setPreviousStatus(entrustment.getStatus());       // 可能是从其他环节转过来的, 一旦提交, 保存上一个状态
        entrustment.setStatus(newStatus);           // 新的状态(环节), 可能会是审批或提交前


        List<UpdateInfo> pis = entrustment.getProcessInfo();
        if (pis == null) {
            pis = new ArrayList<UpdateInfo>();
        }
        if (opCode == 1) {
            UpdateInfo pi = new UpdateInfo(dlpUser.getId(),
                    dlpUser.getName(),
                    dlpUser.getOrgId(),
                    dlpUser.getOrgName(),
                    "已受理",
                    opCode, entrustment.getStatus(), true);
            pis.add(pi);
        } else {
            UpdateInfo pi = new UpdateInfo(dlpUser.getId(),
                    dlpUser.getName(),
                    dlpUser.getOrgId(),
                    dlpUser.getOrgName(),
                    "受理不通过",
                    opCode, entrustment.getStatus(), false, entrust.getAcceptComments());
            pis.add(pi);
        }
        entrustment.setProcessInfo(pis);

        //上面注释的代码前面已经设置过，不需要再设置一次，直接更新
//        if (StringUtils.isNotBlank(newEntrustAcceptNo)) { 20250114
//            entrustment.setAcceptNo(newEntrustAcceptNo);//设置受理编号
//        }
//        if (!StringUtils.isNotBlank(newEntrustAcceptNo) && opCode == 1) {
//            throw new RuntimeException("受理编号不能为空");
//        }
        entrustment.setIsTrans(1);//如果是通过我们系统进行受理，就让他不能再手动流转了
        if (!this.updateById(entrustment)) {
            throw new RuntimeException("保存委托信息失败");
        }
        // 更新委托书和确认书
        CompletableFuture.runAsync(() -> {
            this.generateIdentifyItemsBook(entrustment.getId());
            try {
                GenerateEntrustmentLetterPDF(this.getEntrustmentVOById(entrustment.getId()));
            } catch (Exception e) {
                log.error("委托书重新生成失败， 失败原因： {}", e.getMessage());
            }
        });

        //同步第三方禁毒系统的受理功能 开始--------------------------------------------------------------
        boolean isSuccess = true;
        try {
            if (entrustment.getDataSources() == 1) {
                if (opCode == 1) {
                    //auditEntrustDataOfThirdSys("SubCenter",entrustment.getId(),"/api/identify/entrust/{entrustId}/acceptAudit","success","");
                    boolean ret = acceptThirdSysEntrust("/api/identify/entrust/{entrustId}/accept", entrustment);
                    if (ret) {
                        log.info("大数据平台受理成功 {}", entrustment.getId());
                        if (opCode > 0) {
                            List<EntrustmentIdentificationMaterial> imList = entrustmentIdentificationMaterialService.list(Wrappers.<EntrustmentIdentificationMaterial>query()
                                    .eq("entrustment_id", entrustment.getId()));
                            List<Sample> newSampleList = new ArrayList<Sample>();
                            for (EntrustmentIdentificationMaterial im : imList) {

                                List<Sample> oldSampleList = sampleService.createSample(im, entrustment.getClientOrgId(), dlpUser.getId());
                                for (Sample oldSamObj : oldSampleList) {
                                    Sample newSamObj = new Sample();
                                    BeanUtils.copyProperties(oldSamObj, newSamObj);
                                    newSampleList.add(newSamObj);
                                }
                            }
                            System.out.println("-------------准备写入远程检材系统的数据量为：" + newSampleList.size());
                            //调用流转系统的接口，并将数据写过去
                            remoteSampleService.enterSample(newSampleList);
                        }
                    } else {
                        isSuccess = false;
                        log.info("大数据平台受理失败 {}", entrustment.getId());
                        throw new RuntimeException(String.format("同步受理信息至大数据平台失败，此次受理失败，请从大数据平台重新受理，然后将在本系统已受理页面将委托同步!"));
                    }
                } else {
                    System.out.println("不支持的受理类型参数");
                }
            } else {
                List<EntrustmentIdentificationMaterial> imList = entrustmentIdentificationMaterialService.list(Wrappers.<EntrustmentIdentificationMaterial>query()
                        .eq("entrustment_id", entrustment.getId()));
                List<Sample> newSampleList = new ArrayList<Sample>();
                for (EntrustmentIdentificationMaterial im : imList) {

                    List<Sample> oldSampleList = sampleService.createSample(im, entrustment.getClientOrgId(), dlpUser.getId());
                    for (Sample oldSamObj : oldSampleList) {
                        Sample newSamObj = new Sample();
                        BeanUtils.copyProperties(oldSamObj, newSamObj);
                        newSampleList.add(newSamObj);
                    }
                }
                System.out.println("-------------准备写入远程检材系统的数据量为：" + newSampleList.size());
                //调用流转系统的接口，并将数据写过去
                remoteSampleService.enterSample(newSampleList);
            }

        } catch (Exception e) {
            e.printStackTrace();
            log.info("大数据平台受理失败 {}", entrustment.getId());
//            throw new RuntimeException("同步大数据平台受理出错，此次受理失败");
        }
        if (!isSuccess) {
            throw new RuntimeException(String.format("同步受理信息至大数据平台失败，此次受理失败，请从大数据平台重新受理，然后将在本系统已受理页面将委托同步!"));
        }
        return entrustment;
    }

    /**
     * 创建需要流转到流转系统的检材列表
     *
     * @param dlpUser
     * @param entrustment
     * @return
     */
    @Override
    public List<Sample> getTransferMaterialList(DLPUser dlpUser, Entrustment entrustment) {
        List<EntrustmentIdentificationMaterial> imList = entrustmentIdentificationMaterialService.list(Wrappers.<EntrustmentIdentificationMaterial>query()
                .eq("entrustment_id", entrustment.getId()));
        List<Sample> newSampleList = new ArrayList<>();
        for (EntrustmentIdentificationMaterial im : imList) {

            List<Sample> oldSampleList = sampleService.createSample(im, entrustment.getClientOrgId(), dlpUser.getId());
            for (Sample oldSamObj : oldSampleList) {
                Sample newSamObj = new Sample();
                BeanUtils.copyProperties(oldSamObj, newSamObj);
                newSampleList.add(newSamObj);
            }
        }
        return newSampleList;
    }

    @Override
    public void bizGetPDFIdentifyItemsConfirmLetter(String id, String pdfOrWord, HttpServletRequest
            theHttpServletRequest, HttpServletResponse httpServletResponse) {
        Principal principal = theHttpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();

        EntrustmentVO ev = this.getEntrustmentVOById(id);
        if (ev == null) {
            throw new RuntimeException(String.format("没有找到 id 为 %s 的委托", id));
        }

        if (!dlpUser.isStaff()) {
            throw new RuntimeException("受理员必须是鉴定中心员工, 普通用户不能下载鉴定事项确认书。");
        }

        // 正在受理和已受理这2个状态下可以打印
        //这里再次修改一下，以前是待受理和已受理两个状态才能生成，由于贵阳市局这里的情况是需要在审核的时候查看确认书，所以如果状态是在委托提交以前我们才不允许生成
        if (ev.getStatus() < EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_CHECK_CLAIM.getStatus()) {
            throw new RuntimeException("委托不在可以生成确认书的状态");
        }

        // if (!StrUtil.equalsIgnoreCase(ev.getClientOrgId(), dlpUser.getOrgId())) {
        // 	throw new RuntimeException("您只能打印自己所在机构的鉴定委托书");
        // }

        String identifyItemsConfirmLetterFileName = "鉴定事项确认书-" + ev.getEntrustmentNo();
        // 转换临时目录中的 word 文档为 PDF
        String pdfFilePath = OSSDirectoryConstants.IDENTIFY_BOOK_DIRECTORY + "/" + ev.getId() + "/" + identifyItemsConfirmLetterFileName + ".pdf";
        String wordFilePath = OSSDirectoryConstants.IDENTIFY_BOOK_DIRECTORY + "/" + ev.getId() + "/" + identifyItemsConfirmLetterFileName + ".docx";
        String downFile = "";
        //判断是要获取PDF还是word
        if (pdfOrWord.equals("1")) {
            downFile = wordFilePath;
        } else {
            downFile = pdfFilePath;
        }
        try {
            //如果文件不存在，则生成，否则直接从OSS中获取
            //if (!ossFile.objectExist(pdfFilePath)) {
            //这里加一个判断，由于贵阳市局的确认书需要在审核的时候就能打印出来，为了保证每一次生成的确认书都是委托单位提交过来的最新版，所以我们在审核通过之前，每一次生成委托书都应该重新生成，审核成功以后就不用再重新生成了
            if (!ossFile.objectExist(downFile) || ev.getStatus() <= EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_ACCEPT.getStatus()) {

                if (this.generateIdentifyItemsBook(ev.getId())) {
                    ossFile.fileGet(downFile, httpServletResponse.getOutputStream());
                    httpServletResponse.setContentType(new MimetypesFileTypeMap().getContentType(identifyItemsConfirmLetterFileName));
                } else {
                    throw new RuntimeException("生成鉴定事项确认书失败");
                }
                //GenerateIdentifyItemsConfirmLetterPDF(ev);
            } else {
                ossFile.fileGet(downFile, httpServletResponse.getOutputStream());

                httpServletResponse.setContentType(new MimetypesFileTypeMap().getContentType(identifyItemsConfirmLetterFileName));
            }

        } catch (Exception e) {
            System.out.println(String.format("minioFile objectExist() Exception. %s", e.getLocalizedMessage()));
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }

    @Override
    public void GenerateIdentifyItemsConfirmLetterPDF(EntrustmentVO ev) {

        System.out.println("GenerateIdentifyItemsConfirmLetterPDF().................");

        try {
            //---------------
            // 构造对象 Map
            //Map<String, Object> dm = BeanMap.create(ev);    //ClassUtils.objectToMap(ev);
            Map<String, Object> dm = ClassUtils.objectToMap(ev);

            if (ev.getEntrustmentTime() == null) {
                ev.setEntrustmentTime(LocalDateTime.now());
                UpdateWrapper<Entrustment> updateWrapper = new UpdateWrapper<Entrustment>();
                updateWrapper.eq("id", ev.getId());        // 查询条件是 id 相等

                updateWrapper.set("entrustment_time", ev.getEntrustmentTime());

                if (!this.update(null, updateWrapper)) {
                    throw new RuntimeException("保存委托日期失败");
                }
            }

            dm.put("entrustmentTime", LocalDateTimeUtil.format(ev.getEntrustmentTime(), "yyyy年MM月dd日"));


            List<EntrustmentIdentificationMaterialVO> ems = entrustmentIdentificationMaterialService.getEntrustmentIdentificationMaterialVOList(
                    Wrappers.<EntrustmentIdentificationMaterial>query()
                            .eq("entrustment_id", ev.getId()).orderByAsc("im_no"));
            dm.put("identificationMaterials", ems);

            SysOrg org = remoteOrgService.getById(ev.getClientOrgId()).getData();
            dm.put("clientOrg", ClassUtils.objectToMap(org));

            // QR Code
            BufferedImage bufferedImage = QRCodeUtils.genQRCode(ev.getEntrustmentNo(), 100, 100);
            dm.put("EntrustmentNoQRCode", Pictures.ofBufferedImage(bufferedImage, PictureType.PNG)
                    .size(100, 100).create());

            // 鉴定期限
            dm.put("identificationTimeLimit", AppStartupRunner.getCfg(CommonConstants.DLP_CODE_ENTRUSTMENT_IDENTIFICATION_TIME_LIMIT));

            //-----------------------------
            // 生成 word 版本的 鉴定事项确认书
            String identifyItemsConfirmLetterFileName = "鉴定事项确认书-" + ev.getEntrustmentNo();

            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ossFile.fileGet(OSSDirectoryConstants.TEMPLATE_DIRECTORY + "/" + AppStartupRunner.getCfg(CommonConstants.DLP_CODE_ENTRUSTMENT_IDENTIFY_ITEMS_CONFIRM_LETTER_TEMPLATE), bos);

            byte[] templateArray = bos.toByteArray();
            ByteArrayInputStream bis = new ByteArrayInputStream(templateArray);
            bos.close();

            MultipleRowTableRenderPolicy policy = new MultipleRowTableRenderPolicy();

            Configure config = Configure.builder().buildGramer("${", "}")
                    .bind("identificationMaterials", policy)
                    .bind("candidateDrugs", policy)
                    .useSpringEL(false)
                    .build();

            XWPFTemplate template = XWPFTemplate.compile(bis, config).render(dm);
            bis.close();

            // 输出 word 文档到临时目录
            // String identifyItemsConfirmLetterWordFileName = AppStartupRunner.getCfg(CommonConstants.DLP_CODE_ENTRUSTMENT_TEMPORARY_PATH) + "/" + identifyItemsConfirmLetterFileName + ".docx";
            // FileOutputStream fosWord = new FileOutputStream(identifyItemsConfirmLetterWordFileName);
            ByteArrayOutputStream fosWord = new ByteArrayOutputStream();
            template.write(fosWord);
            template.close();

            //------------
            ByteArrayInputStream fisWord = new ByteArrayInputStream(fosWord.toByteArray());
            fosWord.close();

            // 转换临时目录中的 word 文档为 PDF
            MockMultipartFile mockMultipartFile = new MockMultipartFile("file", identifyItemsConfirmLetterFileName + ".docx", "image/jpg", fisWord);

            Response response = remoteWord2PDFService.word2pdf(mockMultipartFile);
            fisWord.close();

            ByteArrayOutputStream outPDF = new ByteArrayOutputStream();
            IoUtil.copy(response.body().asInputStream(), outPDF, IoUtil.DEFAULT_BUFFER_SIZE);
            ByteArrayInputStream isPDF = new ByteArrayInputStream(outPDF.toByteArray());
            outPDF.close();


            ossFile.fileSave(OSSDirectoryConstants.DOCUMENT_ENTRUSTMENT_DIRECTORY + "/" + ev.getId() + "/" + identifyItemsConfirmLetterFileName + ".pdf", isPDF);
            isPDF.close();


            System.out.println(String.format("转换为 PDF 结束"));

        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }

    @Override
    public Entrustment bizSubmitter_AddEntrustment(Entrustment entrustment, DLPUser dlpUser) {

        if (StringUtils.isNotEmpty(entrustment.getId())) {
            throw new RuntimeException("新创建的委托的 Id 必须为空, Id 应该由系统自动生成");
        }
        entrustment.setId(IdWorker.get32UUID().toUpperCase());

        if (StringUtils.isEmpty(entrustment.getCaseId())) {
            throw new RuntimeException("caseId 不能为空, 委托必须是基于某个案件");
        }
        CaseEvent cj = caseEventService.getById(entrustment.getCaseId());
        if (cj == null) {
            throw new RuntimeException(String.format("不存在 caseId 为 % 的案件", entrustment.getCaseId()));
        }
        entrustment.setStatus(EntrustmentStatusConstants.ENTRUSTMENT_STATUS_CREATED.getStatus());       // 初始状态为待提交
        entrustment.setPreviousStatus(EntrustmentStatusConstants.ENTRUSTMENT_STATUS_CREATED.getStatus());   // 老的状态也为待提交
        List<UpdateInfo> pis = entrustment.getProcessInfo();
        if (pis == null) {
            pis = new ArrayList<UpdateInfo>();
        }
        UpdateInfo pi = new UpdateInfo(dlpUser.getId(),
                dlpUser.getName(),
                dlpUser.getOrgId(),
                dlpUser.getOrgName(),
                "已创建",
                1, entrustment.getStatus(), true);
        pis.add(pi);
        entrustment.setProcessInfo(pis);
        entrustment.setSubmitter(dlpUser.getId());
        this.save(entrustment);
        return entrustment;

    }

    @Override
    public R deleteById(String id, DLPUser dlpUser) {
        if (StrUtil.isBlank(id)) {
            return R.failed("必须把委托 id 作为路径的一部分提供!");
        }
        Entrustment entrustment = this.getById(id);
        if (entrustment == null) {
            return R.failed(String.format("不存在 id 为 %s 的委托!", id));
        }

        if (!StrUtil.equalsIgnoreCase(dlpUser.getOrgId(), entrustment.getClientOrgId())) {
            return R.failed(String.format("这个委托的委托单位不是你的所属单位, 你无权删除!"));
        }

        if (entrustment.getStatus() != EntrustmentStatusConstants.ENTRUSTMENT_STATUS_CREATED.getStatus() ||
                entrustment.getPreviousStatus() != EntrustmentStatusConstants.ENTRUSTMENT_STATUS_CREATED.getStatus()) {
            return R.failed(String.format("这个委托已被提交过, 不能删除!"));
        }


        long entrustmentCount = entrustmentIdentificationMaterialService.countByEntrustmentId(id);
        if (entrustmentCount > 0) {
            return R.failed(String.format("这个委托下有 %d 个检材, 必须先删除全部检材后才能删除委托!", entrustmentCount));
        }

        List<String> attList = ossFile.fileList(OSSDirectoryConstants.ACCEPT_DIRECTORY + "/" + id);
        long attCount = attList.size();
        if (attCount > 0) {
            return R.failed(String.format("这个委托下有 %d 个附件, 必须先删除全部附件后才能删除委托!", attCount));
        }

        if (this.removeById(id)) {
            return R.ok(entrustment, "委托删除成功");
        } else {
            return R.failed(entrustment, "委托删除失败");
        }
    }

    @Override
    public R uploadAttachmentObj_Base64(String entrustmentId, JSONObject jsonParam) throws Exception {
        System.out.println(String.format("uploadPhotoObj: entrustmentId=%s jsonParam.size()=%d", entrustmentId, jsonParam.size()));
        Entrustment entrustment = this.getById(entrustmentId);
        if (entrustment != null) {

            String image = jsonParam.getString("image");
//			System.out.println(String.format("image=%s", image));
            if (StringUtils.isNotEmpty(image)) {
                try {
                    String suffix = image.substring(11, image.indexOf(";"));
                    String fileName = DateUtil.format(new Date(), "yyyyMMddHHmmss") + "." + suffix;
                    System.out.println(String.format("fileName=[%s]", fileName));

                    //去掉头信息
                    String imgBase64 = image.substring(image.indexOf(",") + 1);
                    byte[] decoded = org.apache.commons.codec.binary.Base64.decodeBase64(imgBase64);
                    InputStream is = new ByteArrayInputStream(decoded);

                    String path = OSSDirectoryConstants.ENTRUSTMENT_DIRECTORY + "/" + entrustmentId;
                    Map<String, String> ResultData = new HashMap<>();
                    ResultData.put("fileName", fileName);
                    ResultData.put("path", path);

                    boolean r = ossFile.fileSave(path + "/" + fileName, is);
                    if (r) {
                        return R.ok(ResultData, "上传成功");
                    }
                    return R.failed("上传失败");

                } catch (Exception e) {
                    e.printStackTrace();
                    return R.failed("上传失败");
                }
            } else {
                return R.failed("上传的数据中没有图像");
            }
        }
        return R.failed("不存在这个委托");
    }

    @Override
    public R uploadDeliverPhoto_Base64(String entrustmentId, JSONObject jsonParam) {
        Assert.notBlank(entrustmentId, "委托ID不能为空");
        //证件照片特殊文件标识
        String deliverPhoto = "deliverPhoto";
        String path = OSSDirectoryConstants.ACCEPT_DIRECTORY + "/" + entrustmentId + "/" + deliverPhoto;
        String image = jsonParam.getString("image");
        if (StringUtils.isNotEmpty(image)) {
            try {
                String suffix = image.substring(11, image.indexOf(";"));
                if (suffix.equals("jpeg")) {
                    suffix = "jpg";
                }
                //String fileName = DateUtil.format(new Date(), "yyyyMMddHHmmss") + "-"+(picCount+1)+"." + suffix;
                String fileName = IdWorker.get32UUID() + "." + suffix;
                System.out.println(String.format("fileName=[%s]", fileName));
                //去掉头信息
                String imgBase64 = image.substring(image.indexOf(",") + 1);
                byte[] decoded = org.apache.commons.codec.binary.Base64.decodeBase64(imgBase64);
                InputStream is = new ByteArrayInputStream(decoded);
                Map<String, String> ResultData = new HashMap<>();
                ResultData.put("fileName", fileName);
                ResultData.put("path", path);

                boolean r = ossFile.fileSave(path + "/" + fileName, is);
                if (r) {
                    return R.ok(ResultData, "上传成功");
                }
                return R.failed("上传失败");

            } catch (Exception e) {
                e.printStackTrace();
                return R.failed("上传失败");
            }
        } else {
            return R.failed("上传的数据中没有图像");
        }

    }

    @Override
    public R uploadAcceptAttachmentObj_Base64(String entrustmentId, JSONObject jsonParam) throws Exception {
        System.out.println(String.format("uploadPhotoObj: entrustmentId=%s jsonParam.size()=%d", entrustmentId, jsonParam.size()));
        Entrustment entrustment = this.getById(entrustmentId);
        if (entrustment != null) {

            String image = jsonParam.getString("image");
//			System.out.println(String.format("image=%s", image));
            if (StringUtils.isNotEmpty(image)) {
                try {
                    String suffix = image.substring(11, image.indexOf(";"));
                    String fileName = DateUtil.format(new Date(), "yyyyMMddHHmmss") + "." + suffix;
                    System.out.println(String.format("fileName=[%s]", fileName));

                    //去掉头信息
                    String imgBase64 = image.substring(image.indexOf(",") + 1);
                    byte[] decoded = org.apache.commons.codec.binary.Base64.decodeBase64(imgBase64);
                    InputStream is = new ByteArrayInputStream(decoded);

                    String path = OSSDirectoryConstants.ACCEPT_DIRECTORY + "/" + entrustmentId;
                    Map<String, String> ResultData = new HashMap<>();
                    ResultData.put("fileName", fileName);
                    ResultData.put("path", path);

                    boolean r = ossFile.fileSave(path + "/" + fileName, is);
                    if (r) {
                        return R.ok(ResultData, "上传成功");
                    }
                    return R.failed("上传失败");

                } catch (Exception e) {
                    e.printStackTrace();
                    return R.failed("上传失败");
                }
            } else {
                return R.failed("上传的数据中没有图像");
            }

        }
        return R.failed("不存在这个委托");
    }

    @Override
    public R<List<SysUser>> bizGetAvailableUserList(String entrustmentId) {

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

        if (entrustment.getStatus() == EntrustmentStatusConstants.ENTRUSTMENT_STATUS_CREATED.getStatus()) {
            // 在创建人手中: 已创建, 等待提交
//            return R.ok(this.taskAvailableUserList_Check());
            return R.ok(commonFeignService.remoteGetUsersByPermission(CommonConstants.ORG_TREE_ROOT_ID, CollUtil.newArrayList("EntrustmentCheck")));
        } else if (entrustment.getStatus() == EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_CHECK.getStatus()) {
            // 在审核员手中: 已提交, 待审核
//            return R.ok(this.taskAvailableUserList_Approve());
            return R.ok(commonFeignService.remoteGetUsersByPermission(CommonConstants.ORG_TREE_ROOT_ID, CollUtil.newArrayList("EntrustmentApprove")));
        } else if (entrustment.getStatus() == EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_APPROVE.getStatus()) {
            // 在审批员手中: 已审核, 待审批
//            return R.ok(this.taskAvailableUserList_Confirm(entrustment.getClientOrgId()));
            return R.ok(commonFeignService.remoteGetUsersByPermission(entrustment.getClientOrgId(), CollUtil.newArrayList("EntrustmentConfirm")));
        } else if (entrustment.getStatus() == EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_CONFIRM.getStatus()) {
            // 在确认者手中: 已审批, 待确认
            List<SysUser> users = new ArrayList<SysUser>();
            SysUser submitter = remoteUserService.innerGetById(entrustment.getSubmitter()).getData();
            users.add(submitter);
            return R.ok(users);
        } else if (entrustment.getStatus() == EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_DELIVER.getStatus()) {
            // 在送检提交员(创建者)手中: 已确认, 待送检
//            return R.ok(this.taskAvailableUserList_Accept());
            return R.ok(commonFeignService.remoteGetUsersByPermission(CommonConstants.ORG_TREE_ROOT_ID, CollUtil.newArrayList("EntrustmentAccept")));
        } else {
            return R.failed("委托在当前状态下不需要其他用户处理");
        }
    }

    @Override

    public List<MarkersVO> getImQuantityForInspection(DLPUser dlpUser) {

        List<MarkersVO> markersVOS = new ArrayList<>();
        String orgId = dlpUser.getOrgId();

        Integer entrustmentIdentificationMaterialQuantity = 0;
        Integer acceptanceIdentificationMaterialQuantity = 0;
        Integer sewageJobIdentificationMaterialQuantity = 0;
        Integer hairJobIdentificationMaterialQuantity = 0;

        //查询这个账户（机构）下的所有委托中的所有已受理检材的数量
        List<Entrustment> entrustmentList = this.list(new LambdaQueryWrapper<Entrustment>().eq(Entrustment::getClientOrgId, orgId));
        for (Entrustment entrustment : entrustmentList) {
            List<EntrustmentIdentificationMaterial> entrustmentIdentificationMaterialList = entrustmentIdentificationMaterialService.list(new LambdaQueryWrapper<EntrustmentIdentificationMaterial>().eq(EntrustmentIdentificationMaterial::getEntrustmentId, entrustment.getId())
                    .eq(EntrustmentIdentificationMaterial::getAcceptPassed, 1));
            entrustmentIdentificationMaterialQuantity += entrustmentIdentificationMaterialList.size();
        }

        markersVOS.add(new MarkersVO("案件委托检材", entrustmentIdentificationMaterialQuantity, "", "EntrustmentCreate"));

        R<Integer> imQuantity = remoteSewageJobService.getIMQuantity(dlpUser.getOrgId());
        if (imQuantity.getCode() == CommonConstants.SUCCESS) {
            sewageJobIdentificationMaterialQuantity = imQuantity.getData();
        } else {
            log.error("查询这个账户（机构）下面所送检且已受理的所有污水检材的数量 失败！失败原因：{}", imQuantity.getMsg());
            sewageJobIdentificationMaterialQuantity = 0;
        }
        markersVOS.add(new MarkersVO("污水送检检材", sewageJobIdentificationMaterialQuantity, "", "SewageJobGet"));

        try {
            R<Integer> sampleQuantity = remoteHairJobService.getSampleQuantity(orgId, 2);
            if (sampleQuantity.getCode() == 0) {
                hairJobIdentificationMaterialQuantity = sampleQuantity.getData();
                markersVOS.add(new MarkersVO("毛发送检检材", hairJobIdentificationMaterialQuantity, "", "HairJobGet"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            R<Integer> data = remoteAcceptanceService.getEventByUser(dlpUser.getId());
            if (data.getCode() == 0) {
                acceptanceIdentificationMaterialQuantity = data.getData();
                markersVOS.add(new MarkersVO("事件送检检材", acceptanceIdentificationMaterialQuantity, "", "ima_event"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return markersVOS;
    }

    @Override//创建一个委托(现在的顺序是创建委托——创建案件——创建检材(物证选填))
    public Entrustment addNewEmt(EntrustmentDTO entrustmentDTO, DLPUser dlpUser) {
        if (StringUtils.isNotEmpty(entrustmentDTO.getId())) {
            throw new RuntimeException("新创建的委托的 Id 必须为空, Id 应该由系统自动生成");
        }

        if (!StringUtils.isEmpty(entrustmentDTO.getCaseId())) {
            throw new RuntimeException("caseId 必须为空");
        }
        //开始创建案件
        CaseEvent caseEvent = new CaseEvent();
        caseEvent.setCaseName(entrustmentDTO.getCaseName());
        caseEvent.setCaseBrief(entrustmentDTO.getCaseBrief());
        caseEvent.setHappenTime(entrustmentDTO.getHappenTime());
        caseEvent.setCaseOwnOrgId(entrustmentDTO.getClientOrgId());

        if (StrUtil.isBlank(caseEvent.getCaseNo())) {
            // 如果没有提供案件编码, 生成一个

            if ((caseEvent.getHappenTime() != null) && (StrUtil.isNotBlank(caseEvent.getCaseOwnOrgId()))) {
                SysOrg caseOwnOrg = null;
                R r = remoteOrgService.getById(caseEvent.getCaseOwnOrgId());
                if (r.getCode() == CommonConstants.SUCCESS) {
                    caseOwnOrg = (SysOrg) r.getData();
//                    Date happenTime = Date.from(caseEvent.getHappenTime().atZone(ZoneId.systemDefault()).toInstant());

                    caseEvent.setCaseNo(caseEventService.getNewCaseCode(caseOwnOrg.getOrgCode(), caseEvent.getHappenTime()));
                } else {
                    throw new RuntimeException(String.format("没有找到 orgId 为 %s 的机构, 请确认案件所属机构(CaseOwnOrg)的正确性!", caseEvent.getCaseOwnOrgId()));
                }
            }
        }
        caseEvent.setId(IdWorker.get32UUID().toUpperCase());

        caseEventService.save(caseEvent);

        entrustmentDTO.setStatus(EntrustmentStatusConstants.ENTRUSTMENT_STATUS_CREATED.getStatus());       // 初始状态为待提交
        entrustmentDTO.setPreviousStatus(EntrustmentStatusConstants.ENTRUSTMENT_STATUS_CREATED.getStatus());   // 老的状态也为待提交
        List<UpdateInfo> pis = entrustmentDTO.getProcessInfo();
        if (pis == null) {
            pis = new ArrayList<UpdateInfo>();
        }
        UpdateInfo pi = new UpdateInfo(dlpUser.getId(),
                dlpUser.getName(),
                dlpUser.getOrgId(),
                dlpUser.getOrgName(),
                "已创建",
                1, entrustmentDTO.getStatus(), true);
        pis.add(pi);
        entrustmentDTO.setProcessInfo(pis);
        entrustmentDTO.setSubmitter(dlpUser.getId());
        //将DTO的数据赋值给实体类
        Entrustment entrustment = new Entrustment();
        BeanUtils.copyProperties(entrustmentDTO, entrustment);
        entrustment.setClientOrgId(entrustmentDTO.getClientOrgId());
        entrustment.setClientOrgName(entrustmentDTO.getClientOrgName());
        entrustment.setId(IdWorker.get32UUID().toUpperCase());
        entrustment.setCaseId(caseEvent.getId());
        this.save(entrustment);
        return entrustment;

    }

    @Override//获得送检页面全局小红点
    public List<MarkersVO> getInspectMarkers(DLPUser dlpUser) {

        String orgId = dlpUser.getOrgId();

        List<MarkersVO> sewageMarkers = new ArrayList<>();
        R<List<MarkersVO>> sewageMarkersR = remoteSewageJobService.getSewageMarkers(dlpUser.getOrgId());
        if (sewageMarkersR.getCode() == CommonConstants.SUCCESS) {
            sewageMarkers = sewageMarkersR.getData();
        } else {
            log.error("调用污水系统查询各个状态下的污水检材数量失败！失败原因：{}", sewageMarkersR.getMsg());
        }


        ArrayList<MarkersVO> markersVOS = new ArrayList<>();

        markersVOS.addAll(sewageMarkers);

        List<Entrustment> entrustmentList1 = this.list(new LambdaQueryWrapper<Entrustment>().eq(Entrustment::getClientOrgId, orgId)
                .eq(Entrustment::getStatus, EntrustmentStatusConstants.ENTRUSTMENT_STATUS_CREATED.getStatus()));
        markersVOS.add(new MarkersVO("案件委托", entrustmentList1.size(), "待提交"));

        List<Entrustment> entrustmentList2 = this.list(new LambdaQueryWrapper<Entrustment>().eq(Entrustment::getClientOrgId, orgId)
                .in(Entrustment::getStatus, EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_DELIVER.getStatus(), EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_CONFIRM.getStatus()));
        markersVOS.add(new MarkersVO("案件委托", entrustmentList2.size(), "待送检"));

        List<Entrustment> entrustmentList3 = this.list(new LambdaQueryWrapper<Entrustment>().eq(Entrustment::getClientOrgId, orgId)
                .eq(Entrustment::getReturnOrNot, -1));
        markersVOS.add(new MarkersVO("案件委托", entrustmentList3.size(), "已退回"));

        List<Entrustment> entrustmentList4 = this.list(new LambdaQueryWrapper<Entrustment>().eq(Entrustment::getClientOrgId, orgId)
                .eq(Entrustment::getStatus, EntrustmentStatusConstants.ENTRUSTMENT_STATUS_COMPLETED.getStatus()));
        markersVOS.add(new MarkersVO("案件委托", entrustmentList4.size(), "已完成"));

        Integer entrustAlterApplyCount = (int) entrustAlterApplyService.count(Wrappers.<EntrustAlterApply>lambdaQuery()
                .eq(EntrustAlterApply::getStatus, EntrustAlterApplyStatus.APPLY_SUCCESS.getStatus())
                .eq(EntrustAlterApply::getApplyOrgId, orgId));
        markersVOS.add(new MarkersVO("案件委托", entrustAlterApplyCount, "委托申请修改"));

        try {
            R<Integer> data1 = remoteHairJobService.getJobQuantity(orgId, 0);
            if (data1.getCode() == 0) {
                markersVOS.add(new MarkersVO("毛发任务", data1.getData(), "待发布"));
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            R<Integer> data2 = remoteHairJobService.getJobQuantity(orgId, 1);
            if (data2.getCode() == 0) {
                markersVOS.add(new MarkersVO("毛发任务", data2.getData(), "已发布"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            R<Integer> data3 = remoteHairJobService.getJobQuantity(orgId, -2);
            if (data3.getCode() == 0) {
                markersVOS.add(new MarkersVO("毛发任务", data3.getData(), "被拒收"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            R<Integer> data4 = remoteAcceptanceService.getEventQuantity(dlpUser.getId(), 0, 0);
            R<Integer> data5 = remoteAcceptanceService.getEventQuantity(dlpUser.getId(), 1, 0);
            if (data4.getCode() == 0 && data5.getCode() == 0) {
                markersVOS.add(new MarkersVO("事件送检", data4.getData() + data5.getData(), "待处理"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            R<Integer> data6 = remoteAcceptanceService.getEventQuantity(dlpUser.getId(), 2, 0);
            if (data6.getCode() == 0) {
                markersVOS.add(new MarkersVO("事件送检", data6.getData(), "已受理"));
            }

        } catch (Exception e) {
            e.printStackTrace();

        }
        return markersVOS;
    }


    @Override
    public List<MarkersVO> getImQuantityForAccept() {

        ArrayList<MarkersVO> markersVOS = new ArrayList<>();

        markersVOS.add(new MarkersVO("司法鉴定委托", entrustmentIdentificationMaterialService.list(new LambdaQueryWrapper<EntrustmentIdentificationMaterial>()
                .eq(EntrustmentIdentificationMaterial::getAcceptPassed, 1)).size(), "", "EntrustmentAccept"));
        Integer imQuantityForAccept = 0;
        R<Integer> imQuantityForAcceptR = remoteSewageJobService.getImQuantityForAccept();
        if (imQuantityForAcceptR.getCode() == CommonConstants.SUCCESS) {
            imQuantityForAccept = imQuantityForAcceptR.getData();
        } else {
            log.error("受理系统统计已受理的污水检材数量接口数据获取失败！失败原因：{}", imQuantityForAcceptR.getMsg());
        }
        markersVOS.add(new MarkersVO("污水任务", imQuantityForAccept, "", "SewageJobCreate"));


        try {
            R<Integer> data = remoteAcceptanceService.getImQuantityForAccept();
            if (data.getCode() == 0) {
                markersVOS.add(new MarkersVO("事件委托", data.getData(), "", "ima_event_im"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            R<Integer> data1 = remoteHairJobService.getSampleQuantityForAccept();
            if (data1.getCode() == 0) {
                markersVOS.add(new MarkersVO("毛发任务", data1.getData(), "", "HairJobSampleAccept"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            R<Integer> data2 = remoteFeatureAnalysis.getReceivedImQuantity("received");
            if (data2.getCode() == 0) {
                markersVOS.add(new MarkersVO("特征分析", data2.getData(), "", "FeatureAnalysisAllPermission"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return markersVOS;

    }

    @Override
    public List<MarkersVO> getMarkersForOther(DLPUser dlpUser) {

        List<MarkersVO> markersVOS = new ArrayList<>();

        try {
            R<Integer> data3 = remoteHairJobService.getJobQuantity("0", null);
            if (data3.getCode() == 0) {
                markersVOS.add(new MarkersVO("毛发任务受理", data3.getData(), "毛发任务"));
                markersVOS.add(new MarkersVO("毛发任务受理", data3.getData(), "毛发受理"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            R<Integer> data4 = remoteHairJobService.getJobGabQuantity();
            if (data4.getCode() == 0) {
                markersVOS.add(new MarkersVO("毛发任务受理", data4.getData(), "毛发抽样"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            R<Integer> data = remoteAcceptanceService.getEventQuantity(dlpUser.getId(), 1, 1);
            if (data.getCode() == 0) {
                markersVOS.add(new MarkersVO("事件受理", data.getData(), "待处理"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            R<Integer> data1 = remoteAcceptanceService.getEventQuantity(dlpUser.getId(), 2, 1);
            if (data1.getCode() == 0) {
                markersVOS.add(new MarkersVO("事件受理", data1.getData(), "已受理"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            R<Integer> data2 = remoteFeatureAnalysis.getJobQuantity();
            if (data2.getCode() == 0) {
                markersVOS.add(new MarkersVO("特征分析", data2.getData(), "特征分析"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


        return markersVOS;
    }

    /**
     * 获得委托的小红点标记
     *
     * @return
     */
    @Override
    public List<MarkersVO> getMarkersForEntrustment() {

        List<MarkersVO> markersVOS = new ArrayList<>();

        List<Entrustment> entrustmentList1 = this.list(new LambdaQueryWrapper<Entrustment>()
                .eq(Entrustment::getDataSources, 0)
                .eq(Entrustment::getStatus, EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_ACCEPT.getStatus()));

        List<Entrustment> entrustmentList2 = this.list(new LambdaQueryWrapper<Entrustment>()
                .eq(Entrustment::getDataSources, 1)
                .eq(Entrustment::getStatus, EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_ACCEPT.getStatus()));

        List<Entrustment> entrustmentList3 = this.list(new LambdaQueryWrapper<Entrustment>()
                .eq(Entrustment::getDataSources, 0)
                .eq(Entrustment::getStatus, EntrustmentStatusConstants.ENTRUSTMENT_STATUS_ACCEPTED.getStatus()));

        List<Entrustment> entrustmentList4 = this.list(new LambdaQueryWrapper<Entrustment>()
                .eq(Entrustment::getDataSources, 1)
                .eq(Entrustment::getStatus, EntrustmentStatusConstants.ENTRUSTMENT_STATUS_ACCEPTED.getStatus()));

        List<Integer> integers1 = new ArrayList<>();
        List<Integer> integers2 = new ArrayList<>();
        integers1.add(1);
        integers1.add(2);
        integers2.add(3);
        integers2.add(4);
        // 创建一个污水系统的统计DTO 初始化统计数量为0
        StatisticsDiffStatusJobDTO statisticsDiffStatusSewageJobDTO = new StatisticsDiffStatusJobDTO(
                0, 0, 0, 0, 0);
        R<StatisticsDiffStatusJobDTO> statisticsDiffStatusJobDTOR = remoteSewageJobService.statisticsDiffStatusJob();
        if (statisticsDiffStatusJobDTOR.getCode() == CommonConstants.SUCCESS) {
            statisticsDiffStatusSewageJobDTO = statisticsDiffStatusJobDTOR.getData();
        } else {
            log.error("通过查询接口调用获取污水系统统计数据失败！失败原因：{}", statisticsDiffStatusJobDTOR.getMsg());
        }

        ArrayList<Integer> integers = new ArrayList<>();
        integers.add(2);
        markersVOS.add(new MarkersVO(EntrustMarkConstants.CASE_ACCEPT, entrustmentList1.size(), String.format("待受理（%s）", EntrustMarkConstants.PUBLIC_SECURITY_BUREAU)));
        markersVOS.add(new MarkersVO(EntrustMarkConstants.CASE_ACCEPT, entrustmentList2.size(), "待受理 (大数据平台)"));
        markersVOS.add(new MarkersVO(EntrustMarkConstants.CASE_ACCEPT, entrustmentList3.size(), String.format("已受理 (%s)", EntrustMarkConstants.PUBLIC_SECURITY_BUREAU)));
        markersVOS.add(new MarkersVO(EntrustMarkConstants.CASE_ACCEPT, entrustmentList4.size(), "已受理 (大数据平台)"));
        markersVOS.add(new MarkersVO(EntrustMarkConstants.CASE_ACCEPT, this.list(Wrappers.<Entrustment>lambdaQuery().inSql(Entrustment::getId, "SELECT entrust_id FROM b_entrust_material_checkout_result")).size(), "检测结果"));
        markersVOS.add(new MarkersVO(EntrustMarkConstants.REVIEW_OR_APPROVAL,
                this.list(new LambdaQueryWrapper<Entrustment>()
                        .in(Entrustment::getStatus, integers1)
                        .eq(Entrustment::getDataSources, 0)).size(), String.format("委托审核(%s)", EntrustMarkConstants.PUBLIC_SECURITY_BUREAU)));
        markersVOS.add(new MarkersVO(EntrustMarkConstants.REVIEW_OR_APPROVAL,
                this.list(new LambdaQueryWrapper<Entrustment>()
                        .in(Entrustment::getStatus, integers2)
                        .eq(Entrustment::getDataSources, 0)).size(), String.format("委托审批(%s)", EntrustMarkConstants.PUBLIC_SECURITY_BUREAU)));
        markersVOS.add(new MarkersVO(EntrustMarkConstants.REVIEW_OR_APPROVAL,
                this.list(new LambdaQueryWrapper<Entrustment>()
                        .in(Entrustment::getStatus, integers1)
                        .eq(Entrustment::getDataSources, 1)).size(), "委托审核(大数据平台)"));
        markersVOS.add(new MarkersVO(EntrustMarkConstants.REVIEW_OR_APPROVAL,
                this.list(new LambdaQueryWrapper<Entrustment>()
                        .in(Entrustment::getStatus, integers2)
                        .eq(Entrustment::getDataSources, 1)).size(), "委托审批(大数据平台)"));
        markersVOS.add(new MarkersVO(EntrustMarkConstants.REVIEW_OR_APPROVAL,
                (int) entrustAlterApplyService.count(Wrappers.<EntrustAlterApply>lambdaQuery()
                        .eq(EntrustAlterApply::getStatus, EntrustAlterApplyStatus.SUBMITTED_WAIT_APPROVE.getStatus())),
                "委托修改审核"));
        markersVOS.add(new MarkersVO(EntrustMarkConstants.SEWAGE_JOB_ACCEPT, statisticsDiffStatusSewageJobDTO.getJobStatusCreatedNum(), "污水任务待发布"));
        markersVOS.add(new MarkersVO(EntrustMarkConstants.SEWAGE_JOB_ACCEPT, statisticsDiffStatusSewageJobDTO.getJobStatusClaimNum(), "污水任务已发布"));
        markersVOS.add(new MarkersVO(EntrustMarkConstants.SEWAGE_JOB_ACCEPT, statisticsDiffStatusSewageJobDTO.getJobStatusClaimNum(), "污水受理"));
        markersVOS.add(new MarkersVO(EntrustMarkConstants.SEWAGE_JOB_ACCEPT, statisticsDiffStatusSewageJobDTO.getSewageTreatmentPlantNum(), "污水厂管理"));

        return markersVOS;
    }

    /**
     * 获得需要打印的检材信息
     *
     * @return
     */
    public List<EntrustmentIdentificationMaterial> getAllSampleForPrint() {
        List<EntrustmentIdentificationMaterial> entrustmentIdentificationMaterials = new ArrayList<>();
        List<Entrustment> entrustmentList = this.list(Wrappers.<Entrustment>lambdaQuery()
                .ge(Entrustment::getStatus, EntrustmentStatusConstants.ENTRUSTMENT_STATUS_ACCEPTED)
                .orderByAsc(Entrustment::getAcceptNo));

        for (Entrustment entrustment : entrustmentList) {
            List<EntrustmentIdentificationMaterial> entrustmentIdentificationMaterialList = entrustmentIdentificationMaterialService.list(Wrappers.<EntrustmentIdentificationMaterial>lambdaQuery()
                    .eq(EntrustmentIdentificationMaterial::getEntrustmentId, entrustment.getId())
                    .orderByAsc(EntrustmentIdentificationMaterial::getAcceptNo));
            if (entrustmentIdentificationMaterialList.size() > 0) {
                if (entrustmentIdentificationMaterialList.size() > 18) {
                    int remainder = entrustmentIdentificationMaterialList.size() % 18;
                    if (remainder != 0) {
                        int index = 18 - remainder;
                        for (int i = 0; i < index; i++) {
                            EntrustmentIdentificationMaterial entrustmentIdentificationMaterial = getEntrustmentIdentificationMaterial();
                            entrustmentIdentificationMaterialList.add(entrustmentIdentificationMaterial);
                        }
                    }
                } else {
                    int remainder = 18 - entrustmentIdentificationMaterialList.size();
                    for (int i = 0; i < remainder; i++) {
                        EntrustmentIdentificationMaterial entrustmentIdentificationMaterial = getEntrustmentIdentificationMaterial();
                        entrustmentIdentificationMaterialList.add(entrustmentIdentificationMaterial);
                    }
                }
                for (int i = 0; i < entrustmentIdentificationMaterialList.size(); i++) {
                    EntrustmentIdentificationMaterial entrustmentIdentificationMaterial = entrustmentIdentificationMaterialList.get(i);
                    if (StringUtils.isNotBlank(entrustmentIdentificationMaterial.getAcceptNo())) {
                        entrustmentIdentificationMaterial.setOrderNo(i + 1);
                    }
                    entrustmentIdentificationMaterial.setPersonNationality(LocalDateTimeUtil.format(entrustmentIdentificationMaterial.getAcceptTime(), "yyyy-MM-dd"));
                }
                entrustmentIdentificationMaterials.addAll(entrustmentIdentificationMaterialList);
            }
        }
        return entrustmentIdentificationMaterials;
    }

    /**
     * 打印样本档案
     *
     * @param entrustmentId
     * @throws Exception
     */
    @Override
    public void printSampleFile(String entrustmentId) throws Exception {
    }

    /**
     * 通过检材的类别设置委托的类别(生物样本、缴获物)
     *
     * @return
     */
    @Override
    public boolean synchronizationByMaterialType() {
        List<Entrustment> entrustmentList = this.list(Wrappers.<Entrustment>lambdaQuery().eq(Entrustment::getDataSources, 1));
        ArrayList<Entrustment> list = new ArrayList<>();
        entrustmentList.forEach(item -> {
            EntrustOfThirdSys entrustOfThirdSys = synchronizeDataService.getOne(Wrappers.<EntrustOfThirdSys>lambdaQuery().eq(EntrustOfThirdSys::getEntrustMainId, item.getId()));
            if (entrustOfThirdSys != null && StrUtil.isNotBlank(entrustOfThirdSys.getMaterialType())) {
                String materialType = entrustOfThirdSys.getMaterialType();
                if (materialType.equals("inVitro")) {
                    item.setEntrustmentType(0);
                } else if (materialType.equals("inVivo")) {
                    item.setEntrustmentType(1);
                } else {
                    item.setEntrustmentType(2);
                }
                list.add(item);
            }
        });
        return this.updateBatchById(list);
    }

    /**
     * 获得委托与检材信息
     *
     * @param page
     * @param status
     * @param keywords
     * @return
     */
    @Override
    public IPage getEntrustmentAndMaterial(Page page, Integer status, String keywords) {
        IPage<EntrustmentVO> voPage = this.getEntrustmentVOPage(page, Wrappers.<Entrustment>query()
                .and(StrUtil.isNotBlank(keywords), wrapper -> wrapper
                        .like("e.entrustment_no", keywords)
                        .or()
                        .like("e.accept_no", keywords)
                        .or()
                        .like("c.case_name", keywords))
                .eq("status", status)
                .orderByDesc("accept_no")
        );

        List<EntrustmentVO> records = voPage.getRecords();

        for (EntrustmentVO entrustmentVO : records) {
            List<EntrustmentIdentificationMaterial> materialList = entrustmentIdentificationMaterialService
                    .list(Wrappers.<EntrustmentIdentificationMaterial>lambdaQuery()
                            .eq(EntrustmentIdentificationMaterial::getEntrustmentId, entrustmentVO.getId())
                            .orderByAsc(EntrustmentIdentificationMaterial::getAcceptNo));
            entrustmentVO.setMaterialList(materialList);
        }
        return voPage;
    }

    /**
     * 判断是否已经生成好了检材照片，如果生成了，返回给前端true 如果没有就返回false
     *
     * @param entrustmentId
     * @return
     */
    @Override
    public boolean isMaterialPhoto(String entrustmentId) {
        String path = "document/accept" + "/" + entrustmentId + "/materialPhoto";
        List<String> fileName = ossFile.fileList(path);
        if (fileName.size() > 0) {
            return true;
        } else return false;
    }

    /**
     * 根据委托时间去取 年月日 修改一些时间类型的字段信息，例如 submit_time、check_claim_time、check_time、approve_claim_time、approve_time、"
     * deliver_confirm_time、accept_claim_time、accept_time、create_time以及process_info字段中的time类型的数据
     *
     * @param entrustment
     * @return
     */
    @Override
    public boolean alertTimeFiledInfoByEntrustDate(Entrustment entrustment) {
        Entrustment entrust = super.getById(entrustment.getId());
        LocalDateTime entrustTime = entrust.getEntrustmentTime();
        if (entrustTime == null) {
            throw new ValidateCodeException("该委托信息中的委托时间为空！");
        }
        // 获取年月日的数值
        int year = entrustTime.getYear();
        int monthValue = entrustTime.getMonthValue();
        int dayValue = entrustTime.getDayOfMonth();

        // 开始更新信息
        // 定义解析的格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        List<UpdateInfo> processInfoList = JSONArray.parseArray(JSONObject.toJSONString(entrust.getProcessInfo()), UpdateInfo.class);
        processInfoList.forEach(process ->
                process.setProcessTime(
                        LocalDateTime.parse(process.getProcessTime(), formatter)
                                .withYear(year).withMonth(monthValue).withDayOfMonth(dayValue)
                                .format(formatter)
                ));
        entrust.setSubmitTime(entrust.getSubmitTime().withYear(year).withMonth(monthValue).withDayOfMonth(dayValue));
        entrust.setCheckClaimTime(entrust.getCheckClaimTime().withYear(year).withMonth(monthValue).withDayOfMonth(dayValue));
        entrust.setCheckTime(entrust.getCheckTime().withYear(year).withMonth(monthValue).withDayOfMonth(dayValue));
        entrust.setApproveClaimTime(entrust.getApproveClaimTime().withYear(year).withMonth(monthValue).withDayOfMonth(dayValue));
        entrust.setApproveTime(entrust.getApproveTime().withYear(year).withMonth(monthValue).withDayOfMonth(dayValue));
        entrust.setDeliverConfirmTime(entrust.getDeliverConfirmTime().withYear(year).withMonth(monthValue).withDayOfMonth(dayValue));
        entrust.setAcceptTime(entrust.getAcceptTime().withYear(year).withMonth(monthValue).withDayOfMonth(dayValue));
        entrust.setCreateTime(entrust.getCreateTime().withYear(year).withMonth(monthValue).withDayOfMonth(dayValue));
        entrust.setProcessInfo(processInfoList);
        return super.updateById(entrust);
    }

    /**
     * 判断当前保存的委托检材数量是否符合，决定是否可以提交委托审核
     *
     * @param entrustId     委托id
     * @param materialCount 当前用户所在的检材页面检材数量
     * @return
     */
    @Override
    public Boolean isEligibleForSubmission(String entrustId, Integer materialCount) {
        int count = (int) entrustmentIdentificationMaterialService.count(Wrappers.<EntrustmentIdentificationMaterial>lambdaQuery().eq(EntrustmentIdentificationMaterial::getEntrustmentId, entrustId));
        return materialCount.equals(count);
    }


    private Deliverer getDeliverer2(Entrustment entrust, DLPUser dlpUser) {
        Deliverer deliverer2 = new Deliverer();
        deliverer2.setOwnerUserId(dlpUser.getId());
        deliverer2.setName(entrust.getDeliverer2Name());
        deliverer2.setPosition(entrust.getDeliverer2Position());
        deliverer2.setCert(entrust.getDeliverer2Cert());
        deliverer2.setIdnum(entrust.getDeliverer2Id());
        deliverer2.setPhone(entrust.getDeliverer2Phone());
        return deliverer2;
    }

    private Deliverer getDeliverer1(Entrustment entrust, DLPUser dlpUser) {
        Deliverer deliverer1 = new Deliverer();
        deliverer1.setOwnerUserId(dlpUser.getId());
        deliverer1.setName(entrust.getDeliverer1Name());
        deliverer1.setPosition(entrust.getDeliverer1Position());
        deliverer1.setCert(entrust.getDeliverer1Cert());
        deliverer1.setIdnum(entrust.getDeliverer1Id());
        deliverer1.setPhone(entrust.getDeliverer1Phone());
        return deliverer1;
    }

    private EntrustmentIdentificationMaterial getEntrustmentIdentificationMaterial() {
        EntrustmentIdentificationMaterial entrustmentIdentificationMaterial = new EntrustmentIdentificationMaterial();
        entrustmentIdentificationMaterial.setAcceptNo("");
        entrustmentIdentificationMaterial.setOrderNo(null);
        entrustmentIdentificationMaterial.setTypeName("");
        entrustmentIdentificationMaterial.setFormName("");
        entrustmentIdentificationMaterial.setFundName("");
        entrustmentIdentificationMaterial.setAcceptTime(null);
        return entrustmentIdentificationMaterial;
    }

    /**
     * 根据给定的DLP用户获取相关的配送员信息。
     *
     * @param dlpUser DLP用户对象，用于获取组织ID。
     * @return 返回包含两个配送员信息的列表；如果没有找到相关记录，则返回null。
     */
    @Override
    public List<Deliverer> getDelivererList(DLPUser dlpUser) {
        // 从DLP用户对象中获取组织ID
        String orgId = dlpUser.getOrgId();

        // 查询数据库以获取与当前组织ID匹配且有指定配送员信息的委托记录列表，
        // 按创建时间降序排列。
        List<Entrustment> list = this.list(Wrappers.<Entrustment>lambdaQuery()
                .eq(Entrustment::getClientOrgId, orgId)
                .isNotNull(Entrustment::getDeliverer1Name) // 确保第一个配送员名字不为空
                .isNotNull(Entrustment::getDeliverer2Name) // 确保第二个配送员名字不为空
                .orderByDesc(Entrustment::getCreateTime)); // 按创建时间降序

        // 如果查询结果不为空且至少有一个条目
        if (list != null && list.size() > 0) {
            Entrustment entrustment = list.get(0); // 获取最新的一条记录

            List<Deliverer> deliverers = new ArrayList<>(); // 创建一个列表来保存配送员信息

            // 设置第一个配送员的信息，并加入到列表中
            Deliverer deliverer1 = new Deliverer();
            deliverer1.setCert(entrustment.getDeliverer1Cert());
            deliverer1.setName(entrustment.getDeliverer1Name());
            deliverer1.setPhone(entrustment.getDeliverer1Phone());
            deliverer1.setPosition(entrustment.getDeliverer1Position());
            deliverer1.setId(entrustment.getDeliverer1Id());

            // 设置第二个配送员的信息，并加入到列表中
            Deliverer deliverer2 = new Deliverer();
            deliverer2.setCert(entrustment.getDeliverer2Cert());
            deliverer2.setName(entrustment.getDeliverer2Name());
            deliverer2.setPhone(entrustment.getDeliverer2Phone());
            deliverer2.setPosition(entrustment.getDeliverer2Position());
            deliverer2.setId(entrustment.getDeliverer2Id());

            deliverers.add(deliverer1);
            deliverers.add(deliverer2);

            return deliverers; // 返回包含两个配送员信息的列表
        } else {
            return null; // 如果没有找到相关记录，则返回null
        }
    }

}
