package com.ningdatech.carapi.car.vehicle.manage;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletResponse;

import com.ningdatech.carapi.car.position.model.po.ReqDataPO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.function.VUtils;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.basic.util.CollUtils;
import com.ningdatech.carapi.archives.enums.AuditStateEnum;
import com.ningdatech.carapi.car.vehicle.contants.VehicleContant;
import com.ningdatech.carapi.car.vehicle.model.NdVehicleBaseInfo;
import com.ningdatech.carapi.car.vehicle.model.NdVehicleBaseInfoJoin;
import com.ningdatech.carapi.car.vehicle.model.dto.*;
import com.ningdatech.carapi.car.vehicle.model.vo.VehicleBaseVO;
import com.ningdatech.carapi.car.vehicle.model.vo.VehicleCarPlateVO;
import com.ningdatech.carapi.car.vehicle.service.IVehicleBaseInfoJoinService;
import com.ningdatech.carapi.car.vehicle.service.IVehicleBaseInfoService;
import com.ningdatech.carapi.common.aop.BuildChildrenRegionWrapper;
import com.ningdatech.carapi.common.constant.*;
import com.ningdatech.carapi.common.helper.UserInfoHelper;
import com.ningdatech.carapi.common.util.CodeUtil;
import com.ningdatech.carapi.common.util.ExcelDownUtil;
import com.ningdatech.carapi.common.util.ExcelExportStyle;
import com.ningdatech.carapi.company.enumeration.CompanyTypeEnum;
import com.ningdatech.carapi.datascope.aop.LambdaDataScope;
import com.ningdatech.carapi.datascope.contants.LambdaDataScopeTypeEnum;
import com.ningdatech.carapi.scheduler.entity.VehicleOnlineStatusDay;
import com.ningdatech.carapi.scheduler.service.IVehicleOnlineStatusDayService;
import com.ningdatech.carapi.scheduler.service.IVehicleOnlineStatusHourService;
import com.ningdatech.carapi.sys.entity.Company;
import com.ningdatech.carapi.sys.entity.dto.CompanyDTO;
import com.ningdatech.carapi.sys.entity.dto.OperatorQueryDTO;
import com.ningdatech.carapi.sys.entity.dto.RegionDTO;
import com.ningdatech.carapi.sys.helper.CompaniesCacheHelper;
import com.ningdatech.carapi.sys.helper.OperatorsCacheHelper;
import com.ningdatech.carapi.sys.helper.RegionsCacheHelper;
import com.ningdatech.carapi.sys.helper.UserCacheHelper;
import com.ningdatech.carapi.sys.service.CompanyService;
import com.ningdatech.carapi.user.entity.NdUserInfo;
import com.ningdatech.carapi.user.model.vo.UserBasicInfoVO;
import com.ningdatech.carapi.user.security.auth.model.UserInfoDetails;
import com.ningdatech.carapi.user.util.LoginUserUtil;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import lombok.RequiredArgsConstructor;

/**
 * @Classname VehicleManage
 * @Description
 * @Date 2022/10/14 14:33
 * @Created by PoffyZhang
 */
@Component
@RequiredArgsConstructor
public class VehicleManage {

    private final IVehicleBaseInfoJoinService vehicleBaseInfoJoinService;
    private final IVehicleBaseInfoService vehicleBaseInfoService;

    private final UserCacheHelper userCacheHelper;
    private final OperatorsCacheHelper operatorsCacheHelper;
    private final UserInfoHelper userInfoHelper;
    private final RegionsCacheHelper regionsCacheHelper;
    private final CompanyService companyService;
    private final IVehicleOnlineStatusHourService vehicleOnlineStatusHourService;
    private final IVehicleOnlineStatusDayService vehicleOnlineStatusDayService;
    private final CompaniesCacheHelper companiesCacheHelper;

    /**
     * 车辆档案列表查询
     * @param vehicleArchivesPageQuery
     * @return
     */
    public PageVo<VehicleBaseVO> queryList(VehicleArchivesPageQuery vehicleArchivesPageQuery) {
        // 按照登录用户，如果是运营商账号登录，删选出该运营商关联的车辆信息
        UserInfoDetails userDetail = LoginUserUtil.loginUserDetail();
        Long roleId = userDetail.getRoleId();

        // 如果要展示没有所属企业的车
        List<NdVehicleBaseInfoJoin> baseJoins = Lists.newArrayList();
        if (Boolean.TRUE.equals(vehicleArchivesPageQuery.getShowWithoutCompany())) {
            LambdaQueryWrapper<NdVehicleBaseInfo> otherWrapper = Wrappers.lambdaQuery(NdVehicleBaseInfo.class);
            buildOtherWrapper(otherWrapper, vehicleArchivesPageQuery);
            List<NdVehicleBaseInfo> baseInfos = vehicleBaseInfoService.list(otherWrapper).stream()
                    .filter(v -> Objects.isNull(v.getCompanyId())).collect(Collectors.toList());
            // 如果根据所属企业名称查询，结果置为空（因为查出的车辆所属企业不在系统中）
            if (Objects.nonNull(vehicleArchivesPageQuery.getCompanyName())) {
                baseInfos = Lists.newArrayList();
            } else if (Objects.nonNull(vehicleArchivesPageQuery.getOperatorName())) {
                // 所属企业名称查询为空，运营商名称不为空
                baseInfos = baseInfos.stream().filter(b -> {
                    Long operatorId = b.getOperatorId();
                    if (Objects.nonNull(operatorId)) {
                        OperatorQueryDTO dto = operatorsCacheHelper.getById(operatorId);
                        String operatorName = dto.getName();
                        if (vehicleArchivesPageQuery.getOperatorName().equals(operatorName)) {
                            return true;
                        }
                    }
                    return false;
                }).collect(Collectors.toList());
            }

            baseJoins = CollUtils.convert(baseInfos, r -> {
                NdVehicleBaseInfoJoin join = new NdVehicleBaseInfoJoin();
                BeanUtils.copyProperties(r, join);
                Long operatorId = r.getOperatorId();
                if (Objects.nonNull(operatorId)) {
                    OperatorQueryDTO dto = operatorsCacheHelper.getById(operatorId);
                    join.setOperatorName(dto.getName());
                }
                return join;
            });
        }


        Integer pageSize = vehicleArchivesPageQuery.getPageSize();
        Integer pageNumber = vehicleArchivesPageQuery.getPageNumber();
        List<NdVehicleBaseInfoJoin> joins;
        if (UserRoleTypeEnum.OPERATOR_ROLE_ID.getId().equals(roleId)) {
            String companyName = userDetail.getCompanyName();
            // 暂时控制运营商名称和运营商所在企业名称相同
            OperatorQueryDTO operatorQueryDTO = operatorsCacheHelper.getByName(companyName);
            // 获取运营商id
            Long operatorId = operatorQueryDTO.getId();
            LambdaQueryWrapper<NdVehicleBaseInfoJoin> wrapper = Wrappers.lambdaQuery(NdVehicleBaseInfoJoin.class);
            buildQueryWrapper(wrapper,vehicleArchivesPageQuery);
            wrapper.eq(NdVehicleBaseInfoJoin::getOperatorId,operatorId);
            joins = vehicleBaseInfoJoinService.listCarJoin(wrapper);
        } else if (UserRoleTypeEnum.COMPANY_INFO_OFFICER_ROLE_ID.getId().equals(roleId)) {
            Long companyId = userDetail.getCompanyId();
            LambdaQueryWrapper<NdVehicleBaseInfoJoin> wrapper = Wrappers.lambdaQuery(NdVehicleBaseInfoJoin.class);
            buildQueryWrapper(wrapper,vehicleArchivesPageQuery);
            wrapper.and(w -> w.eq(NdVehicleBaseInfoJoin::getCompanyId,companyId).or().eq(NdVehicleBaseInfoJoin::getUseCompanyId,companyId));
            joins = vehicleBaseInfoJoinService.listCarJoinWithUseCompany(wrapper);
        } else {
            LambdaQueryWrapper<NdVehicleBaseInfoJoin> wrapper = Wrappers.lambdaQuery(NdVehicleBaseInfoJoin.class);
            VehicleManage context = (VehicleManage) AopContext.currentProxy();
            joins = context.searchCar(wrapper, vehicleArchivesPageQuery);
        }
        joins.addAll(baseJoins);
        List<NdVehicleBaseInfoJoin> records = joins.stream().skip((pageNumber - 1) * pageSize).limit(pageSize).collect(Collectors.toList());
        List<VehicleBaseVO> data = CollUtils.convert(records, v -> {
            VehicleBaseVO vo = BeanUtil.copyProperties(v, VehicleBaseVO.class);
            // 根据所属企业的区域Id展示所属区域
            Long companyId = vo.getCompanyId();
            if (Objects.nonNull(companyId)) {
                CompanyDTO companyDto = companiesCacheHelper.getById(companyId);
                Long regionId = companyDto.getRegionId();
                if (Objects.nonNull(regionId)) {
                    vo.setRegionId(regionId);
                    vo.setRegionName(regionsCacheHelper.getDisplayName(regionId));
                }
            }
            CodeUtil.searchCompanyNameAndRegionName(vo);
            vo.setVehicleStatus(v.getVehicleStatus());
            vo.setVehicleStatusName(CarStatusEnum.getDescByCode(v.getVehicleStatus()));
            vo.setVehicleTypeName(VehicleTypeEnum.getDescByCode(vo.getVehicleType()));
            return vo;
        });
        return PageVo.of(data, joins.size());
    }

    /**
     * 车辆新增列表查询
     * @param vehicleArchivesPageQuery
     * @return
     */
    public PageVo<VehicleBaseVO> queryNewAddList(VehicleArchivesPageQuery vehicleArchivesPageQuery) {
        // 按照登录用户，如果是运营商账号登录，删选出该运营商关联的车辆信息
        UserInfoDetails userDetail = LoginUserUtil.loginUserDetail();
        Long roleId = userDetail.getRoleId();
        if (UserRoleTypeEnum.OPERATOR_ROLE_ID.getId().equals(roleId)) {
            String companyName = userDetail.getCompanyName();
            // 暂时控制运营商名称和运营商所在企业名称相同
            OperatorQueryDTO operatorQueryDTO = operatorsCacheHelper.getByName(companyName);
            // 获取运营商id
            Long operatorId = operatorQueryDTO.getId();
            Page<NdVehicleBaseInfoJoin> page = vehicleArchivesPageQuery.page();
            LambdaQueryWrapper<NdVehicleBaseInfoJoin> wrapper = Wrappers.lambdaQuery(NdVehicleBaseInfoJoin.class);
            buildNewAddQueryWrapper(wrapper,vehicleArchivesPageQuery);
            wrapper.eq(NdVehicleBaseInfoJoin::getOperatorId,operatorId);
            vehicleBaseInfoJoinService.pageJoin(page,wrapper);
            List<VehicleBaseVO> data = CollUtils.convert(page.getRecords(), v -> {
                VehicleBaseVO vo = BeanUtil.copyProperties(v, VehicleBaseVO.class);
                // 根据所属企业的区域Id展示所属区域
                Long companyId = vo.getCompanyId();
                CompanyDTO companyDto = companiesCacheHelper.getById(companyId);
                if (Objects.nonNull(companyDto)) {
                    Long regionId = companyDto.getRegionId();
                    if (Objects.nonNull(regionId)) {
                        vo.setRegionId(regionId);
                        vo.setRegionName(regionsCacheHelper.getDisplayName(regionId));
                    }
                }
                CodeUtil.searchCompanyNameAndRegionName(vo);
                vo.setVehicleStatus(v.getVehicleStatus());
                vo.setVehicleStatusName(CarStatusEnum.getDescByCode(v.getVehicleStatus()));
                vo.setVehicleTypeName(VehicleTypeEnum.getDescByCode(vo.getVehicleType()));
                vo.setAuditStateName(AuditStateEnum.getDescByCode(vo.getAuditState()));
                return vo;
            });
            return PageVo.of(data, page.getTotal());
        }
        // 如果是企业信息员账号登录，则查询该企业为所属企业和使用企业的所有车辆信息
        else if (UserRoleTypeEnum.COMPANY_INFO_OFFICER_ROLE_ID.getId().equals(roleId)) {
            Long companyId = userDetail.getCompanyId();
            Page<NdVehicleBaseInfoJoin> page = vehicleArchivesPageQuery.page();
            LambdaQueryWrapper<NdVehicleBaseInfoJoin> wrapper = Wrappers.lambdaQuery(NdVehicleBaseInfoJoin.class);
            buildNewAddQueryWrapper(wrapper,vehicleArchivesPageQuery);
            wrapper.and(w -> w.eq(NdVehicleBaseInfoJoin::getCompanyId,companyId).or().eq(NdVehicleBaseInfoJoin::getUseCompanyId,companyId));
            vehicleBaseInfoJoinService.pageJoinWithUseCompany(page,wrapper);
            List<VehicleBaseVO> data = CollUtils.convert(page.getRecords(), v -> {
                VehicleBaseVO vo = BeanUtil.copyProperties(v, VehicleBaseVO.class);
                vo.setVehicleStatus(v.getVehicleStatus());
                vo.setVehicleStatusName(CarStatusEnum.getDescByCode(v.getVehicleStatus()));
                CodeUtil.searchCompanyNameAndRegionName(vo);
                vo.setVehicleTypeName(VehicleTypeEnum.getDescByCode(vo.getVehicleType()));
                vo.setAuditStateName(AuditStateEnum.getDescByCode(vo.getAuditState()));
                return vo;
            });
            return PageVo.of(data, page.getTotal());
        } else {
            Page<NdVehicleBaseInfoJoin> page = vehicleArchivesPageQuery.page();
            LambdaQueryWrapper<NdVehicleBaseInfoJoin> wrapper = Wrappers.lambdaQuery(NdVehicleBaseInfoJoin.class);
            VehicleManage context = (VehicleManage) AopContext.currentProxy();
            context.searchNewAddPage(page, wrapper, vehicleArchivesPageQuery);
            List<VehicleBaseVO> data = CollUtils.convert(page.getRecords(), v -> {
                VehicleBaseVO vo = BeanUtil.copyProperties(v, VehicleBaseVO.class);
                vo.setVehicleStatus(v.getVehicleStatus());
                vo.setVehicleStatusName(CarStatusEnum.getDescByCode(v.getVehicleStatus()));
                CodeUtil.searchCompanyNameAndRegionName(vo);
                vo.setVehicleTypeName(VehicleTypeEnum.getDescByCode(vo.getVehicleType()));
                vo.setAuditStateName(AuditStateEnum.getDescByCode(vo.getAuditState()));
                return vo;
            });
            return PageVo.of(data, page.getTotal());
        }
    }

    @BuildChildrenRegionWrapper(entityIndex = 2,wrapperIndex = 1)
    public void searchNewAddPage(Page<NdVehicleBaseInfoJoin> page, LambdaQueryWrapper<NdVehicleBaseInfoJoin> wrapper, VehicleArchivesPageQuery vehicleArchivesPageQuery) {
        buildNewAddQueryWrapper(wrapper,vehicleArchivesPageQuery);
        vehicleBaseInfoJoinService.pageJoin(page,wrapper);
    }

    @BuildChildrenRegionWrapper(entityIndex = 2,wrapperIndex = 1)
    public void searchPage(Page<NdVehicleBaseInfoJoin> page, LambdaQueryWrapper<NdVehicleBaseInfoJoin> wrapper, VehicleArchivesPageQuery vehicleArchivesPageQuery) {
        buildQueryWrapper(wrapper,vehicleArchivesPageQuery);
        vehicleBaseInfoJoinService.pageJoin(page,wrapper);
    }

    @BuildChildrenRegionWrapper
    public List<NdVehicleBaseInfoJoin> searchCar(LambdaQueryWrapper<NdVehicleBaseInfoJoin> wrapper, VehicleArchivesPageQuery vehicleArchivesPageQuery) {
        buildQueryWrapper(wrapper,vehicleArchivesPageQuery);
        return vehicleBaseInfoJoinService.listCarJoin(wrapper);
    }



    /**
     * 车辆审核列表
     * @param vehicleArchivesPageQuery
     * @return
     */
    public PageVo<VehicleBaseVO> queryArchivesList(VehicleArchivesPageQuery vehicleArchivesPageQuery) {
        Page<NdVehicleBaseInfoJoin> page = vehicleArchivesPageQuery.page();
        LambdaQueryWrapper<NdVehicleBaseInfoJoin> wrapper = Wrappers.lambdaQuery(NdVehicleBaseInfoJoin.class);
        VehicleManage context = (VehicleManage)AopContext.currentProxy();
        context.searchArchivesPage(page,wrapper,vehicleArchivesPageQuery);
        PageVo<VehicleBaseVO> pageVo = PageVo.empty();
        VUtils.isTrueOrFalse(0L == page.getTotal()).trueOrFalseHandler(
                () -> {},
                () -> {
                    pageVo.setRecords(CollUtils.convert(page.getRecords(), v -> {
                        VehicleBaseVO vo = BeanUtil.copyProperties(v, VehicleBaseVO.class);
                        CodeUtil.searchCompanyNameAndRegionName(vo);
                        vo.setVehicleTypeName(VehicleTypeEnum.getDescByCode(vo.getVehicleType()));
                        return vo;
                    }));
                    pageVo.setTotal(page.getTotal());
                }
        );

        return pageVo;
    }

    public PageVo<VehicleBaseVO> queryArchivesListOpen(VehicleArchivesPageQuery vehicleArchivesPageQuery) {
        Page<NdVehicleBaseInfo> page = vehicleArchivesPageQuery.page();
        LambdaQueryWrapper<NdVehicleBaseInfo> wrapper = Wrappers.lambdaQuery(NdVehicleBaseInfo.class);
        buildWrapper(wrapper,vehicleArchivesPageQuery);
        vehicleBaseInfoService.page(page,wrapper);
        PageVo<VehicleBaseVO> pageVo = PageVo.empty();
        VUtils.isTrueOrFalse(0L == page.getTotal()).trueOrFalseHandler(
                () -> {},
                () -> {
                    pageVo.setRecords(CollUtils.convert(page.getRecords(), v -> {
                        VehicleBaseVO vo = BeanUtil.copyProperties(v, VehicleBaseVO.class);
                        CodeUtil.searchCompanyNameAndRegionName(vo);
                        vo.setVehicleTypeName(VehicleTypeEnum.getDescByCode(vo.getVehicleType()));
                        return vo;
                    }));
                    pageVo.setTotal(page.getTotal());
                }
        );
        return pageVo;
    }

    @BuildChildrenRegionWrapper(entityIndex = 2,wrapperIndex = 1)
    public void searchArchivesPage(Page<NdVehicleBaseInfoJoin> page, LambdaQueryWrapper<NdVehicleBaseInfoJoin> wrapper,
                                   VehicleArchivesPageQuery vehicleArchivesPageQuery) {
        buildHasEquipmentQueryWrapper(wrapper,vehicleArchivesPageQuery);
        vehicleBaseInfoJoinService.pageJoinWithEquipment(page,wrapper);
    }

    @BuildChildrenRegionWrapper(entityIndex = 2,wrapperIndex = 1)
    public void searchArchivesPageOpen(Page<NdVehicleBaseInfoJoin> page, LambdaQueryWrapper<NdVehicleBaseInfoJoin> wrapper,
                                   VehicleArchivesPageQuery vehicleArchivesPageQuery) {
        buildHasEquipmentQueryWrapper(wrapper,vehicleArchivesPageQuery);
        vehicleBaseInfoJoinService.pageJoinWithEquipmentOpen(page,wrapper);
    }

    /**
     * 车辆待审核
     * @param vehicleAuditPageQuery
     * @return
     */
    public PageVo<VehicleBaseVO> queryToBeAudit(VehicleAuditPageQuery vehicleAuditPageQuery) {
        Page<NdVehicleBaseInfoJoin> page = vehicleAuditPageQuery.page();
        LambdaQueryWrapper<NdVehicleBaseInfoJoin> wrapper = Wrappers.lambdaQuery(NdVehicleBaseInfoJoin.class);
        wrapper.eq(NdVehicleBaseInfoJoin::getAuditState, AuditStateEnum.AUDIT.getCode());
        VehicleManage context = (VehicleManage)AopContext.currentProxy();
        context.searchTobeAuditPage(page,wrapper,vehicleAuditPageQuery);
        List<VehicleBaseVO> data = CollUtils.convert(page.getRecords(), v -> {
            VehicleBaseVO vo = BeanUtil.copyProperties(v, VehicleBaseVO.class);
            // 根据所属企业的区域Id展示所属区域
            Long companyId = vo.getCompanyId();
            if (Objects.nonNull(companyId)) {
                CompanyDTO companyDto = companiesCacheHelper.getById(companyId);
                if (Objects.nonNull(companyDto)) {
                    Long regionId = companyDto.getRegionId();
                    if (Objects.nonNull(regionId)) {
                        vo.setRegionId(regionId);
                        vo.setRegionName(regionsCacheHelper.getDisplayName(regionId));
                    }
                }
            }
            CodeUtil.searchCompanyNameAndRegionName(vo);
            vo.setVehicleTypeName(VehicleTypeEnum.getDescByCode(vo.getVehicleType()));
            vo.setVehicleStatus(v.getVehicleStatus());
            vo.setVehicleStatusName(CarStatusEnum.getDescByCode(v.getVehicleStatus()));
            // 判断当前登录用户是否可以审核该车辆
            if (!checkCanAudit(vo)){
                vo.setCanAudit(Boolean.FALSE);
            }
            return vo;
        });
        return PageVo.of(data, page.getTotal());
    }

    private boolean checkCanAudit(VehicleBaseVO vo) {
        // 根据当前登录用户角色判断：
        // 如果登录用户是区县散办管理员，且车辆所属区域有区县散办则可以审核；
        // 如果登录用户是市级散办管理员，且车辆所属区域没有区县散办则可以审核；
        UserBasicInfoVO userFullInfo = userInfoHelper.getUserFullInfo();
        Long roleId = userFullInfo.getRoleId();
        Long userRegionId = userFullInfo.getRegionId();
        Long regionId = vo.getRegionId();
        if (UserRoleTypeEnum.REGION_ADMIN_ROLE_ID.getId().equals(roleId)
                && regionId.equals(userRegionId)){
            return true;
        } else if (UserRoleTypeEnum.BULK_CEMENT_ADMIN_ROLE_ID.getId().equals(roleId)) {
            // 如果是市级散办
            // 查询车辆所属区域是否为该市下属区域且无区县散办
            List<Long> childRegions = regionsCacheHelper.listChild(userRegionId);
            if (CollUtil.isNotEmpty(childRegions) && childRegions.contains(regionId)){
                // 获取车辆所属区域的区县散办
                RegionDTO regionDto = regionsCacheHelper.getByRegionId(regionId);
                if (Objects.nonNull(regionDto)) {
                    String adminCompanyName = regionDto.getRegionName() + VehicleContant.ADMIN_COMPANY_NAME;
                    // 根据区县散办所属管理企业名称查询管理企业，如果不存在，说明没有相应的区县散办
                    Company company = companyService.getCompanyByCompanyNames(adminCompanyName);
                    if (Objects.isNull(company) || !company.getCompanyType().equals(CompanyTypeEnum.MANAGE_BU.getCode())){
                        // 没有下属区县散办，则可以审核
                        return true;
                    }else {
                        // 有下属区县散办，不可以审核
                        return false;
                    }
                }
            }
            // 该市没有下属子区域，可以审核
            return true;
        }
        return false;
    }

    @BuildChildrenRegionWrapper(entityIndex = 2,wrapperIndex = 1)
    public void searchTobeAuditPage(Page<NdVehicleBaseInfoJoin> page, LambdaQueryWrapper<NdVehicleBaseInfoJoin> wrapper,
                                    VehicleAuditPageQuery vehicleAuditPageQuery) {
        buildAuditQueryWrapper(wrapper,vehicleAuditPageQuery);
        vehicleBaseInfoJoinService.pageJoin(page,wrapper);
    }

    /**
     * 车辆已审核
     * @param vehicleAuditPageQuery
     * @return
     */
    public PageVo<VehicleBaseVO> queryAuditedList(VehicleAuditPageQuery vehicleAuditPageQuery) {
        Page<NdVehicleBaseInfoJoin> page = vehicleAuditPageQuery.page();
        LambdaQueryWrapper<NdVehicleBaseInfoJoin> wrapper = Wrappers.lambdaQuery(NdVehicleBaseInfoJoin.class);
        VehicleManage context = (VehicleManage)AopContext.currentProxy();
        context.searchAuditedPage(page,wrapper,vehicleAuditPageQuery);
        List<VehicleBaseVO> data = CollUtils.convert(page.getRecords(), v -> {
            VehicleBaseVO vo = BeanUtil.copyProperties(v, VehicleBaseVO.class);
            // 根据所属企业的区域Id展示所属区域
            Long companyId = vo.getCompanyId();
            if (Objects.nonNull(companyId)) {
                CompanyDTO companyDto = companiesCacheHelper.getById(companyId);
                if (Objects.nonNull(companyDto)) {
                    Long regionId = companyDto.getRegionId();
                    if (Objects.nonNull(regionId)) {
                        vo.setRegionId(regionId);
                        vo.setRegionName(regionsCacheHelper.getDisplayName(regionId));
                    }
                }
            }
            CodeUtil.searchCompanyNameAndRegionName(vo);
            vo.setVehicleTypeName(VehicleTypeEnum.getDescByCode(vo.getVehicleType()));
            vo.setVehicleStatus(v.getVehicleStatus());
            vo.setVehicleStatusName(CarStatusEnum.getDescByCode(v.getVehicleStatus()));
            return vo;
        });
        return PageVo.of(data, page.getTotal());
    }

    @BuildChildrenRegionWrapper(entityIndex = 2,wrapperIndex = 1)
    public void searchAuditedPage(Page<NdVehicleBaseInfoJoin> page, LambdaQueryWrapper<NdVehicleBaseInfoJoin> wrapper,
                                  VehicleAuditPageQuery vehicleAuditPageQuery) {
        buildAuditQueryWrapper(wrapper,vehicleAuditPageQuery);
        wrapper.and(wp -> wp.eq(NdVehicleBaseInfoJoin::getAuditState, AuditStateEnum.AUDIT_SUCCESS.getCode()).or()
                .eq(NdVehicleBaseInfoJoin::getAuditState, AuditStateEnum.AUDIT_FAIL.getCode()));
        vehicleBaseInfoJoinService.pageJoin(page,wrapper);
    }

    /**
     * 获取车辆详情
     * @param id
     * @return
     */
    public VehicleArchivesQueryDTO getDetails(Long id) {

        LambdaQueryWrapper<NdVehicleBaseInfo> wrapper = Wrappers.lambdaQuery(NdVehicleBaseInfo.class);
        VehicleManage context = (VehicleManage) AopContext.currentProxy();
        context.buildQuery(wrapper, id);
        NdVehicleBaseInfo ndVehicleBaseInfo = vehicleBaseInfoService.getOne(wrapper);
        if (Objects.isNull(ndVehicleBaseInfo)){
            return null;
        }

        VehicleArchivesQueryDTO query = BeanUtil.toBean(ndVehicleBaseInfo, VehicleArchivesQueryDTO.class);
        Long useCompanyId = ndVehicleBaseInfo.getUseCompanyId();
        if (Objects.nonNull(useCompanyId)){
            CompanyDTO companyDto = companiesCacheHelper.getById(useCompanyId);
            if (Objects.nonNull(companyDto)) {
                query.setUseCompanyName(companyDto.getName());
            }
        }
        CodeUtil.searchCompanyNameAndRegionName(query);
        NdUserInfo user = userCacheHelper.getById(ndVehicleBaseInfo.getAuditBy());
        query.setAuditBy(Objects.nonNull(user) ? user.getUsername() : (Objects.nonNull(ndVehicleBaseInfo.getAuditBy()) ? ndVehicleBaseInfo.getAuditBy() +StringUtils.EMPTY : VehicleContant.DEFAULT_NULL_AUDIT));
        query.setVehicleStatusName(CarStatusEnum.getDescByCode(ndVehicleBaseInfo.getVehicleStatus()));
        Long operatorId = query.getOperatorId();
        if (Objects.nonNull(operatorId)) {
            OperatorQueryDTO operatorQueryDto = operatorsCacheHelper.getById(operatorId);
            if (Objects.nonNull(operatorQueryDto)) {
                query.setOperatorName(operatorQueryDto.getName());
            }
        }
        return query;
    }

    @LambdaDataScope(type = LambdaDataScopeTypeEnum.ALL)
    public void buildQuery(LambdaQueryWrapper<NdVehicleBaseInfo> wrapper, Long id) {
        wrapper.eq(NdVehicleBaseInfo::getId,id);
    }

    /**
     * 查询车牌号
     * @param companyIds
     * @return
     */
    public List<VehicleCarPlateVO> listByCompanyIds(List<String> companyIds) {
        List<NdVehicleBaseInfoJoin> ndVehicleBaseInfos = vehicleBaseInfoJoinService.listJoin(
                Wrappers.lambdaQuery(NdVehicleBaseInfoJoin.class).in(NdVehicleBaseInfoJoin::getCompanyId,companyIds));
        List<VehicleCarPlateVO> query = CollUtils.convert(ndVehicleBaseInfos,w -> BeanUtil.copyProperties(w, VehicleCarPlateVO.class));
        return query;
    }

    /**
     * 处理
     * @param wrapper
     * @param vehicleArchivesPageQuery
     */
    private void buildQueryWrapper(LambdaQueryWrapper<NdVehicleBaseInfoJoin> wrapper, VehicleArchivesPageQuery vehicleArchivesPageQuery) {

        wrapper.eq(NdVehicleBaseInfoJoin::getDeleted, DeletedEnum.NO_DELETED.getCode())
                .eq(Objects.nonNull(vehicleArchivesPageQuery.getCompanyId()),NdVehicleBaseInfoJoin::getCompanyId,vehicleArchivesPageQuery.getCompanyId())
                .like(StringUtils.isNotBlank(vehicleArchivesPageQuery.getCarPlate()), NdVehicleBaseInfoJoin::getCarPlate, vehicleArchivesPageQuery.getCarPlate())
                .like(StringUtils.isNotBlank(vehicleArchivesPageQuery.getCompanyName()), NdVehicleBaseInfoJoin::getCompanyName, vehicleArchivesPageQuery.getCompanyName())
                .like(StringUtils.isNotBlank(vehicleArchivesPageQuery.getUseCompanyName()),NdVehicleBaseInfoJoin::getUseCompanyName,vehicleArchivesPageQuery.getUseCompanyName())
                .eq(Objects.nonNull(vehicleArchivesPageQuery.getVehicleType()), NdVehicleBaseInfoJoin::getVehicleType, vehicleArchivesPageQuery.getVehicleType())
                .eq(Objects.nonNull(vehicleArchivesPageQuery.getVehicleStatus()),NdVehicleBaseInfoJoin::getVehicleStatus,vehicleArchivesPageQuery.getVehicleStatus())
                .like(StringUtils.isNotBlank(vehicleArchivesPageQuery.getOperatorName()), NdVehicleBaseInfoJoin::getOperatorName, vehicleArchivesPageQuery.getOperatorName())
                //.eq(Objects.nonNull(vehicleArchivesPageQuery.getRegionId()),NdVehicleBaseInfoJoin::getRegionId,vehicleArchivesPageQuery.getRegionId())
                .eq(NdVehicleBaseInfoJoin::getAuditState,AuditStateEnum.AUDIT_SUCCESS.getCode())
                .orderBy(Boolean.TRUE,Boolean.FALSE,NdVehicleBaseInfoJoin::getUpdateOn);
    }

    /**
     * 处理
     * @param wrapper
     * @param vehicleArchivesPageQuery
     */
    private void buildOtherWrapper(LambdaQueryWrapper<NdVehicleBaseInfo> wrapper, VehicleArchivesPageQuery vehicleArchivesPageQuery) {

        wrapper.eq(NdVehicleBaseInfo::getDeleted, DeletedEnum.NO_DELETED.getCode())
                .eq(Objects.nonNull(vehicleArchivesPageQuery.getCompanyId()),NdVehicleBaseInfo::getCompanyId,vehicleArchivesPageQuery.getCompanyId())
                .like(StringUtils.isNotBlank(vehicleArchivesPageQuery.getCarPlate()), NdVehicleBaseInfo::getCarPlate, vehicleArchivesPageQuery.getCarPlate())
                .like(StringUtils.isNotBlank(vehicleArchivesPageQuery.getUseCompanyName()),NdVehicleBaseInfo::getUseCompanyName,vehicleArchivesPageQuery.getUseCompanyName())
                .eq(Objects.nonNull(vehicleArchivesPageQuery.getVehicleType()), NdVehicleBaseInfo::getVehicleType, vehicleArchivesPageQuery.getVehicleType())
                .eq(Objects.nonNull(vehicleArchivesPageQuery.getVehicleStatus()),NdVehicleBaseInfo::getVehicleStatus,vehicleArchivesPageQuery.getVehicleStatus())
                //.eq(Objects.nonNull(vehicleArchivesPageQuery.getRegionId()),NdVehicleBaseInfo::getRegionId,vehicleArchivesPageQuery.getRegionId())
                .eq(NdVehicleBaseInfo::getAuditState,AuditStateEnum.AUDIT_SUCCESS.getCode())
                .orderBy(Boolean.TRUE,Boolean.FALSE,NdVehicleBaseInfo::getUpdateOn);
    }

    /**
     * 处理
     * @param wrapper
     * @param vehicleArchivesPageQuery
     */
    private void buildNewAddQueryWrapper(LambdaQueryWrapper<NdVehicleBaseInfoJoin> wrapper, VehicleArchivesPageQuery vehicleArchivesPageQuery) {
        //if(Objects.nonNull(vehicleArchivesPageQuery.getAuditType())){
        //    wrapper.eq(AuditStateEnum.AUDIT.getCode().equals(vehicleArchivesPageQuery.getAuditType()), NdVehicleBaseInfoJoin::getAuditState, AuditStateEnum.AUDIT.getCode())
        //            .and(AuditStateEnum.AUDIT_SUCCESS.getCode().equals(vehicleArchivesPageQuery.getAuditType()) ||
        //                            AuditStateEnum.AUDIT_FAIL.getCode().equals(vehicleArchivesPageQuery.getAuditType()),
        //                    wp -> wp.eq(NdVehicleBaseInfoJoin::getAuditState, AuditStateEnum.AUDIT_SUCCESS.getCode())
        //                            .or().eq(NdVehicleBaseInfoJoin::getAuditState, AuditStateEnum.AUDIT_FAIL.getCode()));
        //}
        wrapper.eq(NdVehicleBaseInfoJoin::getDeleted, DeletedEnum.NO_DELETED.getCode())
                .like(StringUtils.isNotBlank(vehicleArchivesPageQuery.getCarPlate()), NdVehicleBaseInfoJoin::getCarPlate, vehicleArchivesPageQuery.getCarPlate())
                .eq(Objects.nonNull(vehicleArchivesPageQuery.getVehicleType()), NdVehicleBaseInfoJoin::getVehicleType, vehicleArchivesPageQuery.getVehicleType())
                .eq(Objects.nonNull(vehicleArchivesPageQuery.getRegionId()),NdVehicleBaseInfoJoin::getRegionId,vehicleArchivesPageQuery.getRegionId())
                .eq(Objects.nonNull(vehicleArchivesPageQuery.getAuditType()), NdVehicleBaseInfoJoin::getAuditState,vehicleArchivesPageQuery.getAuditType())
                .orderBy(Boolean.TRUE,Boolean.FALSE,NdVehicleBaseInfoJoin::getUpdateOn);
    }

    /**
     * 处理
     * @param wrapper
     * @param vehicleArchivesPageQuery
     */
    private void buildWrapper(LambdaQueryWrapper<NdVehicleBaseInfo> wrapper, VehicleArchivesPageQuery vehicleArchivesPageQuery) {
        if(Objects.nonNull(vehicleArchivesPageQuery.getAuditType())){
            wrapper.eq(AuditStateEnum.AUDIT.getCode().equals(vehicleArchivesPageQuery.getAuditType()), NdVehicleBaseInfo::getAuditState, AuditStateEnum.AUDIT.getCode())
                    .and(AuditStateEnum.AUDIT_SUCCESS.getCode().equals(vehicleArchivesPageQuery.getAuditType()) ||
                                    AuditStateEnum.AUDIT_FAIL.getCode().equals(vehicleArchivesPageQuery.getAuditType()),
                            wp -> wp.eq(NdVehicleBaseInfo::getAuditState, AuditStateEnum.AUDIT_SUCCESS.getCode())
                                    .or().eq(NdVehicleBaseInfo::getAuditState, AuditStateEnum.AUDIT_FAIL.getCode()));
        }
        wrapper.eq(NdVehicleBaseInfo::getDeleted, DeletedEnum.NO_DELETED.getCode())
                .eq(Objects.nonNull(vehicleArchivesPageQuery.getCompanyId()),NdVehicleBaseInfo::getCompanyId,vehicleArchivesPageQuery.getCompanyId())
                .like(StringUtils.isNotBlank(vehicleArchivesPageQuery.getCarPlate()), NdVehicleBaseInfo::getCarPlate, vehicleArchivesPageQuery.getCarPlate())
                .like(StringUtils.isNotBlank(vehicleArchivesPageQuery.getUseCompanyName()),NdVehicleBaseInfo::getUseCompanyName,vehicleArchivesPageQuery.getUseCompanyName())
                .eq(Objects.nonNull(vehicleArchivesPageQuery.getVehicleType()), NdVehicleBaseInfo::getVehicleType, vehicleArchivesPageQuery.getVehicleType())
                .orderBy(Boolean.TRUE,Boolean.FALSE,NdVehicleBaseInfo::getUpdateOn);
    }

    private void buildHasEquipmentQueryWrapper(LambdaQueryWrapper<NdVehicleBaseInfoJoin> wrapper,
                                               VehicleArchivesPageQuery vehicleArchivesPageQuery) {
        wrapper.eq(NdVehicleBaseInfoJoin::getDeleted, DeletedEnum.NO_DELETED.getCode())
                .like(StringUtils.isNotBlank(vehicleArchivesPageQuery.getCarPlate()), NdVehicleBaseInfoJoin::getCarPlate, vehicleArchivesPageQuery.getCarPlate())
                .like(StringUtils.isNotBlank(vehicleArchivesPageQuery.getCompanyName()), NdVehicleBaseInfoJoin::getCompanyName, vehicleArchivesPageQuery.getCompanyName())
                .eq(Objects.nonNull(vehicleArchivesPageQuery.getVehicleType()), NdVehicleBaseInfoJoin::getVehicleType, vehicleArchivesPageQuery.getVehicleType())
                //要审核成功 并且审核通过才能进档案
                .eq(NdVehicleBaseInfoJoin::getAuditState, AuditStateEnum.AUDIT_SUCCESS.getCode())
                .eq(Objects.nonNull(vehicleArchivesPageQuery.getCompanyId()),NdVehicleBaseInfoJoin::getCompanyId, vehicleArchivesPageQuery.getCompanyId())
                .like(StringUtils.isNotBlank(vehicleArchivesPageQuery.getOperatorName()), NdVehicleBaseInfoJoin::getOperatorName, vehicleArchivesPageQuery.getOperatorName())
                .orderBy(Boolean.TRUE,Boolean.FALSE,NdVehicleBaseInfoJoin::getUpdateOn);
    }

    /**
     * 处理
     * @param wrapper
     * @param vehicleAuditPageQuery
     */
    private void buildAuditQueryWrapper(LambdaQueryWrapper<NdVehicleBaseInfoJoin> wrapper, VehicleAuditPageQuery vehicleAuditPageQuery) {
        wrapper.eq(NdVehicleBaseInfoJoin::getDeleted, DeletedEnum.NO_DELETED.getCode())
                .like(StringUtils.isNotBlank(vehicleAuditPageQuery.getCarPlate()), NdVehicleBaseInfoJoin::getCarPlate, vehicleAuditPageQuery.getCarPlate())
                .like(StringUtils.isNotBlank(vehicleAuditPageQuery.getCompanyName()), NdVehicleBaseInfoJoin::getCompanyName, vehicleAuditPageQuery.getCompanyName())
                .eq(Objects.nonNull(vehicleAuditPageQuery.getVehicleType()), NdVehicleBaseInfoJoin::getVehicleType, vehicleAuditPageQuery.getVehicleType())
                .eq(Objects.nonNull(vehicleAuditPageQuery.getAuditType()),NdVehicleBaseInfoJoin::getAuditState,vehicleAuditPageQuery.getAuditType())
                .orderBy(Boolean.TRUE,Boolean.FALSE,NdVehicleBaseInfoJoin::getUpdateOn);
    }

    public void exportNewAddBase(HttpServletResponse response, VehicleArchivesPageQuery archivesPageQuery) {
        archivesPageQuery.page(CommonConstant.EXPORT_PAGE_NUMBER, CommonConstant.EXPORT_PAGE_SIZE);
        PageVo<VehicleBaseVO> page = queryNewAddList(archivesPageQuery);
        List<VehicleBaseExportDTO> collect = page.getRecords().stream().map(w -> BeanUtil.copyProperties(w, VehicleBaseExportDTO.class)).collect(Collectors.toList());
        String fileName = "车辆信息";
        ExcelDownUtil.setFileName(fileName, response);
        // 数据导出处理函数
        try {
            EasyExcel.write(response.getOutputStream(), VehicleBaseExportDTO.class)
                    .autoCloseStream(false)
                    .registerWriteHandler(ExcelExportStyle.formalStyle())
                    .sheet(fileName)
                    .doWrite(collect);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void exportArchives(HttpServletResponse response, VehicleArchivesPageQuery archivesPageQuery) {
        archivesPageQuery.page(CommonConstant.EXPORT_PAGE_NUMBER, CommonConstant.EXPORT_PAGE_SIZE);
        PageVo<VehicleBaseVO> page = queryList(archivesPageQuery);
        List<VehicleBaseVO> exportData = page.getRecords().stream()
                .map(w -> BeanUtil.copyProperties(w, VehicleBaseVO.class))
                .collect(Collectors.toList());
        String fileName = "车辆档案信息";
        ExcelDownUtil.setFileName(fileName, response);
        // 数据导出处理函数
        try {
            EasyExcel.write(response.getOutputStream(), VehicleBaseExportDTO.class)
                    .autoCloseStream(false)
                    .registerWriteHandler(ExcelExportStyle.formalStyle())
                    .sheet(fileName)
                    .doWrite(exportData);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void export(HttpServletResponse response, VehicleArchivesPageQuery archivesPageQuery) {
        archivesPageQuery.page(CommonConstant.EXPORT_PAGE_NUMBER, CommonConstant.EXPORT_PAGE_SIZE);
        PageVo<VehicleBaseVO> page = queryArchivesList(archivesPageQuery);
        List<VehicleBaseVO> collect = page.getRecords().stream().map(w -> BeanUtil.copyProperties(w, VehicleBaseVO.class)).collect(Collectors.toList());
        String fileName = "车辆档案信息";
        ExcelDownUtil.setFileName(fileName, response);
        // 数据导出处理函数
        try {
            EasyExcel.write(response.getOutputStream(), VehicleBaseExportDTO.class)
                    .autoCloseStream(false)
                    .registerWriteHandler(ExcelExportStyle.formalStyle())
                    .sheet(fileName)
                    .doWrite(collect);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void exportAudit(HttpServletResponse response, VehicleAuditPageQuery auditPageQuery) {
        auditPageQuery.page(CommonConstant.EXPORT_PAGE_NUMBER, CommonConstant.EXPORT_PAGE_SIZE);
        PageVo<VehicleBaseVO> toBePage = queryToBeAudit(auditPageQuery);
        PageVo<VehicleBaseVO> auditPage = queryAuditedList(auditPageQuery);
        List<VehicleBaseVO> toBeList = toBePage.getRecords().stream().map(w -> BeanUtil.copyProperties(w, VehicleBaseVO.class)).collect(Collectors.toList());
        List<VehicleBaseVO> auditList = auditPage.getRecords().stream().map(w -> BeanUtil.copyProperties(w, VehicleBaseVO.class)).collect(Collectors.toList());
        String fileName = "车辆审核列表";
        ExcelDownUtil.setFileName(fileName, response);
        // 数据导出处理函数
        String sheetNameToBe = "车辆待审核列表";
        String sheetNameAudited = "车辆已审核列表";
        try {
            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
            //埋点基础信息 sheet
            WriteSheet writeSheet = EasyExcel.writerSheet(0, sheetNameToBe)
                    .head(VehicleBaseExportDTO.class).build();
            excelWriter.write(toBeList, writeSheet);
            //埋点数据转换信息 sheet
            writeSheet = EasyExcel.writerSheet(1, sheetNameAudited)
                    .head(VehicleBaseExportDTO.class).build();
            excelWriter.write(auditList, writeSheet);
            //埋点触发规则信息 sheet
            excelWriter.finish();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 根据车牌号和公司ID 获取车辆 信息 是唯一
     * @param carPlate
     * @param companyId
     * @return
     */
    public NdVehicleBaseInfo queryByCarPlateAndCompanyId(String carPlate, Long companyId) {
        return vehicleBaseInfoService.getOne(Wrappers.lambdaQuery(NdVehicleBaseInfo.class)
                .eq(NdVehicleBaseInfo::getCarPlate, carPlate)
                .eq(NdVehicleBaseInfo::getCompanyId, companyId));
    }

    public NdVehicleBaseInfo update(VehicleUpdateDTO data, Long userId) {
        return vehicleBaseInfoService.update(data, userId);
    }

    public NdVehicleBaseInfo save(VehicleSaveDTO data, Long userId) {
        return vehicleBaseInfoService.save(data, userId);
    }

    public Boolean removeByIdWithCache(List<Long> ids) {
        return vehicleBaseInfoService.removeByIdWithCache(ids);
    }

    public NdVehicleBaseInfo modifyAndUpdate(VehicleUpdateDTO data, Long userId) {
        return vehicleBaseInfoService.modifyAndUpdate(data, userId);
    }

    public void updateOnlineTime() {
        // 获取所有车辆信息
        Map<String, NdVehicleBaseInfo> timeMap = vehicleBaseInfoService.list().stream()
                .collect(Collectors.toMap(NdVehicleBaseInfo::getCarPlate, v -> v));

        // 查出天表所有 累计在线的车辆
        VehicleOnlineStatusDay statusday = new VehicleOnlineStatusDay();
        statusday.setYear(String.valueOf(LocalDateTime.now().getYear()));
        statusday.setMonth(String.valueOf(LocalDateTime.now().getMonthValue()));
        statusday.setDay(String.valueOf(LocalDateTime.now().getDayOfMonth()));
        List<VehicleOnlineStatusDay> onlineDays = vehicleOnlineStatusDayService.listByReqInMonthTable(statusday);
        Map<String, VehicleOnlineStatusDay> onlineDayMap = onlineDays.stream().collect(Collectors.toMap(v -> v.getCarPlate() + v.getYear() +
                v.getMonth() + v.getDay(), v -> v));

        // 将天表在线数据按车牌号分组，获取每个车牌号最新的一条在线数据
        Map<String, VehicleOnlineStatusDay> onlineStatusDayMap = onlineDays.stream().collect(Collectors.groupingBy(VehicleOnlineStatusDay::getCarPlate,
                Collectors.collectingAndThen(Collectors.maxBy(Comparator.comparing(VehicleOnlineStatusDay::getOnlineTime)), Optional::get)));

        // 遍历所有车牌号,如果天表中没有在线数据，需要到对应的GPS表中
        for (String carPlate : timeMap.keySet()) {
            VehicleOnlineStatusDay vehicleOnlineStatusDay = onlineStatusDayMap.get(carPlate);
            NdVehicleBaseInfo ndVehicleBaseInfo = timeMap.get(carPlate);
            if (Objects.isNull(vehicleOnlineStatusDay)) {
                ndVehicleBaseInfo.setLastOnlineTime(vehicleOnlineStatusDay.getOnlineTime());
            }
        }
    }

    public String cancelRelevance(Long id) {
        NdVehicleBaseInfo baseInfo = vehicleBaseInfoService.getById(id);
        if (Objects.isNull(baseInfo)){
            throw new BizException("车辆信息不存在!");
        }
        LambdaUpdateWrapper<NdVehicleBaseInfo> updateWrapper = Wrappers.lambdaUpdate(NdVehicleBaseInfo.class);
        updateWrapper.set(NdVehicleBaseInfo::getCompanyId, null)
                .set(NdVehicleBaseInfo::getUseCompanyId, null)
                .set(NdVehicleBaseInfo::getUseCompanyName, null)
                .set(NdVehicleBaseInfo::getRegionId, null)
                .set(NdVehicleBaseInfo::getRegionName, null)
                .eq(NdVehicleBaseInfo::getId, baseInfo.getId());
        boolean update = vehicleBaseInfoService.update(updateWrapper);
        if (update){
            return "取消关联成功!";
        }
        return "取消关联失败!";
    }

    /**
     * 批量查询 车辆信息 用车牌号
     * @param
     * @return
     */
    public List<VehicleBaseVO> listByCarplate(ReqDataPO po) {
        List<String> carPlates = po.getCarPlates();
        if(CollUtil.isEmpty(carPlates)){
            return Collections.emptyList();
        }
        List<NdVehicleBaseInfoJoin> ndVehicleBaseInfos = vehicleBaseInfoJoinService.listJoin(
                Wrappers.lambdaQuery(NdVehicleBaseInfoJoin.class).in(NdVehicleBaseInfoJoin::getCarPlate,carPlates));
        List<VehicleBaseVO> query = CollUtils.convert(ndVehicleBaseInfos,w -> BeanUtil.copyProperties(w, VehicleBaseVO.class));
        return query;
    }
}

