package org.springblade.modules.app.manager;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.wn.common.perfmonitor.annotation.ServiceTimeLog;
import com.wn.common.validator.Validator;
import org.springblade.modules.app.dto.CityDTO;
import org.springblade.modules.app.client.IWidgetService;
import org.springblade.modules.app.client.ZmtClientService;
import org.springblade.modules.app.common.dto.*;
import org.springblade.modules.app.common.enums.*;
import org.springblade.modules.app.common.query.ApplicationQuery;
import org.springblade.modules.app.common.query.PictureQuery;
import org.springblade.modules.app.common.query.TransportStageQuery;
import org.springblade.modules.app.common.vo.*;
import org.springblade.modules.app.constant.Constants;
import org.springblade.modules.app.constant.ErrorCode;
import org.springblade.modules.app.service.*;
import org.springblade.modules.app.utils.ResponseHandelUtil;
import org.springblade.modules.app.utils.UserUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springblade.modules.app.web.AppRegionController;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Component
public class TransportStageManager {

    @Autowired
    private ITransportService transportService;
    @Autowired
    private ITransportStageInfoService transportStageInfoService;
    @Autowired
    private IPictureInfoService pictureInfoService;
    @Autowired
    private UserManager userManager;
//    @Autowired
//    private IWidgetService widgetService;
    @Autowired
    private ICityService cityService;
    @Autowired
    private IAppUserService userService;
    @Autowired
    private ZmtClientService zmtClientService;
    @Autowired
    private IWaybillService waybillService;
    @Autowired
    private UserUtils userUtils;
    @Autowired
    private IApplicationInfoService applicationInfoService;
    @Autowired
    private MessageLoggingManager messageLoggingManager;
    private final String HEAD = this.getClass().getSimpleName() + ":";

    /**
     * 提交运输单阶段信息
     *
     * @param stageInfoDTO
     * @return java.lang.String
     * @author FUXINSHENG
     * @date 2021/11/12 9:29
     * 1、校验运输单管理调运单状态
     * 2、校验当前用户与调运单间的关系：养殖场、屠宰场、代宰户
     * 3、校验司机信息是否在库中
     * 4、校验入省检疫站信息是否与调运单一致
     */
    @ServiceTimeLog
    @Transactional(rollbackFor = Exception.class)
    public String transportStage(TransportStageInfoDTO stageInfoDTO) {
        Validator.notNull(stageInfoDTO, ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.notNull(stageInfoDTO.getTransportId(), ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.notNull(stageInfoDTO.getStage(), ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.notNull(stageInfoDTO.getSubmitLocation(), ErrorCode.SUBMIT_LOCATION_EXP);
        Validator.notNull(CollectionUtils.isNotEmpty(stageInfoDTO.getPictureInfoDTOList()), ErrorCode.INPUT_PARAMETERS_NULL);

        UserDTO userDTO = userUtils.getUser(stageInfoDTO.getToken());

        Validator.isTrue(userDTO.getType().equals(UserTypeEnum.DRIVER.getCode()), ErrorCode.NO_POWER_GET);
        log.info(HEAD + "上传运输单阶段信息, 当前用户id:{}, 请求参数:{}", userDTO.getId(), JSON.toJSONString(stageInfoDTO));

        TransportDTO transport = transportService.getTransportById(stageInfoDTO.getTransportId());
        Validator.notNull(transport, ErrorCode.TRANSPORT_INFO_NULL);
        Validator.isTrue(transport.getState() == WaybillStateEnum.TRANSPORT.getCode(), ErrorCode.TRANSPORT_IS_EXP);
        Validator.isTrue(transport.getDriverUserId().equals(userDTO.getId()), ErrorCode.NO_POWER_GET);
        TransportStageQuery transportStageQuery = new TransportStageQuery();
        transportStageQuery.setTransportId(stageInfoDTO.getTransportId());
        List<TransportStageInfoDTO> info = transportStageInfoService.listInfo(transportStageQuery);
        int size = CollectionUtils.isNotEmpty(info) ? info.size() : 0;
        Validator.isTrue(size < 3, ErrorCode.INPUT_PARAMETERS_INVALID);
        List<PictureInfoDTO> pictureInfoDTOList = stageInfoDTO.getPictureInfoDTOList();
        if (size == 0) {
            Validator.isTrue(stageInfoDTO.getStage().equals(TransportStageEnum.LOADING.getCode()), ErrorCode.INPUT_PARAMETERS_INVALID);
            pictureInfoDTOList.forEach(pictureInfoDTO -> Validator.isTrue(pictureInfoDTO.getType() == PictureTypeEnum.EMPTY_CAR.getCode() || pictureInfoDTO.getType() == PictureTypeEnum.LOAD_CAR.getCode(), ErrorCode.PICTURE_TYPE_ERROR));
            Boolean locationExp = isLocationExp(stageInfoDTO.getSubmitLocation(), transport.getSalerProvId(), transport.getSalerCityId(), transport.getSalerAreaId());
            if (Boolean.FALSE.equals(locationExp)) {
                stageInfoDTO.setExpType(YesNoEnum.YES.getCode());
            }
        } else if (size == 1) {
            if (stageInfoDTO.getStage().equals(TransportStageEnum.CHECKING.getCode())) {
                PictureInfoDTO pictureInfoDTO = pictureInfoDTOList.get(0);
                Validator.isTrue(pictureInfoDTO.getType() == PictureTypeEnum.A_TICKET.getCode(), ErrorCode.PICTURE_TYPE_ERROR);
                Validator.notNull(pictureInfoDTO.getMessage(), ErrorCode.INPUT_PARAMETERS_NULL);
                VerifyPictureInfoVO verifyPictureInfoVO = JSON.parseObject(pictureInfoDTO.getMessage(), VerifyPictureInfoVO.class);
                Validator.notNull(verifyPictureInfoVO, ErrorCode.INPUT_PARAMETERS_NULL);
                Validator.notNull(verifyPictureInfoVO.getCarCode(), ErrorCode.INPUT_PARAMETERS_NULL);
                Validator.notNull(verifyPictureInfoVO.getVerifyCode(), ErrorCode.INPUT_PARAMETERS_NULL);
                Validator.notNull(verifyPictureInfoVO.getNum(), ErrorCode.INPUT_PARAMETERS_NULL);
                transport.setConfirmTime(new Date());
            } else if (stageInfoDTO.getStage().equals(TransportStageEnum.LOADING.getCode())) {
                pictureInfoDTOList.forEach(pictureInfoDTO -> Validator.isTrue(pictureInfoDTO.getType() == PictureTypeEnum.EMPTY_CAR.getCode() || pictureInfoDTO.getType() == PictureTypeEnum.LOAD_CAR.getCode(), ErrorCode.PICTURE_TYPE_ERROR));
                PictureQuery pictureQuery = new PictureQuery();
                Long stageId = info.get(0).getId();
                pictureQuery.setLinkId(stageId);
                pictureQuery.setType(pictureInfoDTOList.get(0).getType());
                List<PictureInfoDTO> pictureInfoDTOS = pictureInfoService.listPictureInfo(pictureQuery);
                int count = CollectionUtils.isNotEmpty(pictureInfoDTOS) ? pictureInfoDTOS.size() : 0;
                for (PictureInfoDTO pictureInfoDTO : stageInfoDTO.getPictureInfoDTOList()) {
                    pictureInfoDTO.setLinkId(stageId);
                    pictureInfoDTO.setMessage("");
                    pictureInfoDTO.setLinkTable(Constants.TB_TRANSPORT_STAGE_INFO);
                    pictureInfoDTO.setSort(count++);
                    pictureInfoService.addPictureInfo(pictureInfoDTO);
                }
                Boolean locationExp = isLocationExp(stageInfoDTO.getSubmitLocation(), transport.getSalerProvId(), transport.getSalerCityId(), transport.getSalerAreaId());
                if (Boolean.FALSE.equals(locationExp)) {
                    stageInfoDTO.setExpType(YesNoEnum.YES.getCode());
                }
                stageInfoDTO.setId(stageId);
                transportStageInfoService.updateTransportStage(stageInfoDTO);
                return stageId.toString();
            } else {
                Validator.isTrue(false, ErrorCode.INPUT_PARAMETERS_INVALID);
            }

        } else if (size == 2) {
            Validator.isTrue(stageInfoDTO.getStage().equals(TransportStageEnum.ACCEPTING.getCode()), ErrorCode.INPUT_PARAMETERS_INVALID);
            PictureInfoDTO pictureInfoDTO = pictureInfoDTOList.get(0);
            Validator.notNull(pictureInfoDTO.getAcceptNum(), ErrorCode.INPUT_PARAMETERS_NULL);
            Validator.notNull(pictureInfoDTO.getMessage(), ErrorCode.INPUT_PARAMETERS_NULL);
            Validator.isTrue(pictureInfoDTO.getType() == PictureTypeEnum.ACCEPT.getCode(), ErrorCode.PICTURE_TYPE_ERROR);
            VerifyPictureInfoVO verifyPictureInfoVO = JSON.parseObject(pictureInfoDTO.getMessage(), VerifyPictureInfoVO.class);
            Validator.notNull(verifyPictureInfoVO, ErrorCode.INPUT_PARAMETERS_NULL);
            Validator.notNull(verifyPictureInfoVO.getAcceptNum(), ErrorCode.INPUT_PARAMETERS_NULL);
            Validator.notNull(verifyPictureInfoVO.getAcceptWeight(), ErrorCode.INPUT_PARAMETERS_NULL);
            Validator.notNull(verifyPictureInfoVO.getGrossWeight(), ErrorCode.INPUT_PARAMETERS_NULL);
            initApplication(stageInfoDTO, userDTO, transport);
            // 当司机上传接收凭证，向审批人：屠宰场/代宰户发送消息
            if (ObjectUtils.isNotEmpty(transport.getSlaughterHouseId())) {
                messageLoggingManager.messageHandling(transport.getSlaughterHouseId(), MessageEnum.RECEIVE_VOUCHER_UPLOAD.getCode());
            }else {
                messageLoggingManager.messageHandling(transport.getBuyerUserId(), MessageEnum.RECEIVE_VOUCHER_UPLOAD.getCode());
            }
            Boolean locationExp = isLocationExp(stageInfoDTO.getSubmitLocation(), transport.getBuyerProvId(), transport.getBuyerCityId(), transport.getBuyerAreaId());
            if (Boolean.FALSE.equals(locationExp)) {
                stageInfoDTO.setExpType(YesNoEnum.YES.getCode());
            }
        }
        stageInfoDTO.setSubmitTime(new Date());
        Long stageInfoId = transportStageInfoService.addTransportStage(stageInfoDTO);
        transportService.updateTransport(transport);
        int count = 1;
        for (PictureInfoDTO pictureInfoDTO : stageInfoDTO.getPictureInfoDTOList()) {
            pictureInfoDTO.setLinkId(stageInfoId);
            if (pictureInfoDTO.getType() == PictureTypeEnum.EMPTY_CAR.getCode() || pictureInfoDTO.getType() == PictureTypeEnum.LOAD_CAR.getCode()) {
                pictureInfoDTO.setMessage("");
            }
            pictureInfoDTO.setLinkTable(Constants.TB_TRANSPORT_STAGE_INFO);
            pictureInfoDTO.setSort(count++);
            pictureInfoService.addPictureInfo(pictureInfoDTO);
        }
        if (size == 1 && stageInfoDTO.getStage().equals(TransportStageEnum.CHECKING.getCode())) {
            postTrajectoryReceive(transport);
        }
        return stageInfoId.toString();
    }

    public Boolean isLocationExp(String address, Long provId, Long cityId, Long areaId) {
        return true;

//        Map<String, String> addressResolution = addressResolution(address);
//        if (addressResolution == null) {
//            return false;
//        }
//        String province = addressResolution.get(Constants.PROVINCE);
//        String city = addressResolution.get(Constants.CITY);
//        String county = addressResolution.get(Constants.COUNTY);
//        CityDTO proDTO = new CityDTO();
//        proDTO.setId(provId);
//        CityDTO userProv = cityService.getCityDTO(proDTO);
//        CityDTO cityDTO = new CityDTO();
//        cityDTO.setId(cityId);
//        CityDTO userCity = cityService.getCityDTO(cityDTO);
//        CityDTO areaDTO = new CityDTO();
//        areaDTO.setId(areaId);
//        CityDTO userArea = cityService.getCityDTO(areaDTO);
//
//        return province.contains(userProv.getName()) && city.contains(userCity.getName()) && county.contains(userArea.getName());
    }

    /**
     * 解析地址
     *
     * @param address
     * @return
     */
    public Map<String, String> addressResolution(String address) {
        /*
         *    java.util.regex是一个用正则表达式所订制的模式来对字符串进行匹配工作的类库包。它包括两个类：Pattern和Matcher Pattern
         *    一个Pattern是一个正则表达式经编译后的表现模式。 Matcher
         *    一个Matcher对象是一个状态机器，它依据Pattern对象做为匹配模式对字符串展开匹配检查。
         *    首先一个Pattern实例订制了一个所用语法与PERL的类似的正则表达式经编译后的模式，然后一个Matcher实例在这个给定的Pattern实例的模式控制下进行字符串的匹配工作。
         */
        Matcher m = Pattern.compile(Constants.ADDRESS_REG).matcher(address);
        String province = null;
        String city = null;
        String county = null;
        String town = null;
        String village = null;
        Map<String, String> row = null;
        while (m.find()) {
            row = new HashMap<>();
            province = m.group(Constants.PROVINCE);
            row.put(Constants.PROVINCE, province == null ? "" : province.trim());
            city = m.group(Constants.CITY);
            row.put(Constants.CITY, city == null ? "" : city.trim());
            county = m.group(Constants.COUNTY);
            row.put(Constants.COUNTY, county == null ? "" : county.trim());
            town = m.group(Constants.TOWN);
            row.put(Constants.TOWN, town == null ? "" : town.trim());
            village = m.group(Constants.VILLAGE);
            row.put(Constants.VILLAGE, village == null ? "" : village.trim());
        }
        return row;
    }

    public void initApplication(TransportStageInfoDTO stageInfoDTO, UserDTO userDTO, TransportDTO transport) {
        UserDTO buyer = userService.getUserById(transport.getSlaughterHouseId() != null && transport.getSlaughterHouseId() != 0 ? transport.getSlaughterHouseId() : transport.getBuyerUserId());
        ApplicationInfoDTO applicationInfoDTO = userManager.initApplicationInfo(ApplicationTypeEnum.ACCEPT_STAGE.getCode(), stageInfoDTO.getTransportId(), buyer, userDTO);
        applicationInfoDTO.setLinkTable(Constants.TB_TRANSPORT);
        applicationInfoService.addApplicationInfo(applicationInfoDTO);
        transport.setAcceptState(ApplicationStateEnum.UNCHECK.getCode());
    }

    public void postTrajectoryReceive(TransportDTO transportDTO) {
        OutApiSyncTrajectoryParamVO trajectoryParamVO = new OutApiSyncTrajectoryParamVO();

        WaybillDTO waybill = waybillService.getWaybillById(transportDTO.getWaybillId());
        trajectoryParamVO.setRegisteredUuid(waybill.getRegisteredUuid());

        List<OutApiSyncTrajectoryDetailVO> trajectoryDetailVOList = new ArrayList<>();
        TransportStageQuery stageQuery = new TransportStageQuery();
        stageQuery.setTransportId(transportDTO.getId());
        List<TransportStageInfoDTO> info = transportStageInfoService.listInfo(stageQuery);
        for (TransportStageInfoDTO transportStageInfoDTO : info) {
            OutApiSyncTrajectoryDetailVO outApiSyncTrajectoryDetailVO = new OutApiSyncTrajectoryDetailVO();
            Map<String, String> resolution = addressResolution(transportStageInfoDTO.getSubmitLocation());
            String province = resolution.get(Constants.PROVINCE);
            String city = resolution.get(Constants.CITY);
            String county = resolution.get(Constants.COUNTY);
            String describe = TransportStageEnum.findByCode(transportStageInfoDTO.getStage()).getText() + "地址" + province + city + county;
            outApiSyncTrajectoryDetailVO.setDescribe(describe);
            outApiSyncTrajectoryDetailVO.setTime(new Date());

            List<OutApiSyncTrajectoryPictureVO> trajectoryPictureVOList = new ArrayList<>();
            PictureQuery pictureQuery = new PictureQuery();
            pictureQuery.setLinkId(transportStageInfoDTO.getId());
            List<PictureInfoDTO> pictureInfoDTOList = pictureInfoService.listPictureInfo(pictureQuery);
            int count = 1;
            for (PictureInfoDTO pictureInfoDTO : pictureInfoDTOList) {
                OutApiSyncTrajectoryPictureVO outApiSyncTrajectoryPictureVO = new OutApiSyncTrajectoryPictureVO();
                outApiSyncTrajectoryPictureVO.setPicName(zmtClientService.getImag(pictureInfoDTO.getUrl(), "/"));
                outApiSyncTrajectoryPictureVO.setPicType(zmtClientService.getImag(pictureInfoDTO.getUrl(), "."));
                outApiSyncTrajectoryPictureVO.setPicData(pictureInfoDTO.getUrl());
                outApiSyncTrajectoryPictureVO.setPicSort(count++);
                trajectoryPictureVOList.add(outApiSyncTrajectoryPictureVO);
            }
            outApiSyncTrajectoryDetailVO.setPics(trajectoryPictureVOList);
            trajectoryDetailVOList.add(outApiSyncTrajectoryDetailVO);
        }
        trajectoryParamVO.setDetail_item_list(trajectoryDetailVOList);
        log.info(Constants.HEADER + "轨迹信息接收，param：{}", JSON.toJSONString(trajectoryParamVO));
        zmtClientService.postTrajectoryReceive(trajectoryParamVO);
    }

    /**
     * 审批验收单数据
     *
     * @param approvalVO
     * @return java.lang.String
     * @author FUXINSHENG
     * @date 2021/12/26 15:12
     * <p>
     * 1、校验参数是否异常
     * 2、校验当前用户是否有对应权限
     * 3、校验重量参数是否异常
     * 4、调用接口传递验收数量
     * 4、修改审批单数据
     * 5、修改运输单状态
     */
    @ServiceTimeLog
    @Transactional(rollbackFor = Exception.class)
    public Boolean approvalAccept(ApprovalVO approvalVO) {
        Validator.notNull(approvalVO.getLinkId(), ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.notNull(approvalVO.getApprovalType(), ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.isTrue(approvalVO.getApprovalType() == ApplicationTypeEnum.ACCEPT_STAGE.getCode(), ErrorCode.INPUT_PARAMETERS_INVALID);
        Validator.notNull(approvalVO.getResult(), ErrorCode.INPUT_PARAMETERS_NULL);

        UserDTO userDTO = userUtils.getUser(approvalVO.getToken());
        log.info(HEAD + "审批验收单数据, 当前用户id:{}, 请求参数:{}", userDTO.getId(), JSON.toJSONString(approvalVO));

        ApplicationQuery applicationQuery = new ApplicationQuery();
        applicationQuery.setLinkId(approvalVO.getLinkId());
        applicationQuery.setType(ApplicationTypeEnum.ACCEPT_STAGE.getCode());
        ApplicationInfoDTO applicationInfoDTO = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
        Validator.notNull(applicationInfoDTO, ErrorCode.APPLY_NULL);
        Validator.isTrue(applicationInfoDTO.getState() == ApplicationStateEnum.UNCHECK.getCode(), ErrorCode.APPLY_STATE_ERROR);
        TransportDTO transport = transportService.getTransportById(approvalVO.getLinkId());
        Validator.notNull(transport, ErrorCode.TRANSPORT_INFO_NULL);
        Validator.isTrue(transport.getState() == WaybillStateEnum.TRANSPORT.getCode(), ErrorCode.TRANSPORT_IS_EXP);
        Validator.isTrue(transport.getAcceptState() == WaybillStateEnum.UNCHECK.getCode(), ErrorCode.TRANSPORT_IS_EXP);
//        Validator.isTrue(userDTO.getId().equals(applicationInfoDTO.getApplyUserId()), ErrorCode.NO_POWER_GET);
        int driverMessageCode = 0;
        int submitterMessageCode = 0;

        if (approvalVO.getResult().equals(YesNoEnum.YES.getCode())) {
            TransportStageQuery stageQuery = new TransportStageQuery();
            stageQuery.setTransportId(approvalVO.getLinkId());
            stageQuery.setStage(TransportStageEnum.ACCEPTING.getCode());
            List<TransportStageInfoDTO> info = transportStageInfoService.listInfo(stageQuery);
            TransportStageInfoDTO transportStageInfoDTO = info.get(Constants.ZERO);
            PictureQuery pictureQuery = new PictureQuery();
            pictureQuery.setLinkId(transportStageInfoDTO.getId());
            pictureQuery.setType(PictureTypeEnum.ACCEPT.getCode());
            PictureInfoDTO pictureInfo = pictureInfoService.getPictureInfo(pictureQuery);
            VerifyPictureInfoVO verifyPictureInfoVO = JSON.parseObject(pictureInfo.getMessage(), VerifyPictureInfoVO.class);
            if (verifyPictureInfoVO.getGrossWeight() > verifyPictureInfoVO.getAcceptWeight()) {
                transport.setExpType(TransportStageExpEnum.COMPROMISE.getCode());
            }
            applicationInfoDTO.setState(ApplicationStateEnum.PASS.getCode());
            transport.setAcceptState(ApplicationStateEnum.PASS.getCode());
            transport.setState(WaybillStateEnum.FINISH.getCode());
            transport.setFinishTime(new Date());

            WaybillDTO waybill = waybillService.getWaybillById(transport.getWaybillId());
            OutApiSyncAcceptNumParamVO acceptNumParamVO = new OutApiSyncAcceptNumParamVO();
            acceptNumParamVO.setRegisteredUuid(waybill.getRegisteredUuid());
            acceptNumParamVO.setQuantity(verifyPictureInfoVO.getAcceptWeight());
            acceptNumParamVO.setAcceptTime(new Date());
            zmtClientService.postRegisteredDeal(acceptNumParamVO);
            driverMessageCode = MessageEnum.RECEIVE_SUCCESS_DRIVER.getCode();
            submitterMessageCode = MessageEnum.RECEIVE_SUCCESS_OTHER.getCode();
        } else if (approvalVO.getResult().equals(YesNoEnum.NO.getCode())) {
            applicationInfoDTO.setState(ApplicationStateEnum.REJECT.getCode());
            transport.setAcceptState(ApplicationStateEnum.REJECT.getCode());
            transport.setExpType(TransportStageExpEnum.REJECT.getCode());
            driverMessageCode = MessageEnum.RECEIVE_FAIL_DRIVER.getCode();
            submitterMessageCode = MessageEnum.RECEIVE_FAIL_OTHER.getCode();
        } else {
            Validator.notNull(null, ErrorCode.INPUT_PARAMETERS_INVALID);
        }
        transportService.updateTransport(transport);
        applicationInfoService.updateApplicationInfo(applicationInfoDTO);

        // 验收单审批完成后向司机和运输单发起人发送消息
        ApplicationQuery applicationQueryTrans = new ApplicationQuery();
        applicationQueryTrans.setLinkId(approvalVO.getLinkId());
        applicationQueryTrans.setType(ApplicationTypeEnum.TRANSPORT.getCode());
        applicationQueryTrans.setState(YesNoEnum.YES.getCode());
        ApplicationInfoDTO applicationInfoDTOTrans = applicationInfoService.getApplicationInfoByQuery(applicationQueryTrans);
        messageLoggingManager.messageHandling(transport.getDriverUserId(), driverMessageCode);
        messageLoggingManager.messageHandling(applicationInfoDTOTrans.getSubmitUserId(), submitterMessageCode);
        return true;
    }

    @ServiceTimeLog
    @Transactional(rollbackFor = Exception.class)
    public Boolean resubmitAccept(TransportStageInfoDTO stageInfoDTO) {
        Validator.notNull(stageInfoDTO, ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.notNull(stageInfoDTO.getId(), ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.notNull(stageInfoDTO.getTransportId(), ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.notNull(stageInfoDTO.getStage(), ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.notNull(CollectionUtils.isNotEmpty(stageInfoDTO.getPictureInfoDTOList()), ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.isTrue(stageInfoDTO.getStage().equals(TransportStageEnum.ACCEPTING.getCode()), ErrorCode.INPUT_PARAMETERS_INVALID);

        UserDTO userDTO = userUtils.getUser(stageInfoDTO.getToken());
        Validator.isTrue(userDTO.getType().equals(UserTypeEnum.DRIVER.getCode()), ErrorCode.NO_POWER_GET);
        log.info(HEAD + "重新提交验收单数据, 当前用户id:{}, 请求参数:{}", userDTO.getId(), JSON.toJSONString(stageInfoDTO));

        TransportDTO transport = transportService.getTransportById(stageInfoDTO.getTransportId());
        Validator.notNull(transport, ErrorCode.TRANSPORT_INFO_NULL);
        Validator.isTrue(transport.getState() == WaybillStateEnum.TRANSPORT.getCode(), ErrorCode.TRANSPORT_INFO_NULL);
        Validator.isTrue(transport.getAcceptState() == ApplicationStateEnum.REJECT.getCode(), ErrorCode.TRANSPORT_INFO_NULL);
        Validator.isTrue(transport.getDriverUserId().equals(userDTO.getId()), ErrorCode.NO_POWER_GET);

        ApplicationQuery applicationQuery = new ApplicationQuery();
        applicationQuery.setLinkId(stageInfoDTO.getTransportId());
        applicationQuery.setType(ApplicationTypeEnum.ACCEPT_STAGE.getCode());
        ApplicationInfoDTO applicationInfoByQuery = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
        Validator.isTrue(applicationInfoByQuery.getState() == ApplicationStateEnum.REJECT.getCode(), ErrorCode.APPLY_STATE_ERROR);

        TransportStageQuery transportStageQuery = new TransportStageQuery();
        transportStageQuery.setTransportId(stageInfoDTO.getTransportId());
        List<TransportStageInfoDTO> info = transportStageInfoService.listInfo(transportStageQuery);
        Validator.isTrue(CollectionUtils.isNotEmpty(info), ErrorCode.INPUT_PARAMETERS_INVALID);
        Validator.isTrue(info.size() == 3, ErrorCode.INPUT_PARAMETERS_INVALID);

        List<PictureInfoDTO> pictureInfoDTOList = stageInfoDTO.getPictureInfoDTOList();
        for (PictureInfoDTO pictureInfoDTO : pictureInfoDTOList) {
            Validator.notNull(pictureInfoDTO.getAcceptNum(), ErrorCode.INPUT_PARAMETERS_NULL);
            Validator.notNull(pictureInfoDTO.getMessage(), ErrorCode.INPUT_PARAMETERS_NULL);
            Validator.isTrue(pictureInfoDTO.getType() == PictureTypeEnum.ACCEPT.getCode(), ErrorCode.PICTURE_TYPE_ERROR);
            VerifyPictureInfoVO verifyPictureInfoVO = JSON.parseObject(pictureInfoDTO.getMessage(), VerifyPictureInfoVO.class);
            Validator.notNull(verifyPictureInfoVO, ErrorCode.INPUT_PARAMETERS_NULL);
            Validator.notNull(verifyPictureInfoVO.getAcceptNum(), ErrorCode.INPUT_PARAMETERS_NULL);
            Validator.notNull(verifyPictureInfoVO.getAcceptWeight(), ErrorCode.INPUT_PARAMETERS_NULL);
            Validator.notNull(verifyPictureInfoVO.getGrossWeight(), ErrorCode.INPUT_PARAMETERS_NULL);
        }
        initApplication(stageInfoDTO, userDTO, transport);
        stageInfoDTO.setSubmitTime(new Date());
        transportStageInfoService.updateTransportStage(stageInfoDTO);
        transportService.updateTransport(transport);
        int count = 1;
        PictureQuery pictureQuery = new PictureQuery();
        pictureQuery.setLinkId(stageInfoDTO.getId());
        pictureInfoService.deleteByLinkId(pictureQuery);
        for (PictureInfoDTO pictureInfo : stageInfoDTO.getPictureInfoDTOList()) {
            pictureInfo.setLinkId(stageInfoDTO.getId());
            pictureInfo.setLinkTable(Constants.TB_TRANSPORT_STAGE_INFO);
            pictureInfo.setSort(count++);
            pictureInfoService.addPictureInfo(pictureInfo);
        }
        // 当司机上传接收凭证，向审批人：屠宰场/代宰户发送消息
        if (ObjectUtils.isNotEmpty(transport.getSlaughterHouseId())) {
            messageLoggingManager.messageHandling(transport.getSlaughterHouseId(), MessageEnum.RECEIVE_VOUCHER_UPLOAD.getCode());
        }else {
            messageLoggingManager.messageHandling(transport.getBuyerUserId(), MessageEnum.RECEIVE_VOUCHER_UPLOAD.getCode());
        }
        return true;
    }
}
