package org.springblade.modules.app.manager;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wn.common.perfmonitor.annotation.ServiceTimeLog;
import com.wn.common.tools.date.DateUtils;
import com.wn.common.validator.Validator;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.modules.app.common.dto.*;
import org.springblade.modules.app.common.enums.*;
import org.springblade.modules.app.common.query.*;
import org.springblade.modules.app.common.vo.ApprovalVO;
import org.springblade.modules.app.common.vo.VerifyPictureInfoVO;
import org.springblade.modules.app.common.vo.WaybillListVO;
import org.springblade.modules.app.constant.Constants;
import org.springblade.modules.app.constant.ErrorCode;
import org.springblade.modules.app.entity.UserDO;
import org.springblade.modules.app.service.*;
import org.springblade.modules.app.utils.UserUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Component
public class TransportManager {

    @Autowired
    private IWaybillService waybillService;
    @Autowired
    private UserManager userManager;
    @Autowired
    private ITransportService transportService;
    @Autowired
    private IAppUserService userService;
    @Autowired
    private IApplicationInfoService applicationInfoService;
    @Autowired
    private ITransportStageInfoService transportStageInfoService;
    @Autowired
    private IPictureInfoService pictureInfoService;
    @Autowired
    private MessageLoggingManager messageLoggingManager;
    @Autowired
    private UserUtils userUtils;

    /**
     * 创建运输单
     *
     * @param transportDTO
     * @return java.lang.String
     * @author FUXINSHENG
     * @date 2021/11/12 9:29
     * @describe 1、校验运输单管理调运单状态
     * 2、校验当前用户与调运单间的关系：养殖场、屠宰场、代宰户
     * 3、校验司机信息是否在库中
     * 4、校验入省检疫站信息是否与调运单一致
     */
    @ServiceTimeLog
    @Transactional(rollbackFor = Exception.class)
    public String creatTransport(TransportDTO transportDTO) {
        UserDTO userDTO = userUtils.getUser(transportDTO.getToken());
        log.info("创建运输单,当前用户id:{} ,请求参数：{}", userDTO.getId(), JSON.toJSONString(transportDTO));
        //Validator.notNull(transportDTO, ErrorCode.TRANSPORT_IS_EXP);
//        Validator.notNull(transportDTO.getDriverUserId(), ErrorCode.TRANSPORT_IS_EXP);
        UserDTO driver = userService.getUserById(transportDTO.getDriverUserId());
        TransportQuery transportQuery = new TransportQuery();
        transportQuery.setWayBillId(transportDTO.getWaybillId());
        List<TransportDTO> transportDTOList = transportService.listTransport(transportQuery);
        Validator.isTrue(CollectionUtils.isEmpty(transportDTOList), ErrorCode.WAYBILL_HAVING_TRANSPORT);

        checkTransport(transportDTO, userDTO, driver);

        WaybillDTO waybill = waybillService.getWaybillById(transportDTO.getWaybillId());
        transportDTO.setAgentUserId(waybill.getAgentUserId());
        transportDTO.setAgentUserName(waybill.getAgentName());
        transportDTO.setSalerUserName(waybill.getSalerUserName());
        transportDTO.setBuyerUserName(waybill.getBuyerUserName());
        transportDTO.setCode(RandomStringUtils.randomNumeric(16));
        transportDTO.setSubmitTime(new Date());
        Long transportId = transportService.addTransport(transportDTO);

        ApplicationInfoDTO initApplicationInfo = userManager.initApplicationInfo(ApplicationTypeEnum.TRANSPORT.getCode(), transportId, driver, userDTO);
        initApplicationInfo.setLinkTable(Constants.TB_TRANSPORT);
        applicationInfoService.addApplicationInfo(initApplicationInfo);

        // 创建运输单后向司机发起消息
        messageLoggingManager.messageHandling(transportDTO.getDriverUserId(), MessageEnum.TRANSPORT_CREATE.getCode());
        return transportId.toString();
    }

    public void checkTransport(TransportDTO transportDTO, UserDTO userDTO, UserDTO driver) {
//        Validator.notNull(transportDTO.getWaybillId(), ErrorCode.TRANSPORT_IS_EXP);
        WaybillDTO waybill = waybillService.getWaybillById(transportDTO.getWaybillId());
//        Validator.notNull(waybill, ErrorCode.TRANSPORT_WAYBILL_INFO_EMPTY);
//        Validator.isTrue(waybill.getState().equals(WaybillStateEnum.FINISH.getCode()), ErrorCode.ORDER_INFO_STATE_ERROR);
//        Validator.notNull(waybill.getOutTradeNo(), ErrorCode.ORDER_INFO_STATE_ERROR);

        if (userDTO.getType().equals(UserTypeEnum.SLAUGHTER.getCode())) {
//            Validator.isTrue((waybill.getSlaughterHouseId() == null || waybill.getSlaughterHouseId() == 0) && waybill.getBuyerUserId().equals(userDTO.getId()), ErrorCode.NO_POWER_GET);
        } else if (userDTO.getType().equals(UserTypeEnum.FARM.getCode())) {
//            Validator.isTrue(waybill.getSalerUserId().equals(userDTO.getId()), ErrorCode.NO_POWER_GET);
        } else if (userDTO.getType().equals(UserTypeEnum.SLAUGHTER_HOUSE.getCode())) {
//            Validator.isTrue(waybill.getSlaughterHouseId().equals(userDTO.getId()), ErrorCode.NO_POWER_GET);
        } else if (userDTO.getType().equals(UserTypeEnum.AGENT.getCode())) {
//            Validator.isTrue(waybill.getAgentUserId().equals(userDTO.getId()), ErrorCode.NO_POWER_GET);
        } else {
//            Validator.isTrue(false, ErrorCode.NO_POWER_GET);
        }

//        Validator.notNull(driver, ErrorCode.DRIVER_IS_NULL);
//        Validator.isTrue(UserTypeEnum.DRIVER.getCode() == driver.getType(), ErrorCode.DRIVER_IS_NULL);
//        Validator.isTrue(UserStateEnum.PASS.getCode() == driver.getState(), ErrorCode.DRIVER_STATE_EXP);
        transportDTO.setState(WaybillStateEnum.UNCHECK.getCode());
//        Validator.notNull(transportDTO.getBuyerUserAddress(), ErrorCode.INPUT_PARAMETERS_NULL);
//        Validator.notNull(transportDTO.getBuyerAreaId(), ErrorCode.INPUT_PARAMETERS_NULL);
//        Validator.notNull(transportDTO.getBuyerCityId(), ErrorCode.INPUT_PARAMETERS_NULL);
//        Validator.notNull(transportDTO.getBuyerProvId(), ErrorCode.INPUT_PARAMETERS_NULL);
//        Validator.notNull(transportDTO.getBuyerPhone(), ErrorCode.INPUT_PARAMETERS_NULL);
//        Validator.notNull(transportDTO.getBuyerUserLinkMan(), ErrorCode.INPUT_PARAMETERS_NULL);
//        Validator.notNull(transportDTO.getSalerAreaId(), ErrorCode.INPUT_PARAMETERS_NULL);
//        Validator.notNull(transportDTO.getSalerCityId(), ErrorCode.INPUT_PARAMETERS_NULL);
//        Validator.notNull(transportDTO.getSalerProvId(), ErrorCode.INPUT_PARAMETERS_NULL);
//        Validator.notNull(transportDTO.getSalerUserAddress(), ErrorCode.INPUT_PARAMETERS_NULL);
//        Validator.notNull(transportDTO.getSalerPhone(), ErrorCode.INPUT_PARAMETERS_NULL);
//        Validator.notNull(transportDTO.getSalerUserLinkMan(), ErrorCode.INPUT_PARAMETERS_NULL);
//        Validator.notNull(transportDTO.getPriceType(), ErrorCode.INPUT_PARAMETERS_NULL);
//        Validator.notNull(transportDTO.getFrontPrice(), ErrorCode.INPUT_PARAMETERS_NULL);
//        Validator.notNull(transportDTO.getPrice(), ErrorCode.INPUT_PARAMETERS_NULL);
    }

    /**
     * @param transportId
     * @return org.springblade.modules.app.common.dto.TransportDTO
     * @author FUXINSHENG
     * @date 2021/11/12 15:10
     * @describe 1、校验用户是否可以获取该信息
     * 2、获取运输单的审批信息，是否具有驳回原因
     * 3、获取运输单的阶段信息，以及附件资料
     */
    @ServiceTimeLog
    public TransportDTO getTransportDetail(Long transportId, String token) {
        UserDTO userDTO = userUtils.getUser(token);
        log.info("获取调运单详情,当前用户id:{} ,请求参数：{}", userDTO.getId(), transportId);
        TransportDTO transportDTO = transportService.getTransportById(transportId);
        Validator.notNull(transportDTO, ErrorCode.TRANSPORT_INFO_NULL);
        Long waybillId = transportDTO.getWaybillId();
        WaybillDTO waybill = waybillService.getWaybillById(waybillId);
        Validator.notNull(waybill, ErrorCode.WAYBILL_INFO_EMPTY);

        if (userDTO.getType().equals(UserTypeEnum.SLAUGHTER.getCode())) {
            Validator.isTrue(waybill.getBuyerUserId().equals(userDTO.getId()), ErrorCode.NO_POWER_GET);
        } else if (userDTO.getType().equals(UserTypeEnum.FARM.getCode())) {
            Validator.isTrue(waybill.getSalerUserId().equals(userDTO.getId()), ErrorCode.NO_POWER_GET);
        } else if (userDTO.getType().equals(UserTypeEnum.SLAUGHTER_HOUSE.getCode())) {
            Validator.isTrue(waybill.getSlaughterHouseId().equals(userDTO.getId()), ErrorCode.NO_POWER_GET);
        } else if (userDTO.getType().equals(UserTypeEnum.AGENT.getCode())) {
            Validator.isTrue(waybill.getAgentUserId().equals(userDTO.getId()), ErrorCode.NO_POWER_GET);
        } else if (userDTO.getType().equals(UserTypeEnum.DRIVER.getCode())) {
            Validator.isTrue(transportDTO.getDriverUserId().equals(userDTO.getId()), ErrorCode.NO_POWER_GET);
        } else {
            Validator.isTrue(false, ErrorCode.NO_POWER_GET);
        }

        ApplicationQuery applicationQuery = new ApplicationQuery();
        applicationQuery.setLinkId(transportId);
        applicationQuery.setType(ApplicationTypeEnum.TRANSPORT.getCode());
        ApplicationInfoDTO applicationInfoDTO = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
        if (applicationInfoDTO.getState() == ApplicationStateEnum.REJECT.getCode()) {
            transportDTO.setMessage(applicationInfoDTO.getMessage());
        }
        transportDTO.setIfCreator(userDTO.getId().equals(applicationInfoDTO.getSubmitUserId()) ? YesNoEnum.YES.getCode() : YesNoEnum.NO.getCode());

        if (transportDTO.getSlaughterHouseId() == 0) {
            transportDTO.setSlaughterHouseId(null);
        }
        TransportStageQuery transportStageQuery = new TransportStageQuery();
        transportStageQuery.setTransportId(transportId);
        List<TransportStageInfoDTO> transportStageInfoDTOList = transportStageInfoService.listInfo(transportStageQuery);
        if (CollectionUtils.isNotEmpty(transportStageInfoDTOList)) {
            for (TransportStageInfoDTO transportStageInfoDTO : transportStageInfoDTOList) {
                PictureQuery query = new PictureQuery();
                query.setLinkId(transportStageInfoDTO.getId());
                List<PictureInfoDTO> pictureInfoDTOList = pictureInfoService.listPictureInfo(query);
                transportStageInfoDTO.setPictureInfoDTOList(pictureInfoDTOList);
            }
        }

        transportDTO.setStageInfoDTOList(transportStageInfoDTOList);
        return transportDTO;
    }

    /**
     * 获取运输单列表
     *
     * @param
     * @return java.util.List<org.springblade.modules.app.common.vo.WaybillListVO>
     * @author FUXINSHENG
     * @date 2021/11/12 15:50
     * @describe 1、校验用户角色
     * 2、根据用户的id查询调运单信息
     * 3、获取所有调运单的运输单
     */
    @ServiceTimeLog
    public List<WaybillListVO> getTransportList(WaybillClientQuery waybillClientQuery) {
        UserDTO userDTO = userUtils.getUser(waybillClientQuery.getToken());
        log.info("获取运输单列表,当前用户id:{}", userDTO.getId());
        TransportQuery transportQuery = new TransportQuery();
        List<Integer> stateList = new ArrayList<>();
        if (waybillClientQuery == null || waybillClientQuery.getState() == null || waybillClientQuery.getState() == WaybillClientStateEnum.Going.getCode()) {
            stateList.add(WaybillStateEnum.UNCHECK.getCode());
            stateList.add(WaybillStateEnum.PASS.getCode());
            stateList.add(WaybillStateEnum.TRANSPORT.getCode());
//            transportQuery.setNeAcceptState(ApplicationStateEnum.REJECT.getCode());
        } else if (waybillClientQuery.getState() == WaybillClientStateEnum.FINISH.getCode()) {
            stateList.add(WaybillStateEnum.FINISH.getCode());
        } else if (waybillClientQuery.getState() == WaybillClientStateEnum.REJECT.getCode()) {
            stateList.add(WaybillStateEnum.REJECT.getCode());
            stateList.add(WaybillStateEnum.UNPASS.getCode());
//            transportQuery.setAcceptState(ApplicationStateEnum.REJECT.getCode());
//            transportQuery.setIsList(YesNoEnum.YES.getCode());
        } else if (waybillClientQuery.getState() == WaybillClientStateEnum.ALL.getCode()) {
            stateList = null;
        }
        transportQuery.setStateList(stateList);

        if (userDTO.getType().equals(UserTypeEnum.SLAUGHTER.getCode())) {
            transportQuery.setBuyerId(userDTO.getId());
        } else if (userDTO.getType().equals(UserTypeEnum.FARM.getCode())) {
            transportQuery.setSalerId(userDTO.getId());
        } else if (userDTO.getType().equals(UserTypeEnum.SLAUGHTER_HOUSE.getCode())) {
            transportQuery.setSlaughterHouseId(userDTO.getId());
        } else if (userDTO.getType().equals(UserTypeEnum.AGENT.getCode())) {
            transportQuery.setAgentId(userDTO.getId());
        } else if (userDTO.getType().equals(UserTypeEnum.DRIVER.getCode())) {
            transportQuery.setDriverId(userDTO.getId());
        } else {
            Validator.isTrue(false, ErrorCode.NO_POWER_GET);
        }
        List<WaybillListVO> waybillListVOList = new ArrayList<>();
        List<TransportDTO> transportDTOS = transportService.listTransport(transportQuery);
        if (CollectionUtils.isNotEmpty(transportDTOS)) {
            for (TransportDTO transportDTO : transportDTOS) {
                WaybillListVO waybillListVO = new WaybillListVO();
                waybillListVO.setState(transportDTO.getState());
//                if (transportDTO.getAcceptState() == ApplicationStateEnum.REJECT.getCode()) {
//                    waybillListVO.setState(WaybillStateEnum.REJECT.getCode());
//                }
                waybillListVO.setBillName(transportDTO.getWaybillName());
                waybillListVO.setCreatedTime(transportDTO.getCreatedTime());
                waybillListVO.setId(transportDTO.getId());
                waybillListVO.setAcceptState(transportDTO.getAcceptState());
                waybillListVOList.add(waybillListVO);
            }
        }

        if (CollectionUtils.isNotEmpty(waybillListVOList)) {
            ApplicationQuery applicationQuery = new ApplicationQuery();
            applicationQuery.setType(ApplicationTypeEnum.TRANSPORT.getCode());
            for (WaybillListVO waybillListVO : waybillListVOList) {
                applicationQuery.setLinkId(waybillListVO.getId());
                ApplicationInfoDTO applicationInfoDTO = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
                waybillListVO.setIfCreator(userDTO.getId().equals(applicationInfoDTO.getSubmitUserId()) ? YesNoEnum.YES.getCode() : YesNoEnum.NO.getCode());
            }
        }
        return waybillListVOList;
    }

    /**
     * 审批运输单
     *
     * @param approvalVO
     * @return java.lang.Boolean
     * @author FUXINSHENG
     * @date 2021/11/12 16:14
     * @describe
     */
    @ServiceTimeLog
    @Transactional(rollbackFor = Exception.class)
    public Boolean approvalTransport(ApprovalVO approvalVO) {
        UserDTO userDTO = userUtils.getUser(approvalVO.getToken());
        log.info("审批运输单,当前用户id:{}, 请求参数：{}", userDTO.getId(), JSON.toJSONString(approvalVO));
        Validator.notNull(approvalVO, ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.notNull(approvalVO.getLinkId(), ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.notNull(approvalVO.getResult(), ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.notNull(approvalVO.getApprovalType(), ErrorCode.INPUT_PARAMETERS_NULL);

        Long transportId = approvalVO.getLinkId();
        TransportDTO transport = transportService.getTransportById(transportId);
        Validator.notNull(transport, ErrorCode.TRANSPORT_INFO_NULL);
        Validator.isTrue(transport.getState() == WaybillStateEnum.UNCHECK.getCode(), ErrorCode.TRANSPORT_INFO_NULL);
        Validator.isTrue(userDTO.getId().equals(transport.getDriverUserId()), ErrorCode.NO_POWER_GET);
        ApplicationQuery applicationQuery = new ApplicationQuery();
        applicationQuery.setLinkId(transportId);
        applicationQuery.setType(ApplicationTypeEnum.TRANSPORT.getCode());
        ApplicationInfoDTO applicationInfoDTO = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
        Validator.isTrue(applicationInfoDTO.getState() == ApplicationStateEnum.UNCHECK.getCode(), ErrorCode.APPLY_STATE_ERROR);
        int messageCode = 0;

        if (approvalVO.getResult().equals(YesNoEnum.NO.getCode())) {
            applicationInfoDTO.setState(ApplicationStateEnum.REJECT.getCode());
            applicationInfoDTO.setMessage(approvalVO.getMessage());
            transport.setState(WaybillStateEnum.REJECT.getCode());
            messageCode = MessageEnum.TRANSPORT_FAIL.getCode();
        } else {
            applicationInfoDTO.setState(ApplicationStateEnum.PASS.getCode());
            transport.setConfirmTime(new Date());
            transport.setState(WaybillStateEnum.TRANSPORT.getCode());
            messageCode = MessageEnum.TRANSPORT_ADOPT.getCode();
        }
        applicationInfoService.updateApplicationInfo(applicationInfoDTO);
        transportService.updateTransport(transport);

        // 司机审批后向运输单发起人：经纪人/养殖场/屠宰场/代宰户
        if (ObjectUtils.isNotEmpty(applicationInfoDTO.getSubmitUserId())) {
            messageLoggingManager.messageHandling(applicationInfoDTO.getSubmitUserId(), messageCode);
        }
        return true;
    }

    /**
     * @param transportDTO
     * @return java.lang.Boolean
     * @author FUXINSHENG
     * @date 2021/11/12 16:46
     * @describe 1、获取原来的运输单，校验状态为驳回/未通过
     * 2、获取原来的运输单审批记录，校验状态为未通过
     * 3、校验用户角色，是否可以重新进行提交运输单
     * 4、根据创建运输单的逻辑，校验运输单详情
     * 5、更新运输单，并重新创建新的审批记录
     */
    @ServiceTimeLog
    @Transactional(rollbackFor = Exception.class)
    public Boolean resubmitTransport(TransportDTO transportDTO) {
        UserDTO userDTO = userUtils.getUser(transportDTO.getToken());
        log.info("重新提交运输单,当前用户id:{}, 请求参数：{}", userDTO.getId(), JSON.toJSONString(transportDTO));

        Validator.notNull(transportDTO, ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.notNull(transportDTO.getId(), ErrorCode.INPUT_PARAMETERS_NULL);
        UserDTO driver = userService.getUserById(transportDTO.getDriverUserId());

        TransportDTO transport = transportService.getTransportById(transportDTO.getId());
        Validator.notNull(transport, ErrorCode.TRANSPORT_INFO_NULL);
        Validator.isTrue(transport.getState() == WaybillStateEnum.REJECT.getCode() || transport.getState() == WaybillStateEnum.CANCEL.getCode(), ErrorCode.TRANSPORT_INFO_NULL);
        ApplicationQuery applicationQuery = new ApplicationQuery();
        applicationQuery.setType(ApplicationTypeEnum.TRANSPORT.getCode());
        applicationQuery.setLinkId(transportDTO.getId());
        applicationQuery.setSubmitUserId(userDTO.getId());
        ApplicationInfoDTO applicationInfoDTO = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
        Validator.notNull(applicationInfoDTO, ErrorCode.INPUT_PARAMETERS_INVALID);
        Validator.isTrue(applicationInfoDTO.getState() == ApplicationStateEnum.REJECT.getCode()
                || applicationInfoDTO.getState() == ApplicationStateEnum.CANCEL.getCode(), ErrorCode.INPUT_PARAMETERS_INVALID);
        checkTransport(transportDTO, userDTO, driver);
        transportDTO.setAgentUserId(null);
        transportDTO.setSubmitTime(new Date());
        transportService.updateTransport(transportDTO);
        ApplicationInfoDTO initApplicationInfo = userManager.initApplicationInfo(ApplicationTypeEnum.TRANSPORT.getCode(), transportDTO.getId(), driver, userDTO);
        initApplicationInfo.setLinkTable(Constants.TB_TRANSPORT);
        applicationInfoService.addApplicationInfo(initApplicationInfo);

        // 创建运输单后向司机发起消息
        messageLoggingManager.messageHandling(transportDTO.getDriverUserId(), MessageEnum.TRANSPORT_CREATE.getCode());

        return true;
    }


    public String getOutcode(Long transportId, String token) {
        UserDTO userDTO = userUtils.getUser(token);
        log.info("获取调运单外部编号,当前用户id:{},请求参数：{}", userDTO.getId(), JSON.toJSONString(transportId));
        Validator.notNull(transportId, ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.isTrue(userDTO.getType().equals(UserTypeEnum.DRIVER.getCode()), ErrorCode.NO_POWER_GET);
        TransportDTO transport = transportService.getTransportById(transportId);
        Validator.notNull(transport, ErrorCode.TRANSPORT_INFO_NULL);
        Validator.isTrue(transport.getState() == WaybillStateEnum.TRANSPORT.getCode(), ErrorCode.TRANSPORT_INFO_EXP);
        Validator.isTrue(transport.getDriverUserId().equals(userDTO.getId()), ErrorCode.NO_POWER_GET);

        return transport.getWaybillOutCode();
    }

    public TransportDTO initTransport(Long waybillId, String token) {
        UserDTO userDTO = userUtils.getUser(token);
        log.info("初始化运输单信息,当前用户id:{},请求参数：{}", userDTO.getId(), JSON.toJSONString(waybillId));
        WaybillDTO waybill = waybillService.getWaybillById(waybillId);
        checkWaybillPower(userDTO, waybill);
        Validator.notNull(waybill, ErrorCode.TRANSPORT_WAYBILL_INFO_EMPTY);
        Validator.isTrue(waybill.getState().equals(WaybillStateEnum.FINISH.getCode()), ErrorCode.ORDER_INFO_STATE_ERROR);
        TransportDTO transport = new TransportDTO();
        UserDTO farm = userService.getUserById(waybill.getSalerUserId());

        if (StringUtil.isEmpty(farm)) {
            UserDO farm1 = userService.getOne(Wrappers.<UserDO>lambdaQuery().eq(UserDO::getZmtUserId, waybill.getSalerUserId()).last("limit 1"), false);
            if (StringUtil.isEmpty(farm1)) {
                Validator.notNull(waybill.getAgentUserId(), ErrorCode.TRANSPORT_USER_IS_EXP);
            } else {
                farm = new UserDTO();
                BeanUtils.copyProperties(farm1, farm);
            }

        }

        if (StringUtil.isEmpty(waybill.getAgentUserId())) {
            Validator.isTrue(farm.getState() == UserStateEnum.PASS.getCode(), ErrorCode.TRANSPORT_USER_IS_EXP);

            transport.setSalerAreaId(farm.getAreaId());
            transport.setSalerCityId(farm.getCityId());
            transport.setSalerProvId(farm.getProvId());
            transport.setSalerPhone(farm.getPhone());
            transport.setSalerUserAddress(farm.getAddress());
            transport.setSalerUserLinkMan(farm.getBusinessLinkMan());
        }

        if(!StringUtil.isEmpty(farm)){
            transport.setSalerAreaId(farm.getAreaId());
            transport.setSalerCityId(farm.getCityId());
            transport.setSalerProvId(farm.getProvId());
            transport.setSalerPhone(farm.getPhone());
            transport.setSalerUserAddress(farm.getAddress());
            transport.setSalerUserLinkMan(farm.getBusinessLinkMan());
        }


        Boolean flag = waybill.getSlaughterHouseId() != null && waybill.getSlaughterHouseId() != 0;
        //Long userId = Boolean.TRUE.equals(flag) ? waybill.getSlaughterHouseId() : waybill.getBuyerUserId();
        Long userId = waybill.getBuyerUserId();

        UserDTO user = userService.getUserById(userId);
        Validator.notNull(user, ErrorCode.TRANSPORT_USER_IS_EXP);
        Validator.isTrue(user.getState() == UserStateEnum.PASS.getCode(), ErrorCode.TRANSPORT_USER_IS_EXP);

//        transport.setBuyerAreaId(user.getAreaId());
//        transport.setBuyerCityId(user.getCityId());
//        transport.setBuyerProvId(user.getProvId());
//        transport.setBuyerPhone(user.getPhone());
//        transport.setBuyerUserAddress(user.getAddress());
//        transport.setBuyerUserLinkMan(Boolean.TRUE.equals(flag) ? user.getUserName() : user.getBusinessLinkMan());
        transport.setBuyerAreaId(user.getAreaId());
        transport.setBuyerCityId(user.getCityId());
        transport.setBuyerProvId(user.getProvId());
        transport.setBuyerPhone(user.getPhone());
        transport.setBuyerUserAddress(user.getAddress());
        transport.setBuyerUserLinkMan(Boolean.TRUE.equals(flag) ? user.getUserName() : user.getBusinessLinkMan());

       return transport;
    }

    public static void checkWaybillPower(UserDTO userDTO, WaybillDTO waybill) {
        UserTypeEnum type = UserTypeEnum.findByCode(userDTO.getType());
        switch (type) {
            case FARM:
                Validator.isTrue(waybill.getSalerUserId().equals(userDTO.getId()), ErrorCode.NO_POWER_GET);
                break;
            case SLAUGHTER:
                Validator.isTrue(waybill.getBuyerUserId().equals(userDTO.getId()), ErrorCode.NO_POWER_GET);
                break;
            case SLAUGHTER_HOUSE:
                Validator.isTrue(waybill.getSlaughterHouseId().equals(userDTO.getId()), ErrorCode.NO_POWER_GET);
                break;
            case AGENT:
                Validator.isTrue(waybill.getAgentUserId().equals(userDTO.getId()), ErrorCode.NO_POWER_GET);
                break;
            default:
                Validator.isTrue(false, ErrorCode.NO_POWER_GET);
                break;
        }
    }

    public Page<TransportDTO> pageTransport(AdminWaybillQuery transportQuery) {
//        log.info("管理端分页查询运输单列表, 请求参数:{}", JSON.toJSONString(transportQuery));
        Page<TransportDTO> page = transportService.pageTransport(transportQuery);
        List<TransportDTO> records = page.getRecords();
        for (TransportDTO transportDTO : records) {
            WaybillDTO waybill = waybillService.getWaybillById(transportDTO.getWaybillId());
            transportDTO.setWaybillCode(waybill.getBillCode());
        }
        return page;
    }

    public List<TransportStageInfoDTO> getTransportStageDetail(Long id) {
//        log.info("管理端分页查询运输单阶段信息, 请求参数:{}", JSON.toJSONString(id));
        TransportStageQuery transportStageQuery = new TransportStageQuery();
        transportStageQuery.setTransportId(id);
        List<TransportStageInfoDTO> stageInfoDTOList = transportStageInfoService.listInfo(transportStageQuery);
        PictureQuery pictureQuery = new PictureQuery();
        for (TransportStageInfoDTO transportStageInfoDTO : stageInfoDTOList) {
            pictureQuery.setLinkId(transportStageInfoDTO.getId());
            List<PictureInfoDTO> pictureInfoDTOList = pictureInfoService.listPictureInfo(pictureQuery);
            transportStageInfoDTO.setPictureInfoDTOList(pictureInfoDTOList);
        }
        return stageInfoDTOList;
    }

    /**
     * @param transportId
     * @return org.springblade.modules.app.common.dto.TransportDTO
     * @author FUXINSHENG
     * @date 2021/11/12 15:10
     * @describe 1、校验用户是否可以获取该信息
     * 2、获取运输单的审批信息，是否具有驳回原因
     * 3、获取运输单的阶段信息，以及附件资料
     */
    @ServiceTimeLog
    public TransportDTO getAdminTransportDetail(Long transportId) {
        log.info("管理端获取调运单详情, 请求参数：{}", transportId);
        TransportDTO transportDTO = transportService.getTransportById(transportId);
        Validator.notNull(transportDTO, ErrorCode.TRANSPORT_INFO_NULL);
        Long waybillId = transportDTO.getWaybillId();
        WaybillDTO waybill = waybillService.getWaybillById(waybillId);
        Validator.notNull(waybill, ErrorCode.WAYBILL_INFO_EMPTY);

        UserDTO driver = userService.getUserById(transportDTO.getDriverUserId());
        transportDTO.setDriverLicenceCode(driver.getDriverLicenceCode());
        transportDTO.setDriverLicenceUrl(driver.getDriverLicenceUrl());

        if (transportDTO.getState() == WaybillStateEnum.REJECT.getCode()) {
            ApplicationQuery applicationQuery = new ApplicationQuery();
            applicationQuery.setLinkId(transportId);
            applicationQuery.setType(ApplicationTypeEnum.TRANSPORT.getCode());
            ApplicationInfoDTO applicationInfoDTO = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
            Validator.notNull(applicationInfoDTO, ErrorCode.APPLY_NULL);
            Validator.isTrue(applicationInfoDTO.getState() == ApplicationStateEnum.REJECT.getCode(), ErrorCode.APPLY_STATE_ERROR);
            transportDTO.setMessage(applicationInfoDTO.getMessage());
            transportDTO.setApplyUserName(applicationInfoDTO.getApplyUserName());
        }

        if (transportDTO.getState() == WaybillStateEnum.FINISH.getCode()) {
            ApplicationQuery applicationQuery = new ApplicationQuery();
            applicationQuery.setLinkId(transportId);
            applicationQuery.setType(ApplicationTypeEnum.TRANSPORT.getCode());
            ApplicationInfoDTO applicationInfoDTO = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
            transportDTO.setApplyUserName(applicationInfoDTO.getApplyUserName());
        }

        TransportStageQuery transportStageQuery = new TransportStageQuery();
        transportStageQuery.setTransportId(transportId);
        List<TransportStageInfoDTO> transportStageInfoDTOList = transportStageInfoService.listInfo(transportStageQuery);
        if (CollectionUtils.isNotEmpty(transportStageInfoDTOList)) {
            for (TransportStageInfoDTO transportStageInfoDTO : transportStageInfoDTOList) {
                PictureQuery query = new PictureQuery();
                query.setLinkId(transportStageInfoDTO.getId());
                List<PictureInfoDTO> pictureInfoDTOList = pictureInfoService.listPictureInfo(query);
                transportStageInfoDTO.setPictureInfoDTOList(pictureInfoDTOList);
            }
        }

        transportDTO.setStageInfoDTOList(transportStageInfoDTOList);
        return transportDTO;
    }

    /**
     * 司机自动确认运输单
     *
     * @param
     * @return void
     * @author FUXINSHENG
     * @date 2021/12/28 9:09
     */
    @ServiceTimeLog
    @Transactional(rollbackFor = Exception.class)
    public void driverConfirmJobHandler() {
        TransportQuery transportQuery = new TransportQuery();
        transportQuery.setState(WaybillStateEnum.UNCHECK.getCode());
        List<TransportDTO> transportDTOS = transportService.listTransport(transportQuery);
        if (CollectionUtils.isEmpty(transportDTOS)) {
            return;
        }
        List<TransportDTO> transportDTOList = new ArrayList<>();
        List<ApplicationInfoDTO> applicationInfoDTOList = new ArrayList<>();
        for (TransportDTO transportDTO : transportDTOS) {
            Date now = new Date();
            Date endTime = DateUtils.addDay(transportDTO.getSubmitTime(), 1);
            if (now.getTime() > endTime.getTime()) {
                transportDTO.setState(WaybillStateEnum.TRANSPORT.getCode());
                ApplicationQuery applicationQuery = new ApplicationQuery();
                applicationQuery.setLinkId(transportDTO.getId());
                applicationQuery.setType(ApplicationTypeEnum.TRANSPORT.getCode());
                ApplicationInfoDTO applicationInfo = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
                log.info("查询运输单审批记录，Param:{}", JSON.toJSONString(applicationQuery));
                Validator.notNull(applicationInfo, ErrorCode.APPLY_NULL);
                applicationInfo.setState(ApplicationStateEnum.PASS.getCode());
                applicationInfo.setMessage("超过24小时，运输单自动通过");
                applicationInfoDTOList.add(applicationInfo);
                transportDTOList.add(transportDTO);
            }
        }
        if (CollectionUtils.isNotEmpty(applicationInfoDTOList)) {
            applicationInfoService.updateBatchApplicationInfo(applicationInfoDTOList);
        }
        if (CollectionUtils.isNotEmpty(transportDTOList)) {
            transportService.updateBatch(transportDTOList);
        }
    }

    /**
     * 屠宰场自动确认验收
     *
     * @param
     * @return void
     * @author FUXINSHENG
     * @date 2021/12/28 9:09
     */
    @ServiceTimeLog
    @Transactional(rollbackFor = Exception.class)
    public void slaughterAcceptConfirm() {
        TransportQuery transportQuery = new TransportQuery();
        transportQuery.setAcceptState(ApplicationStateEnum.UNCHECK.getCode());
        List<TransportDTO> transportDTOS = transportService.listTransport(transportQuery);
        if (CollectionUtils.isEmpty(transportDTOS)) {
            return;
        }
        List<ApplicationInfoDTO> applicationInfoDTOList = new ArrayList<>();
        List<TransportDTO> transportDTOList = new ArrayList<>();
        List<TransportStageInfoDTO> transportStageInfoDTOList = new ArrayList<>();

        for (TransportDTO transportDTO : transportDTOS) {
            TransportStageQuery stageQuery = new TransportStageQuery();
            stageQuery.setTransportId(transportDTO.getId());
            stageQuery.setStage(TransportStageEnum.ACCEPTING.getCode());
            TransportStageInfoDTO stageInfoDTO = transportStageInfoService.getInfo(stageQuery);
            log.info("查询运输单阶段信息，Param:{}", JSON.toJSONString(stageQuery));
            Validator.notNull(stageInfoDTO, ErrorCode.TRANSPORT_IS_EXP);

            Date now = new Date();
            Date endTime = DateUtils.addDay(stageInfoDTO.getSubmitTime(), 1);
            if (now.getTime() > endTime.getTime()) {
                transportStageInfoDTOList.add(stageInfoDTO);

                ApplicationQuery applicationQuery = new ApplicationQuery();
                applicationQuery.setLinkId(transportDTO.getId());
                applicationQuery.setType(ApplicationTypeEnum.ACCEPT_STAGE.getCode());
                ApplicationInfoDTO applicationInfo = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
                Validator.notNull(applicationInfo, ErrorCode.APPLY_NULL);
                applicationInfo.setState(ApplicationStateEnum.PASS.getCode());
                applicationInfo.setMessage("超过24小时，运输单自动通过");
                applicationInfoDTOList.add(applicationInfo);

                transportDTO.setAcceptState(ApplicationStateEnum.PASS.getCode());
                transportDTO.setState(WaybillStateEnum.FINISH.getCode());
                transportDTO.setFinishTime(new Date());

                PictureQuery pictureQuery = new PictureQuery();
                pictureQuery.setLinkId(stageInfoDTO.getId());
                pictureQuery.setType(PictureTypeEnum.ACCEPT.getCode());
                PictureInfoDTO pictureInfo = pictureInfoService.getPictureInfo(pictureQuery);
                VerifyPictureInfoVO verifyPictureInfoVO = JSON.parseObject(pictureInfo.getMessage(), VerifyPictureInfoVO.class);
                if (verifyPictureInfoVO.getGrossWeight() > verifyPictureInfoVO.getAcceptWeight()) {
                    transportDTO.setExpType(TransportStageExpEnum.COMPROMISE.getCode());
                } else {
                    transportDTO.setExpType(TransportStageExpEnum.OVERTIME.getCode());
                }
                transportDTOList.add(transportDTO);
            }
        }
        if (CollectionUtils.isNotEmpty(transportStageInfoDTOList)) {
            transportStageInfoService.updateBatch(transportStageInfoDTOList);
        }
        if (CollectionUtils.isNotEmpty(applicationInfoDTOList)) {
            applicationInfoService.updateBatchApplicationInfo(applicationInfoDTOList);
        }
        if (CollectionUtils.isNotEmpty(transportDTOList)) {
            transportService.updateBatch(transportDTOList);
        }
    }

    /**
     * 撤销运输单
     * 1，校验：
     * 1.1 运输单状态=0（待确认）
     * 1.2 用户必须是创建调运单的用户（运输单用户从审批信息中获取）
     * 2，更新运输单状态为撤销
     * 3，删除审批信息
     *
     * @param id
     * @param userDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean cancel(Long id, UserDTO userDTO) {
        Validator.notNull(id, ErrorCode.INPUT_PARAMETERS_NULL);
        TransportDTO transportDTO = transportService.getTransportById(id);
        Validator.notNull(transportDTO, ErrorCode.TRANSPORT_INFO_NULL);
        Validator.notNull(transportDTO.getState().intValue() == WaybillStateEnum.UNCHECK.getCode(), ErrorCode.TRANSPORT_STATE_NOT_UNCHECK);
        ApplicationQuery applicationQuery = new ApplicationQuery();
        applicationQuery.setLinkId(transportDTO.getId());
        applicationQuery.setType(ApplicationTypeEnum.TRANSPORT.getCode());
        ApplicationInfoDTO applicationInfoDTO = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
        Validator.notNull(applicationInfoDTO, ErrorCode.APPLY_NULL);
        long creator = applicationInfoDTO.getSubmitUserId() == null ? 0 : applicationInfoDTO.getSubmitUserId().longValue();
        Validator.isTrue(creator == userDTO.getId().longValue(), ErrorCode.ORDER_INFO_MAST_CREATOR);
        //更新运输单信息
        transportDTO.setState(WaybillStateEnum.CANCEL.getCode());
        transportDTO.setModifiedTime(new Date());
        Validator.isTrue(transportService.updateTransport(transportDTO), ErrorCode.TRANSPORT_UPDATE_FAIL);
        //更新审核信息状态
        applicationInfoDTO.setState(ApplicationStateEnum.CANCEL.getCode());
        Validator.isTrue(applicationInfoService.updateApplicationInfo(applicationInfoDTO), ErrorCode.UPDATE_DATA_ERROR);
        return true;
    }


    public String getVerifycode(Long transportId, UserDTO userDTO) {
        Validator.notNull(transportId, ErrorCode.INPUT_PARAMETERS_NULL);
        TransportStageQuery transportStageQuery = new TransportStageQuery();
        transportStageQuery.setTransportId(transportId);
        transportStageQuery.setStage(TransportStageEnum.CHECKING.getCode());
        TransportStageInfoDTO transportStageInfoDTO = transportStageInfoService.getInfo(transportStageQuery);
        if (transportStageInfoDTO != null) {
            PictureQuery query = new PictureQuery();
            query.setLinkId(transportStageInfoDTO.getId());
            query.setType(PictureTypeEnum.A_TICKET.getCode());
            PictureInfoDTO pictureInfoDTO = pictureInfoService.getPictureInfo(query);
            if (pictureInfoDTO != null && StringUtils.isNotBlank(pictureInfoDTO.getMessage())) {
                return JSONObject.parseObject(pictureInfoDTO.getMessage()).getString("verifyCode");
            }
        }
        return null;
    }


    /**
     * 运输单自动关闭
     * 关闭条件：
     * 1，运输单状态在0-2之间
     * 2，运输单关联的调运单的计划时间>当前时间-48小时
     * 3，关联的运输阶段 stage=3（验收）有数据
     */
    public void autoClose() {
        log.info("进入运输单自动关闭处理方法-------------");
        //查询运输单
        List<TransportDTO> list = transportService.queryAutoCloseData();
        if (CollectionUtils.isNotEmpty(list)) {
            log.info("【运输单自动关闭】当前可处理数据数量={}", list.size());
            ((TransportManager) AopContext.currentProxy()).doClose(list);
        } else {
            log.info("【运输单自动关闭】当前没有可处理数据");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void doClose(List<TransportDTO> list) {
        for (TransportDTO dto : list) {
            dto.setState(WaybillStateEnum.CLOSE.getCode());
            dto.setModifiedTime(new Date());
        }
        transportService.updateBatch(list);
    }

}
