package digital.laboratory.platform.entrustment.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.amazonaws.services.s3.model.AmazonS3Exception;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import digital.laboratory.platform.common.core.constant.CommonConstants;
import digital.laboratory.platform.common.core.constant.OSSDirectoryConstants;
import digital.laboratory.platform.common.core.util.R;
import digital.laboratory.platform.common.core.util.TestUtils;
import digital.laboratory.platform.common.feign.RemoteTemplate2htmlService;
import digital.laboratory.platform.common.log.annotation.SysLog;
import digital.laboratory.platform.common.mybatis.security.service.DLPUser;
import digital.laboratory.platform.common.oss.service.OssFile;
import digital.laboratory.platform.entrustment.dto.PrintDTO;
import digital.laboratory.platform.entrustment.dto.SampleBoxDTO;
import digital.laboratory.platform.entrustment.entity.CaseEvent;
import digital.laboratory.platform.entrustment.entity.CaseEvidence;
import digital.laboratory.platform.entrustment.entity.Entrustment;
import digital.laboratory.platform.entrustment.entity.EntrustmentIdentificationMaterial;
import digital.laboratory.platform.entrustment.enums.EntrustmentStatusConstants;
import digital.laboratory.platform.entrustment.handler.AppStartupRunner;
import digital.laboratory.platform.entrustment.service.CaseEventService;
import digital.laboratory.platform.entrustment.service.CaseEvidenceService;
import digital.laboratory.platform.entrustment.service.EntrustmentIdentificationMaterialService;
import digital.laboratory.platform.entrustment.service.EntrustmentService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.activation.MimetypesFileTypeMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.security.Principal;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 检材信息
 *
 * @author Zhang Xiaolong created at  2022-03-22
 * @describe 检材信息 前端控制器
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/papp/entrustment/entrustment_identification_material")
@Api(tags = "004-检材管理")
public class EntrustmentIdentificationMaterialController {

    private final CaseEventService caseEventService;

    private final EntrustmentService entrustmentService;

    private final EntrustmentIdentificationMaterialService entrustmentIdentificationMaterialService;

    private final CaseEvidenceService caseEvidenceService;

    private final OssFile ossFile;

    private final RemoteTemplate2htmlService remoteTemplate2htmlService;

    /**
     * 通过id查询检材信息
     *
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id查询", notes = "通过id查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "检材标识", required = true, paramType = "path"),
    })
    @GetMapping("/{id}")
    @PreAuthorize("@pms.hasPermission('EntrustmentIdentificationMaterialGet')")
    public R<EntrustmentIdentificationMaterial> getById(@PathVariable("id") String id) {
        return R.ok(entrustmentIdentificationMaterialService.getById(id));
    }


    /**
     * 分页查询
     *
     * @param page                              分页对象
     * @param entrustmentIdentificationMaterial 检材信息
     * @return
     */
    @ApiOperation(value = "分页查询", notes = "分页查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "页信息", required = true, paramType = "query"),
            @ApiImplicitParam(name = "entrustmentIdentificationMaterial", value = "查询条件", required = true, paramType = "query"),
    })
    @GetMapping("/page")
    @PreAuthorize("@pms.hasPermission('EntrustmentIdentificationMaterialList')")
    public R getEntrustmentIdentificationMaterialPage(
            Page<EntrustmentIdentificationMaterial> page,
            EntrustmentIdentificationMaterial entrustmentIdentificationMaterial) {
        return R.ok(entrustmentIdentificationMaterialService.page(page, new LambdaQueryWrapper<EntrustmentIdentificationMaterial>()
                .eq(EntrustmentIdentificationMaterial::getEntrustmentId, entrustmentIdentificationMaterial.getEntrustmentId())
                .eq(StrUtil.isNotBlank(entrustmentIdentificationMaterial.getImNo()), EntrustmentIdentificationMaterial::getImNo, entrustmentIdentificationMaterial.getImNo())
                .eq(StrUtil.isNotBlank(entrustmentIdentificationMaterial.getColor()), EntrustmentIdentificationMaterial::getColor, entrustmentIdentificationMaterial.getColor())
                .eq(StrUtil.isNotBlank(entrustmentIdentificationMaterial.getName()), EntrustmentIdentificationMaterial::getName, entrustmentIdentificationMaterial.getName())
                .orderByAsc(EntrustmentIdentificationMaterial::getOrderNo)));
    }

    /**
     * 列表查询
     *
     * @param entrustmentIdentificationMaterial 检材信息
     * @return
     */
    @ApiOperation(value = "列表查询", notes = "列表查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "entrustmentIdentificationMaterial", value = "查询条件", required = true, paramType = "query"),
    })
    @GetMapping("/list")
    @PreAuthorize("@pms.hasPermission('EntrustmentIdentificationMaterialList')")
    public R<List<EntrustmentIdentificationMaterial>> getEntrustmentIdentificationMaterialList(EntrustmentIdentificationMaterial entrustmentIdentificationMaterial) {
        List<EntrustmentIdentificationMaterial> list = entrustmentIdentificationMaterialService.list(Wrappers.<EntrustmentIdentificationMaterial>query()
                .eq(StrUtil.isNotBlank(entrustmentIdentificationMaterial.getImNo()), "im_no", entrustmentIdentificationMaterial.getImNo())
                .eq(StrUtil.isNotBlank(entrustmentIdentificationMaterial.getAcceptNo()), "accept_no", entrustmentIdentificationMaterial.getAcceptNo())
        );
        return R.ok(list);
    }

    /**
     * 根据委托查询检材列表
     *
     * @param entrustmentId 委托id
     * @return
     */
    @ApiOperation(value = "根据委托查询检材列表", notes = "根据委托查询检材列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "entrustmentId", value = "委托id", required = true, paramType = "query"),
            @ApiImplicitParam(name = "entrustmentIds", value = "委托id列表", required = true, paramType = "query"),
    })
    @GetMapping("/list_by_entrust")
    @PreAuthorize("@pms.hasPermission('EntrustmentIdentificationMaterialList')")
    public R<List<EntrustmentIdentificationMaterial>> getEntrustmentIdentificationMaterialListByEntrust(
            @RequestParam(value = "entrustmentId", required = false) String entrustmentId,
            @RequestParam(value = "entrustmentIds", required = false) List<String> entrustmentIds) {
        List<EntrustmentIdentificationMaterial> list = entrustmentIdentificationMaterialService.list(Wrappers.<EntrustmentIdentificationMaterial>query()
                .eq(StrUtil.isNotBlank(entrustmentId), "entrustment_id", entrustmentId)
                .in(entrustmentIds != null && entrustmentIds.size() > 0, "entrustment_id", entrustmentIds)
                .orderByAsc("order_no")
        );
        // 处理返回给前端的重量值
        list.forEach(entity -> {
            BigDecimal quantity = entity.getQuantity();
            if (quantity.compareTo(new BigDecimal(100)) >= 0) {
                // 如果 totalSampleMass 大于 100，保留 1 位小数
                entity.setQuantity(quantity.setScale(1, BigDecimal.ROUND_HALF_UP));
            } else {
                // 否则保留 2 位小数
                entity.setQuantity(quantity.setScale(2, BigDecimal.ROUND_HALF_UP));
            }
        });
        return R.ok(list);
    }

    /**
     * 审核者对检材进行审核
     *
     * @param identificationMaterial
     * @return
     */
    @ApiOperation(value = "审核者对检材进行审核", notes = "审核者对检材进行审核, opCode: 1=通过, -1=不通过, 0=未审核")
    @SysLog("审核者对检材进行审核")
    @PutMapping("/check_apply")
    @PreAuthorize("@pms.hasPermission('EntrustmentCheck')")
    public R<EntrustmentIdentificationMaterial> bizCheck_Apply(@RequestBody EntrustmentIdentificationMaterial identificationMaterial, Integer opCode, HttpServletRequest theHttpServletRequest) {
        Principal principal = theHttpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();
        return R.ok(entrustmentIdentificationMaterialService.bizCheck_Apply(identificationMaterial, opCode, dlpUser), "检材审核完成");
    }


    /**
     * 审批者对检材进行审批
     *
     * @param identificationMaterial
     * @return
     */
    @ApiOperation(value = "审批者对检材进行审批", notes = "审批者对检材进行审批, opCode: 1=通过, -1=不通过, 0=未审核")
    @SysLog("审批者对检材进行审批")
    @PutMapping("/approve_apply")
    @PreAuthorize("@pms.hasPermission('EntrustmentApprove')")
    public R<EntrustmentIdentificationMaterial> bizApprove_Apply(@RequestBody EntrustmentIdentificationMaterial identificationMaterial, Integer opCode, HttpServletRequest theHttpServletRequest) {
        Principal principal = theHttpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();
        return R.ok(entrustmentIdentificationMaterialService.bizApprove_Apply(identificationMaterial, opCode, dlpUser));
    }


    /**
     * 受理人保存检材信息
     * <p>
     * 受理人仅可以保存检材的以下属性:
     * fundName
     * fundQuantity
     * quantity
     * sample1No
     * sample1FundQuantity
     * sample1Quantity
     * sample1BoxId
     * sample2No
     * sample2Fund_quantity
     * sample2Quantity
     * sample2BoxId
     *
     * @param materialList
     * @return
     */

    @ApiOperation(value = "受理人保存检材信息", notes = "受理人保存检材信息\n" +
            "如果委托方在送检前未分样, 需要在受理现场分样, 受理只能保存与分样相关的检材属性。\n" +
            "受理人仅可以保存检材的以下属性:\n" +
//			"fundName\n"+
            "fundQuantity\n" +
            "quantity\n" +

            "providedSample1No\n" +
            "providedSample1FundQuantity\n" +
            "providedSample1Quantity\n" +
            "providedSample2Present\n" +
            "providedSample2No\n" +
            "providedSample2Fund_quantity\n" +
            "providedSample2Quantity\n" +

            "sample1No\n" +
            "sample1FundQuantity\n" +
            "sample1Quantity\n" +
            "sample1BoxId\n" +
            "sample2Present\n" +
            "sample2No\n" +
            "sample2Fund_quantity\n" +
            "sample2Quantity\n" +
            "sample2BoxId\n" +
            "当 providedSample2Present 和 sample2Present 为true时, 自动生成 [提供样本2] 和 [样本2] 的编号\n"
    )
    @SysLog("受理人保存检材信息")
    @PutMapping("/accept_save")
    @PreAuthorize("@pms.hasPermission('EntrustmentAccept')")
    public R<List<EntrustmentIdentificationMaterial>> bizAccept_Save(@RequestBody List<EntrustmentIdentificationMaterial> materialList, HttpServletRequest theHttpServletRequest) {
        Principal principal = theHttpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();
        return R.ok(entrustmentIdentificationMaterialService.bizAccept_Save(materialList, dlpUser), "保存检材信息成功");
    }


    /**
     * 受理人对检材进行受理
     *
     * @param identificationMaterial
     * @return
     */
    @ApiOperation(value = "受理人对检材进行受理提交", notes = "受理人对检材进行受理提交, opCode: 1=通过, -1=不通过, 0=未审核\n" +
            "本操作改变检材的受理状态。同时也保存检材的部分属性。\n" +
            "如果委托方在送检前未分样, 需要在受理现场分样, 受理只能保存与分样相关的检材属性。\n" +
            "受理人仅可以保存检材的以下属性:\n" +
//			"fundName\n"+
            "fundQuantity\n" +
            "quantity\n" +
            "sample1Present\n" +
            "sample1No\n" +
            "sample1FundQuantity\n" +
            "sample1Quantity\n" +
            "sample1BoxId\n" +
            "sample2Present\n" +
            "sample2No\n" +
            "sample2Fund_quantity\n" +
            "sample2Quantity\n" +
            "sample2BoxId\n"
    )
    @SysLog("受理人对检材进行受理")
    @PutMapping("/accept_apply")
    @PreAuthorize("@pms.hasPermission('EntrustmentAccept')")
    public R bizAccept_Apply(@RequestBody List<EntrustmentIdentificationMaterial> identificationMaterialList, Integer opCode, HttpServletRequest theHttpServletRequest) {
        Principal principal = theHttpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();
        return R.ok(entrustmentIdentificationMaterialService.bizAccept_Apply_Batch(identificationMaterialList, opCode, dlpUser), "检材受理完成");
    }


    /**
     * 根据提供的 evidenceId 创建新的检材
     * <p>
     * 复制物证信息, 以及附件
     * <p>
     * //	 * param entrustmentId   委托的 id
     * //	 * param evidenceId      参考物证 evidenceId
     * //	 * param copyAttachemnts 是否复制附件
     *
     * @return R<EntrustmentIdentificationMaterial>
     */
    @ApiOperation(value = "新增检材信息", notes = "新增检材信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "entrustmentId", value = "委托的 id", required = true, dataType = "String", paramType = "body"),
            @ApiImplicitParam(name = "evidenceId", value = "参考物证 evidenceId", required = true, dataType = "String", paramType = "body"),
            //@ApiImplicitParam(name = "isASample", value = "是否A样", required = true, dataType = "Boolean", paramType = "body"),
            @ApiImplicitParam(name = "copyAttachemnts", value = "是否复制附件", required = true, dataType = "Boolean", paramType = "body"),
    })
    @SysLog("新增检材信息")
    @PostMapping(value = "/createIdentificationMaterialByEvidenceId")
    @PreAuthorize("@pms.hasPermission('EntrustmentIdentificationMaterialCreate')")
    public R<EntrustmentIdentificationMaterial> createIdentificationMaterialByEvidenceId(@RequestBody EntrustmentIdentificationMaterial identificationMaterial, HttpServletRequest httpServletRequest) {
        Principal principal = httpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();
        EntrustmentIdentificationMaterial im = entrustmentIdentificationMaterialService.createIdentificationMaterialByEvidenceId(identificationMaterial, dlpUser);
        if (im != null) {
            return R.ok(im, "新增检材成功");
        } else {
            return R.failed(im, "新增检材失败");
        }
    }

    @SysLog("新增检材信息11-20修改版")
    @ApiOperation(value = "新增检材信息11-20修改版", notes = "新增检材信息11-20修改版")
    @PostMapping(value = "/create/entrustmentIdent/im")
    @PreAuthorize("@pms.hasPermission('EntrustmentIdentificationMaterialCreate')")
    public R<List<EntrustmentIdentificationMaterial>> createNewIm(@RequestBody List<EntrustmentIdentificationMaterial> identificationMaterialList, HttpServletRequest httpServletRequest) {
        Principal principal = httpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();
        List<EntrustmentIdentificationMaterial> newIm = entrustmentIdentificationMaterialService.createNewIm(identificationMaterialList, dlpUser);
        if (newIm != null) {
            return R.ok(newIm, "新增检材成功");
        } else {
            return R.failed(newIm, "新增检材失败");
        }
    }

    /**
     * 修改检材信息
     *
     * @param identificationMaterial 检材信息
     * @return R
     */
    @ApiOperation(value = "修改检材信息", notes = "修改检材信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "identificationMaterial", value = "要修改的检材", required = true, paramType = "body"),
    })
    @SysLog("修改检材信息")
    @PutMapping
    @PreAuthorize("@pms.hasPermission('EntrustmentIdentificationMaterialEdit') || @pms.hasPermission('EntrustmentAccept')")
    public R<EntrustmentIdentificationMaterial> putUpdateById(@RequestBody EntrustmentIdentificationMaterial identificationMaterial, HttpServletRequest theHttpServletRequest) {
        Principal principal = theHttpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();
        EntrustmentIdentificationMaterial entrustmentIdentificationMaterial = entrustmentIdentificationMaterialService.putUpdateById(identificationMaterial, dlpUser);
        if (entrustmentIdentificationMaterial != null) {
            return R.ok(entrustmentIdentificationMaterial, "保存检材信息成功");
        } else {
            return R.failed(entrustmentIdentificationMaterial, "保存检材信息失败");
        }

    }

    //生成委托时候的检材序号


    /**
     * 通过id删除检材信息
     *
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id删除检材信息", notes = "通过id删除检材信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "要删除的检材的标识", required = true, paramType = "path"),
    })
    @SysLog("通过id删除检材信息")
    @DeleteMapping("/{id}")
    @PreAuthorize("@pms.hasPermission('EntrustmentIdentificationMaterialDelete')")
    public R deleteById(@PathVariable String id, HttpServletRequest theHttpServletRequest) {
        Principal principal = theHttpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();
        Entrustment entrustment = entrustmentService.getById(entrustmentIdentificationMaterialService.getById(id).getEntrustmentId());
        if (entrustment.getStatus() != EntrustmentStatusConstants.ENTRUSTMENT_STATUS_CREATED.getStatus() && !dlpUser.isStaff()) {
            throw new RuntimeException(String.format("当前委托状态不允许删除检材！"));
        }
        EntrustmentIdentificationMaterial entrustmentIdentificationMaterial = entrustmentIdentificationMaterialService.deleteById(id);
        if (entrustmentIdentificationMaterial != null) {
            return R.ok(entrustmentIdentificationMaterial, "检材删除成功");
        } else {
            return R.failed(entrustmentIdentificationMaterial, "检材删除失败");
        }
    }


    /**
     * 取附件列表
     *
     * @param identificationMaterialId
     * @return
     */
    @ApiOperation(value = "取附件列表", notes = "取附件列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "identificationMaterialId", value = "检材标识", required = true, paramType = "path"),
    })
    @GetMapping("/attachment/{identificationMaterialId}/list")
    @PreAuthorize("@pms.hasPermission('EntrustmentIdentificationMaterialAttachmentList')")
    public R getAttachmentList(@PathVariable("identificationMaterialId") String identificationMaterialId) {
        EntrustmentIdentificationMaterial im = entrustmentIdentificationMaterialService.getById(identificationMaterialId);
        if (im != null) {
            return R.ok(ossFile.fileList(OSSDirectoryConstants.ENTRUSTMENT_DIRECTORY + "/" + im.getEntrustmentId() + "/" + identificationMaterialId));
        }
        return R.failed("不存在这个检材");
    }

    /**
     * 取指定检材的指定附件
     *
     * @param identificationMaterialId
     * @param fileName
     * @param httpServletResponse
     * @throws Exception
     */
    @ApiOperation(value = "取指定检材的指定附件", notes = "取指定检材的指定附件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "identificationMaterialId", value = "检材标识", required = true, paramType = "path"),
            @ApiImplicitParam(name = "fileName", value = "要取的文件名", required = true, paramType = "path"),
    })
    @GetMapping("/attachment/{identificationMaterialId}/{fileName}")
    @PreAuthorize("@pms.hasPermission('EntrustmentIdentificationMaterialAttachmentDownload')")
    public void getAttachmentObj(@PathVariable("identificationMaterialId") String identificationMaterialId, @PathVariable String fileName, HttpServletResponse httpServletResponse) throws Exception {
        EntrustmentIdentificationMaterial im = entrustmentIdentificationMaterialService.getById(identificationMaterialId);
        if (im != null) {
            try {
                ossFile.fileGet(OSSDirectoryConstants.ENTRUSTMENT_DIRECTORY + "/" + im.getEntrustmentId() + "/" + identificationMaterialId + "/" + fileName, httpServletResponse.getOutputStream());
                httpServletResponse.setContentType(new MimetypesFileTypeMap().getContentType(fileName));
            } catch (AmazonS3Exception s3e) {
                httpServletResponse.sendError(s3e.getStatusCode(), s3e.toString());
            } catch (Exception e) {
                httpServletResponse.sendError(501, e.toString());
            }
        } else {
            httpServletResponse.sendError(404, "不存在这个检材");
        }
    }

    @PostMapping(value = "/attachment/{identificationMaterialId}")
    @PreAuthorize("@pms.hasPermission('EntrustmentIdentificationMaterialAttachmentUpload')")
    public R uploadAttachmentObj(HttpServletRequest theHttpServletRequest, @PathVariable("identificationMaterialId") String identificationMaterialId, @RequestPart("file") MultipartFile file) throws Exception {
        EntrustmentIdentificationMaterial im = entrustmentIdentificationMaterialService.getById(identificationMaterialId);
        Principal principal = theHttpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();
        if (im == null) {
            return R.failed(String.format("不存在 id 为 %s 的检材", identificationMaterialId));
        }

        if ((im.getCheckPassed() != null && im.getCheckPassed() == 1) && !dlpUser.isStaff()) {
            return R.failed(String.format("已审核的检材不能修改"));
        }
        if ((im.getApprovePassed() != null && im.getApprovePassed() == 1) && !dlpUser.isStaff()) {
            return R.failed(String.format("已审批的检材不能修改"));
        }

        if ((im.getAcceptPassed() != null && im.getAcceptPassed() == 1) && !dlpUser.isStaff()) {
            return R.failed(String.format("已受理的检材不能修改"));
        }

        System.out.println(String.format("uploadPhotoObj: entrustmentId=%s identificationMaterialId=%s OriginalFilename=%s", im.getEntrustmentId(), identificationMaterialId, file.getOriginalFilename()));
        String path = OSSDirectoryConstants.ENTRUSTMENT_DIRECTORY + "/" + im.getEntrustmentId() + "/" + identificationMaterialId;
        boolean r = ossFile.fileUpload(file, path);
        Map<String, String> ResultData = new HashMap<>();
        ResultData.put("fileName", FileNameUtil.getName(file.getOriginalFilename()));
        ResultData.put("path", path);
        if (r) {
            return R.ok(ResultData, "上传成功");
        }
        return R.failed("上传失败");
    }


    @PostMapping(value = "/attachment_base64/{identificationMaterialId}")
    @PreAuthorize("@pms.hasPermission('EntrustmentIdentificationMaterialAttachmentUpload')")
    public R uploadAttachmentObj_Base64(HttpServletRequest theHttpServletRequest, @PathVariable("identificationMaterialId") String identificationMaterialId, @RequestBody JSONObject jsonParam) throws Exception {
        EntrustmentIdentificationMaterial im = entrustmentIdentificationMaterialService.getById(identificationMaterialId);
        if (im == null) {
            return R.failed(String.format("不存在 id 为 %s 的检材", identificationMaterialId));
        }
        Principal principal = theHttpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();

        if (im.getCheckPassed() != null && im.getCheckPassed() == 1 && !dlpUser.isStaff()) {
            return R.failed(String.format("已审核的检材不能修改"));
        }
        if (im.getApprovePassed() != null && im.getApprovePassed() == 1 && !dlpUser.isStaff()) {
            return R.failed(String.format("已审批的检材不能修改"));
        }

        if (im.getAcceptPassed() != null && im.getAcceptPassed() == 1 && !dlpUser.isStaff()) {
            return R.failed(String.format("已受理的检材不能修改"));
        }

        System.out.println(String.format("uploadPhotoObj: entrustmentId=%s identificationMaterialId=%s jsonParam.size()=%d", im.getEntrustmentId(), identificationMaterialId, jsonParam.size()));

        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 = Base64.decodeBase64(imgBase64);
                InputStream is = new ByteArrayInputStream(decoded);

                String path = OSSDirectoryConstants.ENTRUSTMENT_DIRECTORY + "/" + im.getEntrustmentId() + "/" + identificationMaterialId;

                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("上传的数据中没有图像");
        }

    }


    // 从物证复制附件
    @ApiOperation(value = "从物证复制附件", notes = "从物证复制附件到检材")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "identificationMaterialId", value = "检材标识", required = true, paramType = "path"),
            @ApiImplicitParam(name = "fileList", value = "要复制的文件名列表", required = true, paramType = "body"),
    })
    @PostMapping(value = "/attachment/copy/{identificationMaterialId}")
    @PreAuthorize("@pms.hasPermission('EntrustmentIdentificationMaterialAttachmentUpload')")
    public R copyAttachmentsFromEvidence(@PathVariable("identificationMaterialId") String identificationMaterialId, @RequestBody List<String> fileList) throws Exception {
        EntrustmentIdentificationMaterial entrustmentIdentificationMaterial = entrustmentIdentificationMaterialService.getById(identificationMaterialId);
        if (entrustmentIdentificationMaterial != null) {
            for (String fileName : fileList) {
                String srcFileName = OSSDirectoryConstants.ENTRUSTMENT_DIRECTORY + "/" + entrustmentIdentificationMaterial.getCaseId() + "/" + entrustmentIdentificationMaterial.getEvidenceId() + "/" + fileName;
                String destFileName = OSSDirectoryConstants.ENTRUSTMENT_DIRECTORY + "/" + entrustmentIdentificationMaterial.getEntrustmentId() + "/" + entrustmentIdentificationMaterial.getId() + "/" + fileName;
                ossFile.fileCopy(srcFileName, destFileName);
            }
            return R.ok("复制成功");
        }
        return R.failed("不存在这个检材");
    }

    @ApiOperation(value = "删除附件", notes = "删除检材的附件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "identificationMaterialId", value = "检材标识", required = true, paramType = "path"),
            @ApiImplicitParam(name = "fileName", value = "要删除的文件名", required = true, paramType = "path"),
    })
    @DeleteMapping("/attachment/{identificationMaterialId}/{fileName}")
    @PreAuthorize("@pms.hasPermission('EntrustmentIdentificationMaterialAttachmentDelete')")
    public R deleteAttachmentObj(HttpServletRequest theHttpServletRequest, @PathVariable("identificationMaterialId") String identificationMaterialId, @PathVariable String fileName) throws Exception {
        Principal principal = theHttpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();
        EntrustmentIdentificationMaterial im = entrustmentIdentificationMaterialService.getById(identificationMaterialId);
        if (im == null) {
            return R.failed(String.format("不存在 id 为 %s 的检材", identificationMaterialId));
        }

        if (im.getCheckPassed() != null && im.getCheckPassed() == 1 && !dlpUser.isStaff()) {
            return R.failed(String.format("已审核的检材不能修改"));
        }
        if (im.getApprovePassed() != null && im.getApprovePassed() == 1 && !dlpUser.isStaff()) {
            return R.failed(String.format("已审批的检材不能修改"));
        }

        if (im.getAcceptPassed() != null && im.getAcceptPassed() == 1 && !dlpUser.isStaff()) {
            return R.failed(String.format("已受理的检材不能修改"));
        }

        ossFile.fileDelete(OSSDirectoryConstants.ENTRUSTMENT_DIRECTORY + "/" + im.getEntrustmentId() + "/" + identificationMaterialId + "/" + fileName);
        Map<String, String> ResultData = new HashMap<>();
        ResultData.put("fileName", fileName);
        return R.ok(ResultData, "删除文件成功");
    }

    //-----------------------------
    // 受理的附件
    //-----------------------------


    /**
     * 取受理附件列表
     *
     * @param identificationMaterialId
     * @return
     */
    @ApiOperation(value = "取受理附件列表", notes = "取受理附件列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "identificationMaterialId", value = "检材标识", required = true, paramType = "path"),
    })
    @GetMapping("/accept_attachment/{identificationMaterialId}/list")
    @PreAuthorize("@pms.hasPermission('EntrustmentAccept')")
    public R getAcceptAttachmentList(@PathVariable("identificationMaterialId") String identificationMaterialId) {
        EntrustmentIdentificationMaterial im = entrustmentIdentificationMaterialService.getById(identificationMaterialId);
        if (im != null) {
            return R.ok(ossFile.fileList(OSSDirectoryConstants.ACCEPT_DIRECTORY + "/" + im.getEntrustmentId() + "/" + identificationMaterialId));
        }
        return R.failed("不存在这个检材");
    }

    /**
     * 取指定检材的指定受理附件
     *
     * @param identificationMaterialId
     * @param fileName
     * @param httpServletResponse
     * @throws Exception
     */
    @ApiOperation(value = "取指定检材的指定受理附件", notes = "取指定检材的指定受理附件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "identificationMaterialId", value = "检材标识", required = true, paramType = "path"),
            @ApiImplicitParam(name = "fileName", value = "要取的文件名", required = true, paramType = "path"),
    })
    @GetMapping("/accept_attachment/{identificationMaterialId}/{fileName}")
    @PreAuthorize("@pms.hasPermission('EntrustmentAccept')")
    public void getAcceptAttachmentObj(@PathVariable("identificationMaterialId") String identificationMaterialId, @PathVariable String fileName, HttpServletResponse httpServletResponse) throws Exception {
        EntrustmentIdentificationMaterial im = entrustmentIdentificationMaterialService.getById(identificationMaterialId);
        if (im != null) {
            try {
                ossFile.fileGet(OSSDirectoryConstants.ACCEPT_DIRECTORY + "/" + im.getEntrustmentId() + "/" + identificationMaterialId + "/" + fileName, httpServletResponse.getOutputStream());
                httpServletResponse.setContentType(new MimetypesFileTypeMap().getContentType(fileName));
            } catch (AmazonS3Exception s3e) {
                httpServletResponse.sendError(s3e.getStatusCode(), s3e.toString());
            } catch (Exception e) {
                httpServletResponse.sendError(501, e.toString());
            }
        } else {
            httpServletResponse.sendError(404, "不存在这个检材");
        }
    }

    /**
     * 上传受理附件
     *
     * @param identificationMaterialId
     * @param file
     * @return
     * @throws Exception
     */
    @PostMapping(value = "/accept_attachment/{identificationMaterialId}")
    @PreAuthorize("@pms.hasPermission('EntrustmentAccept')")
    public R uploadAcceptAttachmentObj(@PathVariable("identificationMaterialId") String identificationMaterialId, @RequestPart("file") MultipartFile file) throws Exception {
        EntrustmentIdentificationMaterial im = entrustmentIdentificationMaterialService.getById(identificationMaterialId);
        if (im != null) {
            if (im.getAcceptPassed() == null || im.getAcceptPassed() != 1) {
                System.out.println(String.format("uploadAcceptAttachmentObj: entrustmentId=%s identificationMaterialId=%s OriginalFilename=%s", im.getEntrustmentId(), identificationMaterialId, file.getOriginalFilename()));
                String path = OSSDirectoryConstants.ACCEPT_DIRECTORY + "/" + im.getEntrustmentId() + "/" + identificationMaterialId;
                boolean r = ossFile.fileUpload(file, path);
                Map<String, String> ResultData = new HashMap<>();
                ResultData.put("fileName", FileNameUtil.getName(file.getOriginalFilename()));
                ResultData.put("path", path);
                if (r) {
                    return R.ok(ResultData, "上传成功");
                }
                return R.failed("上传失败");
            } else {
                return R.failed("已受理的检材不能再添加附件");
            }
        }
        return R.failed(im, "不存在这个检材");
    }

    /**
     * 上传受理附件
     *
     * @param identificationMaterialId
     * @param jsonParam
     * @return
     * @throws Exception
     */
    @PostMapping(value = "/accept_attachment_base64/{identificationMaterialId}")
    @PreAuthorize("@pms.hasPermission('EntrustmentAccept')")
    public R uploadAcceptAttachmentObj_Base64(@PathVariable("identificationMaterialId") String identificationMaterialId,
                                              @RequestBody JSONObject jsonParam) throws Exception {
        EntrustmentIdentificationMaterial im = entrustmentIdentificationMaterialService.getById(identificationMaterialId);
        if (im != null) {
            System.out.println(String.format("uploadAcceptAttachmentObj_Base64: entrustmentId=%s identificationMaterialId=%s jsonParam.size()=%d", im.getEntrustmentId(), identificationMaterialId, jsonParam.size()));
            String entrustId = jsonParam.getString("entrustId");
            Assert.notBlank(entrustId, "委托ID参数不能为空");
            Entrustment entrustObj = entrustmentService.getById(entrustId);
            Thread.sleep(10);
            //if (im.getAcceptPassed() == null || im.getAcceptPassed() != 1) {
            //只要委托没有受理就可以上传检材的照片
            if (entrustObj.getStatus() >= (EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_ACCEPT.getStatus())) {
                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(";"));
                        if (suffix.equals("jpeg")) {
                            suffix = "jpg";
                        }
                        //String fileName = DateUtil.format(new Date(), "yyyyMMddHHmmss") + "." + suffix;
//                        int randomNumber = (int) (Math.random() * 90) + 10; // [10, 99]
                        // 20241127 为了后续可以对上传的照片进行排序，防止照片上传顺序错乱
                        String fileName = System.currentTimeMillis() + "." + suffix;
                        System.out.println(String.format("fileName=[%s]", fileName));

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

                        String path = OSSDirectoryConstants.ACCEPT_DIRECTORY + "/" + im.getEntrustmentId() + "/" + identificationMaterialId;

                        Map<String, String> ResultData = new HashMap<>();
                        ResultData.put("fileName", fileName);
                        ResultData.put("path", path);

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

                    } catch (Exception e) {
                        e.printStackTrace();
                        return R.failed("上传失败");
                    }
                } else {
                    return R.failed("上传的数据中没有图像");
                }
            } else {
                return R.failed("，检材不能再添加照片");
            }
        }
        return R.failed("不存在这个检材");
    }


    @ApiOperation(value = "删除附件", notes = "删除检材的附件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "identificationMaterialId", value = "检材标识", required = true, paramType = "path"),
            @ApiImplicitParam(name = "fileName", value = "要删除的文件名", required = true, paramType = "path"),
    })
    @DeleteMapping("/accept_attachment/{identificationMaterialId}/{fileName}/{entrustId}")
    @PreAuthorize("@pms.hasPermission('EntrustmentAccept')")
    public R deleteAcceptAttachmentObj(@PathVariable("identificationMaterialId") String identificationMaterialId, @PathVariable String fileName, @PathVariable String entrustId) throws Exception {
        EntrustmentIdentificationMaterial im = entrustmentIdentificationMaterialService.getById(identificationMaterialId);
        if (im != null) {
            Assert.notBlank(entrustId, "委托ID参数不能为空");
            Entrustment entrustObj = entrustmentService.getById(entrustId);
            //if (im.getAcceptPassed() == null || im.getAcceptPassed() != 1) {
            //只要委托没有受理就可以删除检材的照片
            if (entrustObj.getStatus() >= (EntrustmentStatusConstants.ENTRUSTMENT_STATUS_WAITING_ACCEPT.getStatus())) {
                ossFile.fileDelete(OSSDirectoryConstants.ACCEPT_DIRECTORY + "/" + im.getEntrustmentId() + "/" + identificationMaterialId + "/" + fileName);
                Map<String, String> ResultData = new HashMap<>();
                ResultData.put("fileName", fileName);
                return R.ok(ResultData, "删除文件成功");
            } else {
                return R.failed("委托受理后，检材不能再删除检材照片");
            }
        }
        return R.failed("不存在这个检材");
    }

    /**
     * 根据模板生成检材标签的 html, 供 qz 打印使用
     *
     * @param id id
     * @return String
     */
    @ApiOperation(value = "根据模板生成检材标签的 html, 供 qz 打印使用", notes = "根据模板生成检材标签的 html, 供 qz 打印使用")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "检材标识", required = true, paramType = "path"),
    })
    @GetMapping("/imlabel/{id}")
    @PreAuthorize("@pms.hasPermission('EntrustmentIdentificationMaterialGet')")
    public String getIdentificationMaterialLabelHtml(@PathVariable("id") String id) throws Exception {
        //把数据填入上下文
        EntrustmentIdentificationMaterial im = entrustmentIdentificationMaterialService.getById(id);
        if (im == null) {
            throw new RuntimeException(String.format("没有找到 id 为 %s 的检材", id));
        }

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

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

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

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

        String templateFileName = AppStartupRunner.getCfg(CommonConstants.DLP_CODE_ENTRUSTMENT_LABEL_TEMPLATE_IDENTIFICATION_MATERIAL);
        return remoteTemplate2htmlService.getHtml(templateFileName, data);
    }


    /**
     * 根据模板生成提供的样本标签的 html, 供 qz 打印使用
     *
     * @param id id
     * @return String
     */
    @ApiOperation(value = "根据模板生成提供的样本标签的 html, 供 qz 打印使用", notes = "根据模板生成提供的样本标签的 html, 供 qz 打印使用")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "检材标识", required = true, paramType = "path"),
            @ApiImplicitParam(name = "sample", value = "样本1或样本2, (整数, 1 或 2 )", required = true, paramType = "path"),
    })
    @GetMapping("/provided_sample_label/{id}")
    @PreAuthorize("@pms.hasPermission('EntrustmentIdentificationMaterialGet')")
    public String getProvidedSampleLabelHtml(@PathVariable("id") String id, @RequestParam(value = "sample", required = true) Integer sample) throws Exception {
        if ((sample != 1) && (sample != 2)) {
            throw new RuntimeException(String.format("sample 参数必须是 1 或 2"));
        }
        //把数据填入上下文
        EntrustmentIdentificationMaterial im = entrustmentIdentificationMaterialService.getById(id);
        if (im == null) {
            throw new RuntimeException(String.format("没有找到 id 为 %s 的检材", id));
        }

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

        CaseEvent ce = caseEventService.getById(im.getCaseId());
        if (ce == null) {
            throw new RuntimeException(String.format("没有找到 id 为 %s 的案件", im.getCaseId()));
        }
//        打印条码现在已经不需要物证信息了
//        CaseEvidence evidence = caseEvidenceService.getById(im.getEvidenceId());
//        if (evidence == null) {
//            throw new RuntimeException(String.format("没有找到 id 为 %s 的物证", im.getEvidenceId()));
//        }

        Map<String, Object> data = new HashMap<>();
        data.put("identificationMaterial", im);
        data.put("caseEvent", ce);
        data.put("entrustment", entrustment);
//        data.put("evidence", evidence);
        if (sample == 1) {
            //String templateFileName = AppStartupRunner.getCfg(CommonConstants.DLP_CODE_ENTRUSTMENT_LABEL_TEMPLATE_IM_SAMPLE1);
            String templateFileName = AppStartupRunner.getCfg(CommonConstants.DLP_CODE_ENTRUSTMENT_LABEL_TEMPLATE_IM_PROVIDED_SAMPLE1);
            return remoteTemplate2htmlService.getHtml(templateFileName, data);
        } else {
            String templateFileName = AppStartupRunner.getCfg(CommonConstants.DLP_CODE_ENTRUSTMENT_LABEL_TEMPLATE_IM_PROVIDED_SAMPLE2);
            return remoteTemplate2htmlService.getHtml(templateFileName, data);
        }
    }


    /**
     * 根据模板生成样本标签的 html, 供 qz 打印使用
     *
     * @param id id
     * @return String
     */
    @ApiOperation(value = "根据模板生成样本标签的 html, 供 qz 打印使用", notes = "根据模板生成样本标签的 html, 供 qz 打印使用")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "检材标识", required = true, paramType = "path"),
            @ApiImplicitParam(name = "sample", value = "样本1或样本2, (整数, 1 或 2 )", required = true, paramType = "path"),
            @ApiImplicitParam(name = "type", value = "打印大标签或者小标签。（整数，如果打印小标签传入1即可）", required = true, paramType = "path"),
    })
    @GetMapping("/sample_label/{id}")
    @PreAuthorize("@pms.hasPermission('EntrustmentIdentificationMaterialGet')")
    public String getSampleLabelHtml(@PathVariable(value = "id") String id, @RequestParam(value = "sample", required = true) Integer sample) throws Exception {
        if ((sample != 1) && (sample != 2)) {
            throw new RuntimeException(String.format("sample 参数必须是 1 或 2"));
        }
        //把数据填入上下文
        EntrustmentIdentificationMaterial im = entrustmentIdentificationMaterialService.getById(id);
        if (im == null) {
            throw new RuntimeException(String.format("没有找到 id 为 %s 的检材", id));
        }

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

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

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

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

        if (sample == 1) {
            String templateFileName = AppStartupRunner.getCfg(CommonConstants.DLP_CODE_ENTRUSTMENT_LABEL_TEMPLATE_IM_SAMPLE1);
            return remoteTemplate2htmlService.getHtml(templateFileName, data);
        } else {
            String templateFileName = AppStartupRunner.getCfg(CommonConstants.DLP_CODE_ENTRUSTMENT_LABEL_TEMPLATE_IM_SAMPLE2);
            return remoteTemplate2htmlService.getHtml(templateFileName, data);
        }
    }


//    /**
//     * 添加复秤信息的保存接口  还没增加权限控制
//     *
//     * @param id
//     * @param sample1RepeatWeigh
//     * @param sample2RepeatWeigh
//     * @return
//     */
//    @PostMapping("/saveRepWeigh")
//    @ApiOperation(value = "保存复秤信息", notes = "保存复秤信息")
//    @GlobalTransactional
//    public R saveRepWeigh(String id, double sample1RepeatWeigh, double sample2RepeatWeigh, boolean isUseBalance, String sampleFlag) {
//        return R.ok(entrustmentIdentificationMaterialService.saveRepWeigh(id, sample1RepeatWeigh, sample2RepeatWeigh, isUseBalance, sampleFlag), "保存成功");
//    }

    //增加留存样
    @PostMapping("/settingRetained")
    @ApiOperation(value = "添加留存样", notes = "添加留存样的接口，1= true -1=false")
    public R settingRetained(String id, int flag) {
        return R.ok(entrustmentIdentificationMaterialService.settingRetained(id, flag), "操作成功");
    }

    //
    @ApiOperation(value = "根据盒子ID 查询该盒子下的检材", notes = "根据盒子ID 查询该盒子下的检材")
    @GetMapping("/getQueryListByBoxID")
    public R getQueryListByBoxID(String boxId, String boxType) {
        return R.ok(entrustmentIdentificationMaterialService.getQueryListByBoxID(boxId, boxType));
    }

    @ApiOperation(value = "根据盒子ID，分样类型，检材ID 删除分样信息", notes = "根据盒子ID，分样类型，检材ID 删除分样信息")
    @DeleteMapping("/delSampleBoxInfo")
    public R delSampleBoxInfo(String boxId, String sampleNo, String boxType) {
        System.out.println("boxId=" + boxId + "   sampleNo=" + sampleNo + "   boxType" + boxType);
        Boolean aBoolean = entrustmentIdentificationMaterialService.delSampleBoxInfo(boxId, sampleNo, boxType);
        return aBoolean ? R.ok("删除成功") : R.failed("删除失败");
    }

    @ApiOperation(value = "统计盒子中装了多少样本", notes = "统计盒子中装了多少样本")
    @GetMapping("/getBoxCountInfo")
    public R getBoxCountInfo(String boxId) {
        return R.ok(entrustmentIdentificationMaterialService.getBoxCountInfo(boxId));
    }

    @ApiOperation(value = "将样本放进盒子", notes = "将样本放进盒子")
    @PostMapping("/putSampleToBox")
    public R<List<EntrustmentIdentificationMaterial>> putSampleToBox(@RequestBody SampleBoxDTO sampleBoxDTO) {
        Assert.notBlank("boxId", "盒子ID不能为空");
        Assert.notBlank("sampleNo", "样品编号不能为空");
        Assert.notBlank("boxType", "盒子类型不能为空");
        List<EntrustmentIdentificationMaterial> materialList = entrustmentIdentificationMaterialService.putSampleToBox(sampleBoxDTO.getBoxId(), sampleBoxDTO.getSampleNoList(), sampleBoxDTO.getBoxType());

        return materialList != null ? R.ok(materialList, "添加成功") : R.failed("添加失败");
    }

    //=====================================================================================
    // 测试, 为现有的委托创建一些检材
    @ApiOperation(value = "测试用: 为所有委托创建1~100个不等的检材,检材来源于对应的案件的物证", notes = "为所有委托创建1~100个不等的检材,检材来源于对应的案件的物证")
    @GetMapping("/create100")
    public R xxx_TestCreate100() {
        List<Entrustment> es = entrustmentService.list();
        System.out.println(String.format("委托总数: =%d", es.size()));
        for (Entrustment e : es) {
            String caseId = e.getCaseId();
            List<CaseEvidence> ces = caseEvidenceService.list(Wrappers.<CaseEvidence>query()
                    .eq("case_id", e.getCaseId()));
            System.out.println(String.format("EntrustmentNo:%s caseId:%s 物证数: %d", e.getEntrustmentNo(), e.getCaseId(), ces.size()));
            if (ces.size() > 0) {

                int num = TestUtils.genWeightInteger(100) % 10;
                System.out.println(String.format("正在生成委托%s的检材, 将生成%d个检材", e.getId(), num));
                for (int i = 0; i < num; i++) {
                    CaseEvidence ce = ces.get(RandomUtil.randomInt(0, ces.size()));     // 随机取一个物证
                    EntrustmentIdentificationMaterial im = entrustmentIdentificationMaterialService.createNewIdentificationMaterial(ce);    // 测试用
                    im.setEntrustmentId(e.getId());
                    im.setDrawWay("随机抽取");

                    im.setPersonName(TestUtils.genPersonName());
                    im.setPersonGender(RandomUtil.randomInt(0, 2));
                    im.setPersonNation(RandomUtil.randomInt(1, 20));

                    if (StringUtils.isEmpty(im.getTake1Name())) {
                        im.setTake1Name(TestUtils.genPersonName());
                    }
                    if (StringUtils.isEmpty(im.getTake1Position())) {
                        im.setTake1Position(TestUtils.genPosition());
                    }
                    if (StringUtils.isEmpty(im.getTake1Cert())) {
                        im.setTake1Cert(TestUtils.genCertificateType());
                    }
                    if (StringUtils.isEmpty(im.getTake1Id())) {
                        im.setTake1Id(RandomUtil.randomNumbers(6));
                    }
                    if (StringUtils.isEmpty(im.getTake1Phone())) {
                        im.setTake1Phone(TestUtils.genMobile());
                    }
                    if (StringUtils.isEmpty(im.getTake2Name())) {
                        im.setTake2Name(TestUtils.genPersonName());
                    }
                    if (StringUtils.isEmpty(im.getTake2Position())) {
                        im.setTake2Position(TestUtils.genPosition());
                    }
                    if (StringUtils.isEmpty(im.getTake2Cert())) {
                        im.setTake2Cert(TestUtils.genCertificateType());
                    }
                    if (StringUtils.isEmpty(im.getTake2Id())) {
                        im.setTake2Id(RandomUtil.randomNumbers(6));
                    }
                    if (StringUtils.isEmpty(im.getTake2Phone())) {
                        im.setTake2Phone(TestUtils.genMobile());
                    }

                    if (im.getTakeTime() == null) {
                        LocalDateTime t = LocalDateTime.now();
                        t = t.minusDays(RandomUtil.randomInt(100));
                        im.setTakeTime(t);
                    }

                    if (StringUtils.isEmpty(im.getWitnessName())) {
                        im.setWitnessName(TestUtils.genPersonName());
                    }
                    if (StringUtils.isEmpty(im.getWitnessCert())) {
                        im.setWitnessCert(TestUtils.genCertificateType());
                    }
                    if (StringUtils.isEmpty(im.getWitnessId())) {
                        im.setWitnessId(RandomUtil.randomNumbers(6));
                    }
                    im.setId(IdWorker.get32UUID().toUpperCase());

                    if (entrustmentIdentificationMaterialService.save(im)) {
                        System.out.println("新增检材成功");
                    } else {
                        System.out.println("新增检材失败");
                    }

                }
            }
        }
        return R.ok("已经为每个委托创建了 一些检材");
    }


    //=====================================================================================
    // 测试, 为现有的检材补齐资料
    @ApiOperation(value = "测试用: 为现有的检材补齐资料", notes = "为现有的检材补齐资料")
    @GetMapping("/testpatch")
    public R testPatch() {
        List<EntrustmentIdentificationMaterial> ims = entrustmentIdentificationMaterialService.list();
        System.out.println(String.format("检材总数: =%d", ims.size()));
        int i = 0;
        for (EntrustmentIdentificationMaterial im : ims) {
            i++;
            System.out.println(String.format("正在更新检材 %d / %d ...", i, ims.size()));


            im.setPersonName(TestUtils.genPersonName());
            im.setPersonGender(RandomUtil.randomInt(0, 2));
            im.setPersonNation(RandomUtil.randomInt(1, 20));

            if (StringUtils.isEmpty(im.getTake1Name())) {
                im.setTake1Name(TestUtils.genPersonName());
            }
            if (StringUtils.isEmpty(im.getTake1Position())) {
                im.setTake1Position(TestUtils.genPosition());
            }
            if (StringUtils.isEmpty(im.getTake1Cert())) {
                im.setTake1Cert(TestUtils.genCertificateType());
            }
            if (StringUtils.isEmpty(im.getTake1Id())) {
                im.setTake1Id(RandomUtil.randomNumbers(6));
            }
            if (StringUtils.isEmpty(im.getTake1Phone())) {
                im.setTake1Phone(TestUtils.genMobile());
            }
            if (StringUtils.isEmpty(im.getTake2Name())) {
                im.setTake2Name(TestUtils.genPersonName());
            }
            if (StringUtils.isEmpty(im.getTake2Position())) {
                im.setTake2Position(TestUtils.genPosition());
            }
            if (StringUtils.isEmpty(im.getTake2Cert())) {
                im.setTake2Cert(TestUtils.genCertificateType());
            }
            if (StringUtils.isEmpty(im.getTake2Id())) {
                im.setTake2Id(RandomUtil.randomNumbers(6));
            }
            if (StringUtils.isEmpty(im.getTake2Phone())) {
                im.setTake2Phone(TestUtils.genMobile());
            }

            if (im.getTakeTime() == null) {
                LocalDateTime t = LocalDateTime.now();
                t = t.minusDays(RandomUtil.randomInt(100));
                im.setTakeTime(t);
            }

            if (StringUtils.isEmpty(im.getWitnessName())) {
                im.setWitnessName(TestUtils.genPersonName());
            }
            if (StringUtils.isEmpty(im.getWitnessCert())) {
                im.setWitnessCert(TestUtils.genCertificateType());
            }
            if (StringUtils.isEmpty(im.getWitnessId())) {
                im.setWitnessId(RandomUtil.randomNumbers(6));
            }
            entrustmentIdentificationMaterialService.updateById(im);
        }
        return R.ok("已经为每个检材补齐了一些字段");
    }

//    @GetMapping("/print/label")
//    @ApiOperation(value = "打印检材条码，传入检材ID即可", notes = "打印检材条码，传入检材ID即可")
//    public String printLabel(@RequestParam(value = "id") String id) {
//        return entrustmentIdentificationMaterialService.printLabel(id);
//    }

    /**
     * 根据模板生成样本标签的 html, 供 qz 打印使用
     *
     * @param printDTOList printDTOList
     * @return String
     */
    @ApiOperation(value = "批量：根据模板生成样本标签的 html, 供 qz 打印使用//type:区分是打印大标签还是小标签，1：大标签  0：小标签", notes = "批量：根据模板生成样本标签的 html, 供 qz 打印使用//type:区分是打印大标签还是小标签，1：大标签  0：小标签")
    @PostMapping("/sample_many_label")
    @PreAuthorize("@pms.hasPermission('EntrustmentIdentificationMaterialGet')")
    public List<String> getManySampleLabelHtml(@RequestBody List<PrintDTO> printDTOList) throws Exception {
        return entrustmentIdentificationMaterialService.printManyLabel(printDTOList);
    }

    @GetMapping("/print/archives")
    @ApiOperation(value = "生成委托的检材档案信息")
    public R<String> printMaterialArchives(String entrustmentId) throws Exception {
        String path = entrustmentIdentificationMaterialService.printMaterialArchives(entrustmentId);
        return StringUtils.isNotBlank(path) ? R.ok(path, "生成成功!") : R.failed("生成失败!");
    }
}
