package com.prolog.rdc.tms.service.fleetManagement.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.prolog.cs.platform.power.model.Organization;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.exception.BizException;
import com.prolog.framework.core.exception.ParameterException;
import com.prolog.rdc.tms.config.enums.BelongToEnum;
import com.prolog.rdc.tms.config.enums.DepartmentBaseLinkBaseTypeEnum;
import com.prolog.rdc.tms.constant.BussinessConstant;
import com.prolog.rdc.tms.dao.mapper.TmsBaseCarriersMapper;
import com.prolog.rdc.tms.dao.mapper.TmsBaseDriverMapper;
import com.prolog.rdc.tms.dao.mapper.TmsDepartmentBaseLinkMapper;
import com.prolog.rdc.tms.dao.mapper.TmsVehicleDeviceLinkMapper;
import com.prolog.rdc.tms.model.dto.basicConfigure.StandardTemplateDetailsListDTO;
import com.prolog.rdc.tms.model.dto.fleetManagement.VehicleDeviceLinkViewDTO;
import com.prolog.rdc.tms.model.entity.line.TmsBaseCarriersModel;
import com.prolog.rdc.tms.model.entity.line.TmsBaseDriverModel;
import com.prolog.rdc.tms.model.entity.line.TmsDepartmentBaseLinkModel;
import com.prolog.rdc.tms.model.entity.line.TmsVehicleDeviceLinkModel;
import com.prolog.rdc.tms.model.vo.basicConfigure.ImportLogAddVO;
import com.prolog.rdc.tms.model.vo.fleetManagement.VehiclePaperPagingQueryVO;
import com.prolog.rdc.tms.model.vo.xlsimport.DeviceImportVO;
import com.prolog.rdc.tms.rmi.feign.UserFeign;
import com.prolog.rdc.tms.service.DepartmentBaseLinkService;
import com.prolog.rdc.tms.service.basicConfigure.ImportLogService;
import com.prolog.rdc.tms.service.basicConfigure.SysImportTemplethService;
import com.prolog.rdc.tms.util.FileUtils;
import com.prolog.rdc.tms.util.ImportUtils;
import com.prolog.wms.base.util.ExcelUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.prolog.common.util.DateUtils;
import com.prolog.common.util.ToolKits;
import com.prolog.framework.core.pojo.Page;
import com.prolog.framework.core.restriction.Criteria;
import com.prolog.framework.core.restriction.Restriction;
import com.prolog.framework.core.restriction.Restrictions;
import com.prolog.framework.dao.util.PageUtils;
import com.prolog.product.core.framework.entity.UserEntity;
import com.prolog.product.core.framework.util.PlgFxUsrUtils;
import com.prolog.rdc.tms.constant.DataDictionaryConstant;
import com.prolog.rdc.tms.constant.SeriaNnumberConstant;
import com.prolog.rdc.tms.constant.StatusConstant;
import com.prolog.rdc.tms.dao.mapper.TmsBaseDeviceMapper;
import com.prolog.rdc.tms.dao.mapper.TmsBaseVehicleMapper;
import com.prolog.rdc.tms.model.dto.fleetManagement.DeviceByOneDTO;
import com.prolog.rdc.tms.model.dto.fleetManagement.DeviceDTO;
import com.prolog.rdc.tms.model.dto.fleetManagement.DeviceViewDTO;
import com.prolog.rdc.tms.model.entity.line.TmsBaseDeviceModel;
import com.prolog.rdc.tms.model.vo.fleetManagement.DeviceAddVO;
import com.prolog.rdc.tms.model.vo.fleetManagement.DeviceDeleteVO;
import com.prolog.rdc.tms.model.vo.fleetManagement.DevicePopVO;
import com.prolog.rdc.tms.model.vo.fleetManagement.DeviceUpdateVO;
import com.prolog.rdc.tms.model.vo.fleetManagement.DeviceVO;
import com.prolog.rdc.tms.model.vo.fleetManagement.DeviceViewVO;
import com.prolog.rdc.tms.model.vo.fleetManagement.DeviceWhetherEnableVO;
import com.prolog.rdc.tms.service.SysCodeengineService;
import com.prolog.rdc.tms.service.SysRefdatadService;
import com.prolog.rdc.tms.service.fleetManagement.DeviceService;
import com.prolog.rdc.tms.util.PublicMethods;

import cn.hutool.core.date.DateUtil;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

/**
 * 
 *
 * 车队管理-设备资料实现层
 *
 * @className :DeviceServiceImpl
 * @author :fanzw
 * @creationTime :2022/04/18
 * @description :
 *
 * @modifier :fanzw
 * @modifyTime :2022/04/18
 * @reviseRemarks:
 *
 * @version :1.0.0
 *
 */
@Service
@Slf4j
public class DeviceServiceImpl implements DeviceService {

	@Autowired
	private TmsBaseDeviceMapper tmsBaseDeviceMapper;

	@Autowired
	private TmsBaseVehicleMapper tmsBaseVehicleMapper;

	@Autowired
	private SysRefdatadService sysRefdatadService;

	@Autowired
	private SysCodeengineService sysCodeengineService;

	@Autowired
	private TmsDepartmentBaseLinkMapper tmsDepartmentBaseLinkMapper;

	@Autowired
	private TmsBaseCarriersMapper tmsBaseCarriersMapper;

	@Autowired
	private SysImportTemplethService sysImportTemplethService;

	@Autowired
	private DepartmentBaseLinkService departmentBaseLinkService;

	@Autowired
	private UserFeign userFeign;

	@Autowired
	private ImportLogService importLogService;

	@Autowired
	private DeviceService deviceService;

	@Autowired
	private TmsBaseDriverMapper tmsBaseDriverMapper;

	@Autowired
	private TmsVehicleDeviceLinkMapper tmsVehicleDeviceLinkMapper;

	/**
	 * 设备资料分页查询
	 * 
	 * @param vo
	 * @return
	 */
	@SuppressWarnings("resource")
	@Override
	public Page<DeviceDTO> query(DeviceVO vo) {
		ToolKits.isParamNull(vo, "参数不能为空！");
		ToolKits.isParamNull(vo.getPageNum(), "当前页码不能为空");
		ToolKits.isParamNull(vo.getPageSize(), "每页条数不能为空");
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");

		vo.setEnterpriseId(user.getEnterpriseId());
		// 自有账号
		if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
			vo.setDepartmentIdList(user.getDepts());
		}
		// 承运商账号
		else if (user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
			vo.setAffiliationId(Long.valueOf(user.getLoginUserCompanyInfo().getId()));
		}
		// 司机账号
		else if (BussinessConstant.USER_TYPE_SJ.equals(user.getUserType())){
			TmsBaseDriverModel driverModel = tmsBaseDriverMapper.findById(user.getUserid(), TmsBaseDriverModel.class);
			if (ObjectUtil.isNull(driverModel)) {
				throw new BizException("司机不存在！");
			}
			if (DataDictionaryConstant.DRIVER_TYPE_OWN.equals(driverModel.getType())) {
				vo.setDepartmentIdList(user.getDepts());
			} else {
				vo.setAffiliationId(driverModel.getAffiliationId());
			}
		}
		PageUtils.startPage(vo.getPageNum(), vo.getPageSize());
		List<DeviceDTO> dtos = tmsBaseDeviceMapper.findByCondition(vo);
		if (CollectionUtil.isNotEmpty(dtos)) {
			List<Long> baseId = dtos.stream().map(DeviceDTO::getId).collect(Collectors.toList());
			Criteria criteria = Criteria.forClass(TmsDepartmentBaseLinkModel.class);
			Restriction r1 = Restrictions.in("baseId", baseId.toArray());
			Restriction r2 = Restrictions.eq("baseType", DepartmentBaseLinkBaseTypeEnum.DEVICE.getCode());
			criteria.setRestriction(Restrictions.and(r1, r2));
			List<TmsDepartmentBaseLinkModel> tmsDepartmentBaseLinkModelList = tmsDepartmentBaseLinkMapper.findByCriteria(criteria);
			Map<String, List<TmsDepartmentBaseLinkModel>> baseMap =
					tmsDepartmentBaseLinkModelList.stream().collect(Collectors.groupingBy(TmsDepartmentBaseLinkModel::getBaseId));
			// 设备类型
			List<Map<String, Object>> restMessage1 = sysRefdatadService.getDropDownById(DataDictionaryConstant.DEVICE_TYPE, null, null, null);
			// 设备生产厂商
			List<Map<String, Object>> restMessage2 = sysRefdatadService.getDropDownById(DataDictionaryConstant.DEVICE_COMPANY, null, null, null);
			// 设备状态
			List<Map<String, Object>> restMessage3 = sysRefdatadService.getDropDownById(DataDictionaryConstant.MAINDATA_STATUS, null, null, null);
			// 归属
			List<Map<String, Object>> restMessage4 = sysRefdatadService.getDropDownById(BelongToEnum.BELONG_TO_TYPE, null, null, null);
			dtos.forEach(dto -> {
				dto.setCompanyName(PublicMethods.change(restMessage2, String.valueOf(dto.getCompany())));
				dto.setTypeName(PublicMethods.change(restMessage1, String.valueOf(dto.getType())));
				dto.setStatusName(PublicMethods.change(restMessage3, String.valueOf(dto.getStatus())));
				dto.setBelongToName(PublicMethods.change(restMessage4, String.valueOf(dto.getBelongTo())));
				List<TmsDepartmentBaseLinkModel> linkList = baseMap.get(dto.getId().toString());
				if (CollectionUtil.isNotEmpty(linkList)) {
					dto.setDepartmentId(linkList.stream().map(TmsDepartmentBaseLinkModel::getDepartmentId).collect(Collectors.joining(",")));
					dto.setDepartmentCode(linkList.stream().map(TmsDepartmentBaseLinkModel::getDepartmentCode).collect(Collectors.joining(",")));
					dto.setDepartmentName(linkList.stream().map(TmsDepartmentBaseLinkModel::getDepartmentName).collect(Collectors.joining(",")));
				}
			});
		}
		Page<DeviceDTO> page = PageUtils.getPage(dtos);
		return page;
	}

	/**
	 * 设备资料查询
	 *
	 * @param vo
	 * @return
	 */
	public Page<DeviceDTO> deviceQuery(DeviceVO vo) {
		ToolKits.isParamNull(vo, "参数不能为空！");
		ToolKits.isParamNull(vo.getPageNum(), "当前页码不能为空");
		ToolKits.isParamNull(vo.getPageSize(), "每页条数不能为空");
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");

		vo.setEnterpriseId(user.getEnterpriseId());
		// 自有账号
		if (user.getUserType().equals(BussinessConstant.USER_TYPE_ZY)) {
			vo.setDepartmentIdList(user.getDepts());
		}
		// 承运商账号
		else if (user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
			vo.setAffiliationId(Long.valueOf(user.getLoginUserCompanyInfo().getId()));
		}
		// 司机账号
		else if (BussinessConstant.USER_TYPE_SJ.equals(user.getUserType())){
			TmsBaseDriverModel driverModel = tmsBaseDriverMapper.findById(user.getUserid(), TmsBaseDriverModel.class);
			if (ObjectUtil.isNull(driverModel)) {
				throw new BizException("司机不存在！");
			}
			if (DataDictionaryConstant.DRIVER_TYPE_OWN.equals(driverModel.getType())) {
				vo.setDepartmentIdList(user.getDepts());
			} else {
				vo.setAffiliationId(driverModel.getAffiliationId());
			}
		}
		PageUtils.startPage(vo.getPageNum(), vo.getPageSize());
		List<DeviceDTO> dtos = tmsBaseDeviceMapper.deviceQueryByCondition(vo);
		if (CollectionUtil.isNotEmpty(dtos)) {
			List<Long> baseId = dtos.stream().map(DeviceDTO::getId).collect(Collectors.toList());
			Criteria criteria = Criteria.forClass(TmsDepartmentBaseLinkModel.class);
			Restriction r1 = Restrictions.in("baseId", baseId.toArray());
			Restriction r2 = Restrictions.eq("baseType", DepartmentBaseLinkBaseTypeEnum.DEVICE.getCode());
			criteria.setRestriction(Restrictions.and(r1, r2));
			List<TmsDepartmentBaseLinkModel> tmsDepartmentBaseLinkModelList = tmsDepartmentBaseLinkMapper.findByCriteria(criteria);
			Map<String, List<TmsDepartmentBaseLinkModel>> baseMap =
					tmsDepartmentBaseLinkModelList.stream().collect(Collectors.groupingBy(TmsDepartmentBaseLinkModel::getBaseId));
			// 设备类型
			List<Map<String, Object>> restMessage1 = sysRefdatadService.getDropDownById(DataDictionaryConstant.DEVICE_TYPE, null, null, null);
			// 设备生产厂商
			List<Map<String, Object>> restMessage2 = sysRefdatadService.getDropDownById(DataDictionaryConstant.DEVICE_COMPANY, null, null, null);
			// 设备状态
			List<Map<String, Object>> restMessage3 = sysRefdatadService.getDropDownById(DataDictionaryConstant.MAINDATA_STATUS, null, null, null);
			// 归属
			List<Map<String, Object>> restMessage4 = sysRefdatadService.getDropDownById(BelongToEnum.BELONG_TO_TYPE, null, null, null);
			dtos.forEach(dto -> {
				dto.setCompanyName(PublicMethods.change(restMessage2, String.valueOf(dto.getCompany())));
				dto.setTypeName(PublicMethods.change(restMessage1, String.valueOf(dto.getType())));
				dto.setStatusName(PublicMethods.change(restMessage3, String.valueOf(dto.getStatus())));
				dto.setBelongToName(PublicMethods.change(restMessage4, String.valueOf(dto.getBelongTo())));
				List<TmsDepartmentBaseLinkModel> linkList = baseMap.get(dto.getId().toString());
				if (CollectionUtil.isNotEmpty(linkList)) {
					dto.setDepartmentId(linkList.stream().map(TmsDepartmentBaseLinkModel::getDepartmentId).collect(Collectors.joining(",")));
					dto.setDepartmentCode(linkList.stream().map(TmsDepartmentBaseLinkModel::getDepartmentCode).collect(Collectors.joining(",")));
					dto.setDepartmentName(linkList.stream().map(TmsDepartmentBaseLinkModel::getDepartmentName).collect(Collectors.joining(",")));
				}
			});
		}
		Page<DeviceDTO> page = PageUtils.getPage(dtos);
		return page;
	}
	/**
	 * 设备资料弹窗
	 * 
	 * @param vo
	 * @return
	 */
	@SuppressWarnings("resource")
	@Override
	public Page<DeviceDTO> pop(DevicePopVO vo) {
		DeviceVO deviceVO = new DeviceVO();
		BeanUtils.copyProperties(vo, deviceVO);
		deviceVO.setStatus(DataDictionaryConstant.STATUS_ENABLE);
		return query(deviceVO);
	}

	/**
	 * 车辆设备查询
	 * @param vo
	 * @return
	 */
	@Override
	public Page<DeviceDTO> queryByVehicle(DeviceVO vo) {
//		ToolKits.isParamNull(vo.getVehiclePlateNumber(), "车牌号不能为空");
		if (StrUtil.isNotBlank(vo.getVehiclePlateNumber())) {
			VehiclePaperPagingQueryVO vehiclePaperPagingQueryVO = new VehiclePaperPagingQueryVO();
			vehiclePaperPagingQueryVO.setVehiclePlateNumber(vo.getVehiclePlateNumber());
			List<VehicleDeviceLinkViewDTO> vehicleDeviceLinkViewDTOList =
					tmsBaseVehicleMapper.pageVehicleDeviceData(vehiclePaperPagingQueryVO);
			if (CollectionUtil.isNotEmpty(vehicleDeviceLinkViewDTOList)) {
				vo.setDeviceIdList(vehicleDeviceLinkViewDTOList.stream().map(VehicleDeviceLinkViewDTO::getDeviceId).collect(Collectors.toList()));
			}
		}
		vo.setStatus(DataDictionaryConstant.STATUS_ENABLE);
		return query(vo);
	}

	/**
	 * 设备资料查看
	 * 
	 * @param vo
	 * @return
	 */
	@Override
	public DeviceViewDTO view(DeviceViewVO vo) {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		ToolKits.isParamNull(vo.getId(), "设备ID不能为空");
		TmsBaseDeviceModel model = tmsBaseDeviceMapper.findById(vo.getId(), TmsBaseDeviceModel.class);
		ToolKits.isParamNull(model, "设备ID[" + vo.getId() + "]有误,查询为空!");
		// 设备类型
		List<Map<String, Object>> restMessage1 = sysRefdatadService.getDropDownById(DataDictionaryConstant.DEVICE_TYPE, null, null, null);
		// 设备生产厂商
		List<Map<String, Object>> restMessage2 = sysRefdatadService.getDropDownById(DataDictionaryConstant.DEVICE_COMPANY, null, null, null);
		// 设备状态
		List<Map<String, Object>> restMessage3 = sysRefdatadService.getDropDownById(DataDictionaryConstant.MAINDATA_STATUS, null, null, null);
		// 归属
		List<Map<String, Object>> restMessage4 = sysRefdatadService.getDropDownById(BelongToEnum.BELONG_TO_TYPE, null, null, null);
		DeviceViewDTO dto = new DeviceViewDTO();
		BeanUtils.copyProperties(model, dto);
		dto.setCompanyName(PublicMethods.change(restMessage2, String.valueOf(model.getCompany())));
		dto.setTypeName(PublicMethods.change(restMessage1, String.valueOf(model.getType())));
		dto.setStatusName(PublicMethods.change(restMessage3, String.valueOf(model.getStatus())));
		dto.setBelongToName(PublicMethods.change(restMessage4, String.valueOf(dto.getBelongTo())));
		Map<String, Object> findMap = Maps.newHashMap();
		findMap.put("baseType", DepartmentBaseLinkBaseTypeEnum.DEVICE.getCode());
		findMap.put("baseId", vo.getId());
		List<TmsDepartmentBaseLinkModel> linkList = tmsDepartmentBaseLinkMapper.findByMap(findMap, TmsDepartmentBaseLinkModel.class);
		if (CollectionUtil.isNotEmpty(linkList)) {
			dto.setDepartmentId(linkList.stream().map(TmsDepartmentBaseLinkModel::getDepartmentId).collect(Collectors.joining(",")));
			dto.setDepartmentCode(linkList.stream().map(TmsDepartmentBaseLinkModel::getDepartmentCode).collect(Collectors.joining(",")));
			dto.setDepartmentName(linkList.stream().map(TmsDepartmentBaseLinkModel::getDepartmentName).collect(Collectors.joining(",")));
		}
		return dto;
	}

	/**
	 * 设备资料新增
	 * 
	 * @param vo
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void save(DeviceAddVO vo) {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		ToolKits.isParamNull(vo.getCode(), "设备编码不能为空");
		ToolKits.isParamNull(vo.getName(), "设备名称不能为空");
		ToolKits.isParamNull(vo.getType(), "设备类型不能为空");
		ToolKits.isParamNull(vo.getDepartmentId(), "部门不能为空");
		ToolKits.isParamNull(vo.getDepartmentCode(), "部门编号不能为空");
		ToolKits.isParamNull(vo.getDepartmentName(), "部门名称不能为空");
		ToolKits.isParamNull(vo.getBelongTo(), "归属不能为空");
		Map<String, Object> map1 = Maps.newHashMap();
		map1.put("code", vo.getCode());
		map1.put("enterpriseId", user.getEnterpriseId());
		PublicMethods.doesItExistByMap(tmsBaseDeviceMapper, map1, TmsBaseDeviceModel.class, "设备编码【" + vo.getCode() + "】已存在");
		Map<String, Object> map2 = Maps.newHashMap();
		map2.put("name", vo.getName());
		map2.put("enterpriseId", user.getEnterpriseId());
		PublicMethods.doesItExistByMap(tmsBaseDeviceMapper, map2, TmsBaseDeviceModel.class, "设备名称【" + vo.getName() + "】已存在");
		if (BelongToEnum.OWN.getCode().equals(vo.getBelongTo())) {
			if (user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
				if (StrUtil.isNotBlank(user.getLoginUserCompanyInfo().getId())) {
					vo.setAffiliationId(Long.valueOf(user.getLoginUserCompanyInfo().getId()));
				}
				vo.setAffiliationCode(user.getLoginUserCompanyInfo().getCode());
				vo.setAffiliationName(user.getLoginUserCompanyInfo().getName());
			}
		} else {
			ToolKits.isParamNull(vo.getAffiliationId(), "隶属机构编码不为空");
			ToolKits.isParamNull(vo.getAffiliationCode(), "隶属机构编码不为空");
			ToolKits.isParamNull(vo.getAffiliationName(), "隶属机构名称不为空");
			Criteria criteria = Criteria.forClass(TmsBaseCarriersModel.class);
			Restriction r1 = Restrictions.eq("id", vo.getAffiliationId());
			Restriction r2 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
			criteria.setRestriction(Restrictions.and(r1, r2));
			List<TmsBaseCarriersModel> tmsBaseCarriersModels = tmsBaseCarriersMapper.findByCriteria(criteria);
			ToolKits.isParamNull(tmsBaseCarriersModels, "未找到对应的隶属机构[" + vo.getAffiliationName() + "]");
			TmsBaseCarriersModel tmsBaseCarriersModel = tmsBaseCarriersModels.get(0);
			if (StatusConstant.STATUS_DISABLE.equals(tmsBaseCarriersModel.getStatus())) {
				throw new BizException("隶属机构【" + vo.getAffiliationName() + "】已被停用");
			}
		}
		String id = sysCodeengineService.getCodeNumberByCode(SeriaNnumberConstant.DEVICE_ID, "L");
		ToolKits.isParamNull(id, "获取设备ID失败！");
		Date date = DateUtil.date();
		TmsBaseDeviceModel model = new TmsBaseDeviceModel();
		BeanUtils.copyProperties(vo, model);
		model.setId(Long.valueOf(id));
		model.setStatus(DataDictionaryConstant.STATUS_CREATE);
		model.setEnterpriseId(user.getEnterpriseId());
		model.setEnterpriseName(user.getEnterpriseName());
		model.setCreateperson(user.getNickname());
		model.setCreatetime(date);
		model.setUpdateperson(user.getNickname());
		model.setUpdatetime(date);
		tmsBaseDeviceMapper.save(model);
		departmentBaseLinkService.addLink(DepartmentBaseLinkBaseTypeEnum.DEVICE, id, vo.getDepartmentId(), vo.getDepartmentCode(), vo.getDepartmentName());
	}

	/**
	 * 设备资料修改
	 * 
	 * @param vo
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void update(DeviceUpdateVO vo) {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		ToolKits.isParamNull(vo.getId(), "设备ID不能为空");
		ToolKits.isParamNull(vo.getType(), "设备类型不能为空");
		ToolKits.isParamNull(vo.getDepartmentId(), "部门不能为空");
		ToolKits.isParamNull(vo.getDepartmentCode(), "部门编号不能为空");
		ToolKits.isParamNull(vo.getDepartmentName(), "部门名称不能为空");
		ToolKits.isParamNull(vo.getBelongTo(), "归属不能为空");
		if (BelongToEnum.OWN.getCode().equals(vo.getBelongTo())) {
			if (user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
				if (StrUtil.isNotBlank(user.getLoginUserCompanyInfo().getId())) {
					vo.setAffiliationId(Long.valueOf(user.getLoginUserCompanyInfo().getId()));
				}
				vo.setAffiliationCode(user.getLoginUserCompanyInfo().getCode());
				vo.setAffiliationName(user.getLoginUserCompanyInfo().getName());
			}
		} else {
			ToolKits.isParamNull(vo.getAffiliationId(), "隶属机构编码不为空");
			ToolKits.isParamNull(vo.getAffiliationCode(), "隶属机构编码不为空");
			ToolKits.isParamNull(vo.getAffiliationName(), "隶属机构名称不为空");
			Criteria criteria = Criteria.forClass(TmsBaseCarriersModel.class);
			Restriction r1 = Restrictions.eq("id", vo.getAffiliationId());
			Restriction r2 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
			criteria.setRestriction(Restrictions.and(r1, r2));
			List<TmsBaseCarriersModel> tmsBaseCarriersModels = tmsBaseCarriersMapper.findByCriteria(criteria);
			ToolKits.isParamNull(tmsBaseCarriersModels, "未找到对应的隶属机构[" + vo.getAffiliationName() + "]");
			TmsBaseCarriersModel tmsBaseCarriersModel = tmsBaseCarriersModels.get(0);
			if (StatusConstant.STATUS_DISABLE.equals(tmsBaseCarriersModel.getStatus())) {
				throw new BizException("隶属机构【" + vo.getAffiliationName() + "】已被停用");
			}
		}
		TmsBaseDeviceModel model = tmsBaseDeviceMapper.findById(vo.getId(), TmsBaseDeviceModel.class);
		ToolKits.isParamNull(model, "设备ID[" + vo.getId() + "]有误,查询为空!");
		model.setMemo(vo.getMemo());
		model.setAffiliationId(vo.getAffiliationId());
		model.setAffiliationCode(vo.getAffiliationCode());
		model.setAffiliationName(vo.getAffiliationName());
		model.setBelongTo(vo.getBelongTo());
		model.setType(vo.getType());
		model.setUpdateperson(user.getNickname());
		model.setUpdatetime(DateUtils.nowDate());
		tmsBaseDeviceMapper.update(model);
		departmentBaseLinkService.deleteLink(DepartmentBaseLinkBaseTypeEnum.DEVICE, Lists.newArrayList(String.valueOf(vo.getId())));
		departmentBaseLinkService.addLink(DepartmentBaseLinkBaseTypeEnum.DEVICE, String.valueOf(vo.getId()), vo.getDepartmentId(), vo.getDepartmentCode(), vo.getDepartmentName());
	}



	/**
	 * 设备资料是否启用
	 * 
	 * @param deviceWhetherEnableVO
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void whetherEnable(DeviceWhetherEnableVO deviceWhetherEnableVO) {
		ToolKits.isParamNull(deviceWhetherEnableVO, "设备是否启用请求不为空");
		ToolKits.isParamNull(deviceWhetherEnableVO.getIds(), "设备ID集不能为空！");
		ToolKits.isParamNull(deviceWhetherEnableVO.getStatus(), "状态不能为空！");
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		Criteria criteria = Criteria.forClass(TmsBaseDeviceModel.class);
		Restriction r1 = Restrictions.in("id", deviceWhetherEnableVO.getIds().toArray());
		criteria.setRestriction(r1);
		Map<String, Object> map = Maps.newHashMap();
		map.put("status", deviceWhetherEnableVO.getStatus());
		map.put("updateperson", user.getNickname());
		map.put("updatetime", DateUtil.date());
		tmsBaseDeviceMapper.updateMapByCriteria(map, criteria);
	}

	/**
	 * 设备资料删除
	 * 
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void delete(DeviceDeleteVO deviceDeleteVO) {
		ToolKits.isParamNull(deviceDeleteVO, "设备资料删除请求不为空");
		ToolKits.isParamNull(deviceDeleteVO.getIds(), "设备ID集不能为空！");
		// 判断设备是否已经绑定了车辆
		for (Long id : deviceDeleteVO.getIds()) {
			Map<String, Object> map = Maps.newHashMap();
			map.put("deviceId", id);
			PublicMethods.doesItExistByMap(tmsVehicleDeviceLinkMapper, map, TmsVehicleDeviceLinkModel.class, "设备【" + id + "】已绑定车辆,请先解绑");
		}
		// 执行删除
		tmsBaseDeviceMapper.deleteByIds(deviceDeleteVO.getIds().toArray(), TmsBaseDeviceModel.class);
		departmentBaseLinkService.deleteLink(DepartmentBaseLinkBaseTypeEnum.DEVICE,
				deviceDeleteVO.getIds().stream().map(String::valueOf).collect(Collectors.toList()));

	}

	/**
	 * 设备单个查询
	 * 
	 * @param id
	 */
	@Override
	public DeviceByOneDTO getOne(Long id) {
		ToolKits.isParamNull(id, "设备ID不能为空！");
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "没有操作权限！");
		TmsBaseDeviceModel model = tmsBaseDeviceMapper.findById(id, TmsBaseDeviceModel.class);
		ToolKits.isParamNull(model, "设备ID[" + id + "]有误,查询为空!");
		// 设备类型
		List<Map<String, Object>> restMessage1 = sysRefdatadService.getDropDownById(DataDictionaryConstant.DEVICE_TYPE, null, null, null);
		// 设备生产厂商
		List<Map<String, Object>> restMessage2 = sysRefdatadService.getDropDownById(DataDictionaryConstant.DEVICE_COMPANY, null, null, null);
		// 设备状态
		List<Map<String, Object>> restMessage3 = sysRefdatadService.getDropDownById(DataDictionaryConstant.MAINDATA_STATUS, null, null, null);
		// 归属
		List<Map<String, Object>> restMessage4 = sysRefdatadService.getDropDownById(BelongToEnum.BELONG_TO_TYPE, null, null, null);
		DeviceByOneDTO dto = new DeviceByOneDTO();
		BeanUtils.copyProperties(model, dto);
		dto.setCompanyName(PublicMethods.change(restMessage2, String.valueOf(model.getCompany())));
		dto.setTypeName(PublicMethods.change(restMessage1, String.valueOf(model.getType())));
		dto.setStatusName(PublicMethods.change(restMessage3, String.valueOf(model.getStatus())));
		dto.setBelongToName(PublicMethods.change(restMessage4, String.valueOf(model.getBelongTo())));
		Map<String, Object> findMap = Maps.newHashMap();
		findMap.put("baseType", DepartmentBaseLinkBaseTypeEnum.DEVICE.getCode());
		findMap.put("baseId", id);
		List<TmsDepartmentBaseLinkModel> linkList = tmsDepartmentBaseLinkMapper.findByMap(findMap, TmsDepartmentBaseLinkModel.class);
		if (CollectionUtil.isNotEmpty(linkList)) {
			dto.setDepartmentId(linkList.stream().map(TmsDepartmentBaseLinkModel::getDepartmentId).collect(Collectors.joining(",")));
			dto.setDepartmentCode(linkList.stream().map(TmsDepartmentBaseLinkModel::getDepartmentCode).collect(Collectors.joining(",")));
			dto.setDepartmentName(linkList.stream().map(TmsDepartmentBaseLinkModel::getDepartmentName).collect(Collectors.joining(",")));
		}
		return dto;
	}

	/**
	 * 导入设备
	 * @param file
	 */
	@Override
	public void importDevice(MultipartFile file) {
		// 导入文件判断
		FileUtils.multipartFileJudge(file);
		Properties properties = new Properties();
		// 待转换的对象
		Class<DeviceImportVO> importVOClass = DeviceImportVO.class;
		// 标准模板查询
		List<StandardTemplateDetailsListDTO> standardTemplateDetailsListDTOs =
				sysImportTemplethService.listStandardTemplateDetailsData(DataDictionaryConstant.DEVICE_IMPORT);
		standardTemplateDetailsListDTOs.forEach(standardTemplateDetailsListDTO ->
			properties.setProperty(standardTemplateDetailsListDTO.getStdColNo(), standardTemplateDetailsListDTO.getCustColName())
		);
		// @ExcelProperty注解属性修改
		ImportUtils.setHeaderValue(properties, importVOClass);
		// EXCEL转对象
		List<DeviceImportVO> importVOs;
		try {
			importVOs = ExcelUtils.read(file, importVOClass);
		} catch (Exception e) {
			log.error("设备导入异常", e);
			throw new ParameterException("EXCEL转对象失败:" + e.getMessage());
		}
		ToolKits.isParamNull(importVOs, "EXCEL文件内容为空,请重新导入");
		log.info("设备导入详情:{}", JSON.toJSONString(importVOs));
		String importBatchNumber = sysCodeengineService.getCodeNumberByCode(SeriaNnumberConstant.IMPORT_BATCHNO, "L");
		ToolKits.isParamNull(importBatchNumber, "导入批次获取失败");
		// 导入日志对象
		ImportLogAddVO logAddVO = new ImportLogAddVO();
		logAddVO.setImportObjNo(DataDictionaryConstant.DEVICE_IMPORT);
		logAddVO.setImportBatchNumber(importBatchNumber);
		logAddVO.setStatus(DataDictionaryConstant.IMPORT_STATUS_YES);
		logAddVO.setSuccessNum(importVOs.size());
		logAddVO.setFailNum(0);
		try {
			deviceService.saveImportDevice(importVOs, importBatchNumber);
			// 导入执行
			importLogService.addImportLogData(logAddVO);
		} catch (Exception e) {
			logAddVO.setStatus(DataDictionaryConstant.IMPORT_STATUS_NO);
			logAddVO.setSuccessNum(0);
			logAddVO.setFailNum(importVOs.size());
			logAddVO.setFailReason(e.getMessage());
			importLogService.addImportLogData(logAddVO);
			log.error("导入失败", e);
			throw new BizException(e.getMessage());
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void rollbackData(String batchno) {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		Criteria criteria = Criteria.forClass(TmsBaseDeviceModel.class);
		Restriction r1 = Restrictions.eq("importBatchNumber", batchno);
		criteria.setRestriction(r1);
		List<TmsBaseDeviceModel> tmsBaseDeviceModelList = tmsBaseDeviceMapper.findByCriteria(criteria);
		if (ToolKits.isEmpty(tmsBaseDeviceModelList)) {
			throw new BizException("批次号[" + batchno + "]错误,查询为空!");
		}
		DeviceDeleteVO deviceDeleteVO = new DeviceDeleteVO();
		deviceDeleteVO.setIds(tmsBaseDeviceModelList.stream().map(TmsBaseDeviceModel::getId).collect(Collectors.toList()));
		delete(deviceDeleteVO);
	}

	/**
	 * 保存导入数据
	 * @param importVOs
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void saveImportDevice(List<DeviceImportVO> importVOs, String importBatchNumber) {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		RestMessage<List<Organization>> departmentRes = userFeign.search(null, null, null, String.valueOf(user.getEnterpriseId()));
		if (!departmentRes.isSuccess()) {
			throw new BizException("企业部门不存在!");
		}
		List<Organization> departmentList = departmentRes.getData();
		Criteria carrierCriteria = Criteria.forClass(TmsBaseCarriersModel.class);
		Restriction carrierRestriction = Restrictions.eq("enterpriseId", user.getEnterpriseId());
		carrierCriteria.setRestriction(carrierRestriction);
		List<TmsBaseCarriersModel> tmsBaseCarriersModels = tmsBaseCarriersMapper.findByCriteria(carrierCriteria);
		Map<String, TmsBaseCarriersModel> carriersMap = tmsBaseCarriersModels.stream().collect(Collectors.toMap(t1 -> t1.getName(),
				t2 -> t2, (t1, t2) -> t2));
		//校验数据
		check(importVOs, departmentList, carriersMap);

		importVOs.forEach(deviceImportVO -> {
			String id = sysCodeengineService.getCodeNumberByCode(SeriaNnumberConstant.DEVICE_ID, "L");
			ToolKits.isParamNull(id, "获取设备ID失败！");
			TmsBaseCarriersModel carriersModel = carriersMap.get(deviceImportVO.getAffiliationName());
			Date date = DateUtil.date();
			TmsBaseDeviceModel model = new TmsBaseDeviceModel();
			model.setId(Long.valueOf(id));
			model.setCode(deviceImportVO.getCode());
			model.setName(deviceImportVO.getName());
			model.setType(Integer.valueOf(deviceImportVO.getType()));
			if (StrUtil.isNotBlank(deviceImportVO.getCompany())) {
				try {
					Integer.parseInt(deviceImportVO.getCompany());
				} catch (Exception e) {
					throw new BizException("不存在的设备生成厂商");
				}
				model.setCompany(Integer.valueOf(deviceImportVO.getCompany()));
			}
			model.setMemo(deviceImportVO.getMemo());
			if (BelongToEnum.OWN.getCode().equals(deviceImportVO.getBelongTo())) {
				if (user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
					if (StrUtil.isNotBlank(user.getLoginUserCompanyInfo().getId())) {
						model.setAffiliationId(Long.valueOf(user.getLoginUserCompanyInfo().getId()));
					}
					model.setAffiliationCode(user.getLoginUserCompanyInfo().getCode());
					model.setAffiliationName(user.getLoginUserCompanyInfo().getName());
				}
			} else {
				if (ObjectUtil.isNotNull(carriersModel)) {
					model.setAffiliationId(carriersModel.getId());
					model.setAffiliationCode(carriersModel.getCode());
					model.setAffiliationName(carriersModel.getName());
				}
			}
			model.setBelongTo(deviceImportVO.getBelongTo());
			model.setStatus(DataDictionaryConstant.STATUS_CREATE);
			model.setEnterpriseId(user.getEnterpriseId());
			model.setEnterpriseName(user.getEnterpriseName());
			model.setCreateperson(user.getNickname());
			model.setCreatetime(date);
			model.setUpdateperson(user.getNickname());
			model.setUpdatetime(date);
			model.setImportBatchNumber(importBatchNumber);
			tmsBaseDeviceMapper.save(model);
			List<String> departmentNames = Lists.newArrayList(deviceImportVO.getDepartment().replace("，",",").split(","));
			departmentBaseLinkService.addLink(DepartmentBaseLinkBaseTypeEnum.DEVICE, id,
					departmentList.stream().filter(department -> departmentNames.contains(department.getName())).collect(Collectors.toList()));
		});
	}

	/**
	 * 校验导入数据
	 * @param importVOs
	 * @param departmentList
	 * @param carriersMap
	 */
	private void check(List<DeviceImportVO> importVOs, List<Organization> departmentList,
					   Map<String, TmsBaseCarriersModel> carriersMap) {
		for (int i = 0; i < importVOs.size(); i++) {
			if (ToolKits.isEmpty(importVOs.get(i).getCode())) {
				throw new BizException("第" + (i+1) + "行导入数据,设备编码不能为空");
			}
			if (ToolKits.isEmpty(importVOs.get(i).getName())) {
				throw new BizException("第" + (i+1) + "行导入数据,设备名称不能为空");
			}
			if (ToolKits.isEmpty(importVOs.get(i).getType())) {
				throw new BizException("第" + (i+1) + "行导入数据,设备类型不能为空");
			} else {
				try {
					Integer.parseInt(importVOs.get(i).getType());
				} catch (Exception e) {
					throw new BizException("第" + (i+1) + "行导入数据,不存在的设备类型");
				}
			}
			if (ToolKits.isEmpty(importVOs.get(i).getDepartment())) {
				throw new BizException("第" + (i+1) + "行导入数据,部门不能为空");
			}
			if (ToolKits.isEmpty(importVOs.get(i).getBelongTo())) {
				throw new BizException("第" + (i+1) + "行导入数据,归属不能为空");
			}
			if (!BelongToEnum.OWN.getCode().equals(importVOs.get(i).getBelongTo())) {
				if (ToolKits.isEmpty(importVOs.get(i).getAffiliationName())) {
					throw new BizException("第" + (i+1) + "行导入数据,归属不为自有,隶属机构不能为空");
				}
			}
		}
		// 验证导入文件中设备编号是否重复
		Map<String, Long> codeMap = importVOs.stream().collect(Collectors.groupingBy(DeviceImportVO::getCode, Collectors.counting()));
		for (Map.Entry<String, Long> longEntry : codeMap.entrySet()) {
			if (longEntry.getValue() > 1) {
				throw new ParameterException(String.format("导入文件中，设备编号【%s】重复", longEntry.getKey()));
			}
		}
		// 验证导入文件中设备名称是否重复
		Map<String, Long> nameMap = importVOs.stream().collect(Collectors.groupingBy(DeviceImportVO::getName, Collectors.counting()));
		for (Map.Entry<String, Long> longEntry : nameMap.entrySet()) {
			if (longEntry.getValue() > 1) {
				throw new ParameterException(String.format("导入文件中，设备名称【%s】重复", longEntry.getKey()));
			}
		}
		Set<String> codeList = codeMap.keySet();
		Set<String> nameList = nameMap.keySet();
		Criteria criteria = Criteria.forClass(TmsBaseDeviceModel.class);
		Restriction r1 = Restrictions.in("code", codeList.toArray());
		criteria.setRestriction(r1);
		List<TmsBaseDeviceModel> tmsBaseDeviceModelList = tmsBaseDeviceMapper.findByCriteria(criteria);
		if (CollectionUtil.isNotEmpty(tmsBaseDeviceModelList)) {
			throw new ParameterException(String.format("导入文件中，设备编号已存在"));
		}
		Criteria namecriteria = Criteria.forClass(TmsBaseDeviceModel.class);
		Restriction rname = Restrictions.in("name", nameList.toArray());
		namecriteria.setRestriction(rname);
		List<TmsBaseDeviceModel> tmsBaseDeviceModelList1 = tmsBaseDeviceMapper.findByCriteria(namecriteria);
		if (CollectionUtil.isNotEmpty(tmsBaseDeviceModelList1)) {
			throw new ParameterException(String.format("导入文件中，设备名称已存在"));
		}
		Map<String, Organization> departmentMap = departmentList.stream().collect(Collectors.toMap(t1 -> t1.getName(),
				t2 -> t2, (t1, t2) -> t2));
		List<String> departmentNameList = importVOs.stream().flatMap(deviceImportVO ->
						Stream.of(deviceImportVO.getDepartment().replace("，",",").split(","))).
				distinct().collect(Collectors.toList());
		departmentNameList.forEach(departmentName -> {
			if (!departmentMap.keySet().contains(departmentName)) {
				throw new BizException("部门【"+departmentName+"】不存在!");
			}
		});
		List<String> affiliationNameList = importVOs.stream().map(DeviceImportVO::getAffiliationName).
				filter(StrUtil::isNotBlank).collect(Collectors.toList());
		affiliationNameList.forEach(affiliationName -> {
			if (!carriersMap.keySet().contains(affiliationName)) {
				throw new BizException("隶属机构【" + affiliationName + "】不存在!");
			}
			if (StatusConstant.STATUS_DISABLE.equals(carriersMap.get(affiliationName).getStatus())) {
				throw new BizException("隶属机构【" + affiliationName + "】已被停用");
			}
		});
	}

}
