package com.jsowell.pile.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.google.common.collect.Lists;
import com.jsowell.common.constant.CacheConstants;
import com.jsowell.common.constant.Constants;
import com.jsowell.common.core.domain.vo.AuthorizedDeptVO;
import com.jsowell.common.core.domain.ykc.RealTimeMonitorData;
import com.jsowell.common.core.domain.ykc.YKCFrameTypeCode;
import com.jsowell.common.core.redis.RedisCache;
import com.jsowell.common.enums.ykc.PileConnectorDataBaseStatusEnum;
import com.jsowell.common.enums.ykc.PileConnectorStatusEnum;
import com.jsowell.common.util.BytesUtil;
import com.jsowell.common.util.DateUtils;
import com.jsowell.common.util.PageUtils;
import com.jsowell.common.util.SecurityUtils;
import com.jsowell.common.util.StringUtils;
import com.jsowell.pile.domain.PileBasicInfo;
import com.jsowell.pile.domain.PileConnectorInfo;
import com.jsowell.pile.domain.PileModelInfo;
import com.jsowell.pile.domain.PileSimInfo;
import com.jsowell.pile.dto.IndexQueryDTO;
import com.jsowell.pile.dto.QueryPileDTO;
import com.jsowell.pile.dto.ReplaceMerchantStationDTO;
import com.jsowell.pile.mapper.PileBasicInfoMapper;
import com.jsowell.pile.service.IPileBasicInfoService;
import com.jsowell.pile.service.IPileConnectorInfoService;
import com.jsowell.pile.service.IPileMerchantInfoService;
import com.jsowell.pile.service.IPileModelInfoService;
import com.jsowell.pile.service.IPileSimInfoService;
import com.jsowell.pile.service.IPileStationInfoService;
import com.jsowell.pile.service.SimCardService;
import com.jsowell.pile.vo.base.MerchantInfoVO;
import com.jsowell.pile.vo.base.PileInfoVO;
import com.jsowell.pile.vo.uniapp.PersonalPileInfoVO;
import com.jsowell.pile.vo.uniapp.PileConnectorDetailVO;
import com.jsowell.pile.vo.web.IndexGeneralSituationVO;
import com.jsowell.pile.vo.web.PileDetailVO;
import com.jsowell.pile.vo.web.PileModelInfoVO;
import com.jsowell.pile.vo.web.SimCardVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 设备管理Service业务层处理
 *
 * @author jsowell
 * @date 2022-08-26
 */
@Slf4j
@Service
public class PileBasicInfoServiceImpl implements IPileBasicInfoService {
	@Autowired
	private PileBasicInfoMapper pileBasicInfoMapper;

	@Autowired
	private IPileConnectorInfoService pileConnectorInfoService;

	@Autowired
	private IPileModelInfoService pileModelInfoService;

	@Autowired
	private IPileMerchantInfoService pileMerchantInfoService;

	@Autowired
	private IPileStationInfoService pileStationInfoService;

	@Autowired
	private IPileSimInfoService pileSimInfoService;

	@Autowired
	private SimCardService simCardService;

	@Autowired
	private RedisCache redisCache;

	@Value("${qrcodeurl.prefix}")
	private String QRCODE_URL_PREFIX;

	/**
	 * 查询设备管理
	 *
	 * @param id 设备管理主键
	 * @return 设备管理
	 */
	@Override
	public PileBasicInfo selectPileBasicInfoById(Long id) {
		return pileBasicInfoMapper.selectPileBasicInfoById(id);
	}

	/**
	 * 清除缓存
	 * @param pileSn
	 */
	private void cleanRedisCache(String pileSn) {
		List<String> keys = Lists.newArrayList();
		keys.add(CacheConstants.SELECT_PILE_BASIC_INFO_BY_SN + pileSn);
		redisCache.deleteObject(keys);
	}

	@Override
	public PileBasicInfo selectPileBasicInfoBySN(String pileSn) {
		// 加缓存
		String redisKey = CacheConstants.SELECT_PILE_BASIC_INFO_BY_SN + pileSn;
		PileBasicInfo pileBasicInfo = redisCache.getCacheObject(redisKey);
		if (pileBasicInfo == null) {
			// 查数据库
			pileBasicInfo = pileBasicInfoMapper.selectPileBasicInfoBySn(pileSn);
			if (pileBasicInfo != null) {
				redisCache.setCacheObject(redisKey, pileBasicInfo, 5, TimeUnit.MINUTES);
			}
		}
		return pileBasicInfo;
	}

	/**
	 * 查询设备管理列表
	 *
	 * @param pileBasicInfo 设备管理
	 * @return 设备管理
	 */
	@Override
	public List<PileBasicInfo> selectPileBasicInfoList(PileBasicInfo pileBasicInfo) {
		return pileBasicInfoMapper.selectPileBasicInfoList(pileBasicInfo);
	}

	/**
	 * 新增设备管理
	 *
	 * @param pileBasicInfo 设备管理
	 * @return 结果
	 */
	@Override
	public int insertPileBasicInfo(PileBasicInfo pileBasicInfo) {
		pileBasicInfo.setCreateBy(SecurityUtils.getUsername());
		pileBasicInfo.setCreateTime(DateUtils.getNowDate());
		return pileBasicInfoMapper.insertPileBasicInfo(pileBasicInfo);
	}

	/**
	 * 修改设备管理
	 *
	 * @param pileBasicInfo 设备管理
	 * @return 结果
	 */
	@Override
	public int updatePileBasicInfo(PileBasicInfo pileBasicInfo) {
		// pileBasicInfo.setUpdateBy(SecurityUtils.getUsername());
		// 清缓存
		cleanRedisCache(pileBasicInfo.getSn());
		pileBasicInfo.setUpdateTime(DateUtils.getNowDate());
		return pileBasicInfoMapper.updatePileBasicInfo(pileBasicInfo);
	}

	/**
	 * 批量删除设备管理
	 *
	 * @param ids 需要删除的设备管理主键
	 * @return 结果
	 */
	@Override
	public int deletePileBasicInfoByIds(Long[] ids) {
		return pileBasicInfoMapper.deletePileBasicInfoByIds(ids);
	}

	/**
	 * 删除设备管理信息
	 *
	 * @param id 设备管理主键
	 * @return 结果
	 */
	@Override
	public int deletePileBasicInfoById(Long id) {
		return pileBasicInfoMapper.deletePileBasicInfoById(id);
	}

	/**
	 * 查询充电桩信息
	 * 后管使用，带权限过滤
	 * @param dto 前台参数
	 * @return 充电桩信息集合
	 */
	@Override
	// @DataScope(deptAlias = "t2")
	public List<PileDetailVO> queryPileInfos(QueryPileDTO dto) {
		StopWatch watch = new StopWatch("查询充电桩信息");
		watch.start("首先不分页查询所有符合条件的充电桩");
		log.info("queryPileInfos dto:{}", JSONObject.toJSONString(dto));
		// 首先不分页查询所有符合条件的充电桩
		List<PileDetailVO> pileInfoVOS = queryPileInfoList(dto);
		watch.stop();

		watch.start("查询充电桩状态");
		// 获取桩sn列表
		List<String> pileSnList = pileInfoVOS.stream().map(PileDetailVO::getPileSn).collect(Collectors.toList());
		// log.info("获取桩sn列表:{}", JSONObject.toJSONString(pileSnList));
		// 批量获取桩状态 key:桩编号; value:状态
		Map<String, String> pileStatusMap = pileConnectorInfoService.getPileStatus(pileSnList);
		watch.stop();

		watch.start("根据状态过滤");
		// log.info("批量获取桩状态:{}", JSONObject.toJSONString(pileStatusMap));
		// 根据状态过滤
		List<String> snList = Lists.newArrayList();
		if (StringUtils.isNotBlank(dto.getStatus())) {
			for (Map.Entry<String, String> entry : pileStatusMap.entrySet()) {
				String pileSn = entry.getKey();
				String pileStatus = entry.getValue();
				if (StringUtils.equals(dto.getStatus(), pileStatus)) {
					snList.add(pileSn);
				}
			}
		} else {
			// 不根据状态过滤，snList就等于pileSnList
			snList = pileSnList;
			// 根据状态排序

		}
		watch.stop();

		watch.start("查询桩列表");
		if (CollectionUtils.isEmpty(snList)) {
			return Lists.newArrayList();
		}
		// 使用snList查询 分页
		if (dto.getPageNum() != 0) {
			PageUtils.startPage();
		}
		QueryPileDTO queryPileDTO = new QueryPileDTO();
		queryPileDTO.setPileSns(snList);
		pileInfoVOS = queryPileInfoList(queryPileDTO);

		for (PileDetailVO pileInfoVO : pileInfoVOS) {
			pileInfoVO.setStatus(pileStatusMap.get(pileInfoVO.getPileSn()));
		}
		watch.stop();
		log.info("总耗时:{}, 详细信息:{}", watch.getTotalTimeSeconds(), watch.prettyPrint());
		return pileInfoVOS;
	}

	/**
	 * 查询充电桩列表
	 * 后管使用，带权限过滤
	 * @param queryPileDTO
	 * @return
	 */
	@Override
	// @DataScope(deptAlias = "t1")
	public List<PileDetailVO> queryPileInfoList(QueryPileDTO queryPileDTO) {
		AuthorizedDeptVO authorizedMap = SecurityUtils.getAuthorizedMap();
		if (authorizedMap == null) {
			// 为空表示没有权限，返回空数组
			return Lists.newArrayList();
		}
		queryPileDTO.setStationDeptIds(authorizedMap.getStationDeptIds());
		queryPileDTO.setMerchantDeptIds(authorizedMap.getMerchantDeptIds());
		return pileBasicInfoMapper.queryPileInfos(queryPileDTO);
	}

	/**
	 * 通过pileId更改运营商、站点信息
	 *
	 * @param dto 前台参数
	 * @return 结果
	 */
	@Override
	public int replaceMerchantStationByPileIds(ReplaceMerchantStationDTO dto) {

		dto.setUpdateBy(SecurityUtils.getUsername());
		dto.setUpdateTime(DateUtils.getNowDate());
		int num = pileBasicInfoMapper.replaceMerchantStationByPileIds(dto);
		// 修改枪口信息
		if (dto.getConnectorNum() != null && dto.getConnectorNum() > 0) {
			// 先删后插
			pileConnectorInfoService.deletePileConnectorInfoByPileSnList(dto.getPileSnList());
			List<PileConnectorInfo> connectorInfoList = Lists.newArrayList();
			for (String pileSn : dto.getPileSnList()) {
				// 清缓存
				cleanRedisCache(pileSn);
				for (int i = 1; i < dto.getConnectorNum() + 1; i++) {
					// 组装pile_connector_info表数据
					PileConnectorInfo connectorInfo = new PileConnectorInfo();
					connectorInfo.setPileSn(pileSn); // sn号
					String connectorCode = String.format("%1$02d", i);
					connectorInfo.setPileConnectorCode(pileSn + connectorCode); // 枪口编号
					connectorInfo.setStatus(Constants.ZERO); //状态，默认 0-离网
					connectorInfo.setCreateBy(SecurityUtils.getUsername()); // 创建人
					connectorInfo.setDelFlag(Constants.DEL_FLAG_NORMAL); // 删除标识
					connectorInfoList.add(connectorInfo);
				}
			}
			if (CollectionUtils.isNotEmpty(connectorInfoList)) {
				pileConnectorInfoService.batchInsertConnectorInfo(connectorInfoList);
			}
		}
		return num;
	}

	/**
	 * 通过桩id查询basic信息
	 *
	 * @param id 桩id
	 * @return 结果集合
	 */
	@Override
	public PileDetailVO selectBasicInfoById(Long id) {
		PileDetailVO pileInfoVO = pileBasicInfoMapper.selectBasicInfoById(id);
		if (pileInfoVO == null) {
			return null;
		}
		// 获取桩状态
		Map<String, String> pileStatusMap = pileConnectorInfoService.getPileStatus(Lists.newArrayList(pileInfoVO.getPileSn()));
		pileInfoVO.setStatus(pileStatusMap.get(pileInfoVO.getPileSn()));
		String pileQrCodeUrl = getPileQrCodeUrl(pileInfoVO.getPileSn());
		pileInfoVO.setQrCodeURL(pileQrCodeUrl);
		// 设备型号
		PileModelInfo pileModelInfo = pileModelInfoService.selectPileModelInfoById(Long.parseLong(pileInfoVO.getModelId()));
		if (pileModelInfo != null) {
			pileInfoVO.setModelName(pileModelInfo.getModelName());
		}
		return pileInfoVO;
	}

	@Override
	public PileInfoVO selectPileInfoBySn(String pileSn) {
		PileBasicInfo basicInfo = selectPileBasicInfoBySN(pileSn);
		if (basicInfo == null) {
			return null;
		}

		PileInfoVO pileInfoVO = PileInfoVO.builder()
				.pileId(String.valueOf(basicInfo.getId()))
				.pileSn(basicInfo.getSn())
				.stationId(String.valueOf(basicInfo.getStationId()))
				.merchantId(String.valueOf(basicInfo.getMerchantId()))
				.build();
		// 查站点信息
		MerchantInfoVO merchantInfo = pileMerchantInfoService.getMerchantInfo(String.valueOf(basicInfo.getMerchantId()));
		if (merchantInfo != null) {
			pileInfoVO.setMerchantName(merchantInfo.getMerchantName());
		}

		// 查询充电桩额定功率
		PileModelInfoVO pileModelInfoVO = pileModelInfoService.getPileModelInfoByPileSn(pileSn);
		if (pileModelInfoVO != null) {
			pileInfoVO.setRatedPower(pileModelInfoVO.getRatedPower());
			pileInfoVO.setRatedCurrent(pileModelInfoVO.getRatedCurrent());
			pileInfoVO.setRatedVoltage(pileModelInfoVO.getRatedVoltage());
			pileInfoVO.setModelName(pileModelInfoVO.getModelName());
		}
		return pileInfoVO;
	}

	@Override
	public List<PileDetailVO> selectPileListByStationIds(List<Long> stationIdList) {
		// 加缓存
		List<PileDetailVO> pileInfoVOS = pileBasicInfoMapper.selectPileListByStationIds(stationIdList);
		if (CollectionUtils.isEmpty(pileInfoVOS)) {
			return Lists.newArrayList();
		}
		List<String> pileSnList = pileInfoVOS.stream().map(PileDetailVO::getPileSn).collect(Collectors.toList());
		Map<String, String> pileStatusMap = pileConnectorInfoService.getPileStatus(pileSnList);
		for (PileDetailVO pileInfoVO : pileInfoVOS) {
			pileInfoVO.setStatus(pileStatusMap.get(pileInfoVO.getPileSn()));
		}
		return pileInfoVOS;
	}

	/**
	 * 修改状态
	 * 用于登陆协议，心跳包协议，上传实时数据协议 更新状态的方法
	 * 数据库状态
	 * 充电枪：0-离线；1-空闲；2-占用（未充电）；3-占用（充电中）；4-占用（预约锁定）；255-故障
	 * <p>
	 * 充电枪口状态在以下情况会改变
	 * 1.登陆成功后，设置为【1-空闲】
	 * 2.心跳包传0x01故障，设置为【255-故障】
	 * 3.上传实时数据，枪状态传0x00离线，设置为【0-离线】
	 * 4.上传实时数据，枪状态传0x01故障，设置为【255-故障】
	 * 5.上传实时数据，枪状态传0x02空闲，并且为插枪状态，设置为【2-占用（未充电）】
	 * 6.上传实时数据，枪状态传0x02空闲，并且为未插枪状态，设置为【1-空闲】
	 * 7.上传实时数据，枪状态传0x03充电，设置为【3-占用（充电中）】
	 */
	@Override
	public void updateStatus(String frameType, String pileSn, String connectorCode, String status, String putGunType) {
		// 清缓存
		cleanRedisCache(pileSn);
		// log.info("updateStatus传参：帧类型:{}, 桩编号:{}, 枪口号:{}, 状态:{}, 插拔枪:{}", "0x" + frameType, pileSn, connectorCode, status, putGunType);
		/*
		0x01 登陆认证
		登陆成功，把充电桩和枪口的状态都更新为【在线】
		 */
		if (StringUtils.equals(frameType, String.valueOf(YKCFrameTypeCode.LOGIN_CODE.getCode()))) {
			// 枪口状态设置为【空闲】
			pileConnectorInfoService.updateConnectorStatusByPileSn(pileSn, PileConnectorDataBaseStatusEnum.FREE.getValue());
		}

		/*
		0x03 心跳包 枪口状态 0-正常 1-故障
		心跳包会传过来枪口的状态，由枪口状态推导出来充电桩的状态。任意一个枪口状态为故障，则充电桩状态也是故障
		 */
		if (StringUtils.equals(frameType, BytesUtil.bcd2Str(YKCFrameTypeCode.HEART_BEAT_CODE.getBytes()))) {
			// log.info("心跳包的修改状态逻辑 桩号:{}, 枪号:{}, 枪状态:{}", pileSn, connectorCode, status);

			/*
			更新充电桩接口的数据库状态
			传入的状态为【1-故障】，就把枪口数据库改为故障
			 */
			if (StringUtils.equals(status, Constants.ONE)) {
				// 故障
				pileConnectorInfoService.updateConnectorStatus(pileSn + connectorCode, PileConnectorDataBaseStatusEnum.FAULT.getValue());
			} else {
				// 正常
				// List<PileConnectorInfo> connectorInfoList = pileConnectorInfoService.selectPileConnectorInfoList(pileSn);
				// for (PileConnectorInfo connectorInfo : connectorInfoList) {
				// 	// 收到心跳包，只有在离线或故障时，修改为空闲状态
				// 	if (StringUtils.equals(connectorInfo.getStatus(), PileConnectorDataBaseStatusEnum.OFF_NETWORK.getValue())
				// 			|| StringUtils.equals(connectorInfo.getStatus(), PileConnectorDataBaseStatusEnum.FAULT.getValue())) {
				// 		pileConnectorInfoService.updateConnectorStatus(pileSn + connectorCode, PileConnectorDataBaseStatusEnum.FREE.getValue());
				// 	}
				// }
			}
		}

		/*
		 0x13 上传实时数据 枪口状态 0x00：离线 0x01：故障 0x02：空闲 0x03：充电
		根据传来的枪状态和是否插枪，判断状态
		 */
		if (StringUtils.equals(frameType, BytesUtil.bcd2Str(YKCFrameTypeCode.UPLOAD_REAL_TIME_MONITOR_DATA_CODE.getBytes()))
				|| StringUtils.equals(frameType, BytesUtil.bcd2Str(YKCFrameTypeCode.UPLOAD_REAL_TIME_MONITOR_DATA_OLD_VERSION_CODE.getBytes()))) {
			// log.info("上传实时数据中的修改状态逻辑 桩号:{}, 枪号:{}, 枪状态{}, 是否插枪：{}", pileSn, connectorCode, status, putGunType);
			/**
			 * 更新枪状态
			 * connectorStatus 桩传过来的枪口状态： 0x00：离线  0x01：故障  0x02：空闲  0x03：充电
			 * 数据库状态：0：离网 (默认)；1：空闲；2：占用（未充电）；3：占用（充电中）；4：占用（预约锁定） ；255：故障
			 */
			String statusDataBase = ""; // 传给数据库的状态
			if (StringUtils.equals(status, PileConnectorStatusEnum.OFF_NETWORK.getValue())) { // 离线
				statusDataBase = PileConnectorDataBaseStatusEnum.OFF_NETWORK.getValue();
			} else if (StringUtils.equals(status, PileConnectorStatusEnum.FAULT.getValue())) { // 故障
				statusDataBase = PileConnectorDataBaseStatusEnum.FAULT.getValue();
			} else if (StringUtils.equals(status, PileConnectorStatusEnum.FREE.getValue())) { // 空闲
				//是否插枪 0x00：否  0x01：是
				if (StringUtils.equals(putGunType, Constants.ZERO_ONE)) {
					// 空闲并插枪 设置为【占用（未充电）】
					statusDataBase = PileConnectorDataBaseStatusEnum.OCCUPIED_NOT_CHARGED.getValue();
				} else {
					// 空闲没插枪 设置为【空闲】
					statusDataBase = PileConnectorDataBaseStatusEnum.FREE.getValue();
				}
			} else if (StringUtils.equals(status, PileConnectorStatusEnum.OCCUPIED_CHARGING.getValue())) { // 充电
				// 设置为【占用（充电中）】
				statusDataBase = PileConnectorDataBaseStatusEnum.OCCUPIED_CHARGING.getValue();
			}
			pileConnectorInfoService.updateConnectorStatus(pileSn + connectorCode, statusDataBase);
		}
	}

	/**
	 * 充电桩正在充电时的实时数据存到redis
	 * @param realTimeMonitorData 实时数据
	 */
	@Override
	public void saveRealTimeMonitorData2Redis(RealTimeMonitorData realTimeMonitorData) {
		if (StringUtils.equals(realTimeMonitorData.getTransactionCode(), Constants.ILLEGAL_TRANSACTION_CODE)) {
			return;
		}
		// 保存到redis
		String redisKey = CacheConstants.PILE_REAL_TIME_MONITOR_DATA + realTimeMonitorData.getPileConnectorCode() + "_" + realTimeMonitorData.getTransactionCode();

		// 设置接收到实时数据的时间
		Date now = new Date();
		realTimeMonitorData.setDateTime(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, now));
		// 计算功率，后面查询要用
		String power = new BigDecimal(realTimeMonitorData.getOutputVoltage())
				.multiply(new BigDecimal(realTimeMonitorData.getOutputCurrent())).setScale(2, RoundingMode.HALF_UP).toString();
		realTimeMonitorData.setOutputPower(power);
		// 保存json字符串
		String jsonMsg = JSONObject.toJSONString(realTimeMonitorData);
		// 上传实时数据每10秒发送一次，1分钟6次，在同一分钟内，只保留最后一条实时数据
		redisCache.hset(redisKey, DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:00", now), jsonMsg);

		// 把充电桩正在充电中的状态存到redis
		String pileIsChargingKey = CacheConstants.PILE_IS_CHARGING + realTimeMonitorData.getPileSn();
		redisCache.setCacheObject(pileIsChargingKey, Constants.one, 12);
	}

	@Override
	public PileConnectorDetailVO queryPileConnectorDetail(String pileConnectorCode) {
		return pileBasicInfoMapper.queryPileConnectorDetail(pileConnectorCode);
	}

	/**
	 * 返回充电桩二维码
	 * @param pileSn 如充电桩编号为空，则返回前缀 https://api.jsowellcloud.com/app-xcx-h5/pile/pileDetail/
	 * @return
	 */
	@Override
	public String getPileQrCodeUrl(String pileSn) {
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.append(QRCODE_URL_PREFIX);
		stringBuilder.append("/app-xcx-h5/pile/pileDetail/");
		if (StringUtils.isNotEmpty(pileSn)) {
			if (!stringBuilder.toString().endsWith("/")) {
				stringBuilder.append("/");
			}
			stringBuilder.append(pileSn);
		}
		return stringBuilder.toString();
	}

	@Override
	public void updatePileSimInfo(String pileSn, String iccid) {
		// 清缓存
		cleanRedisCache(pileSn);
		PileBasicInfo basicInfo = selectPileBasicInfoBySN(pileSn);
		if (basicInfo == null) {
			return;
		}
		// 通过iccid查pile_sim_info
		PileSimInfo simInfo = pileSimInfoService.getBasicInfoByIccId(iccid);
		if (simInfo == null) {
			SimCardVO simCardVO = simCardService.searchByLoop(iccid);
			// pile_sim_info 新增数据
			if (simCardVO != null) {
				simInfo = PileSimInfo.builder()
						.iccid(iccid)
						.name(simCardVO.getName())
						.simSupplier(simCardVO.getSimCardFactory())
						.expireTime(DateUtils.parseDate(simCardVO.getExpiredTime()))
						.operator(simCardVO.getSimCardOperator())
						.status(simCardVO.getSimCardStatus())
						.surplusData(String.valueOf(simCardVO.getResidualFlowRate()))
						.totalData(String.valueOf(simCardVO.getPackageCapacity()))
						.build();
			}else {
				// 卡商未查到信息，记录为新卡，只存卡号
				simInfo = PileSimInfo.builder()
						.iccid(iccid)
						.build();
			}
			pileSimInfoService.insertPileSimInfo(simInfo);
			// 拿到id
			Long simId = simInfo.getId();
			log.info("新保存的sim卡id:{}", simId);
			// sim_id 更新到pile_basic_info
			basicInfo.setSimId(simId);
		} else {
			// sim信息已经存库了 然后更新充电桩的sim卡
			basicInfo.setSimId(simInfo.getId());
		}
		updatePileBasicInfo(basicInfo);
	}

	/**
	 * 后管首页基本信息查询
	 *
	 * @param dto 站点Id
	 * @return 首页基本信息
	 */
    @Override
    public IndexGeneralSituationVO getGeneralSituation(IndexQueryDTO dto) {
		AuthorizedDeptVO authorizedMap = SecurityUtils.getAuthorizedMap();
		if (authorizedMap == null) {
			return new IndexGeneralSituationVO();
		}
		List<String> stationIdList = Lists.newArrayList();
		List<String> stationDeptIds = authorizedMap.getStationDeptIds();
		if (CollectionUtils.isNotEmpty(stationDeptIds)) {
			// 根据部门id查询站点id
			List<String> list = pileStationInfoService.queryByStationDeptIds(stationDeptIds);
			if (CollectionUtils.isNotEmpty(list)) {
				stationIdList.addAll(list);
			}
		}
		List<String> merchantDeptIds = authorizedMap.getMerchantDeptIds();
		if (CollectionUtils.isNotEmpty(merchantDeptIds)) {
			// 根据运营商部门id查询下面所有站点id
			List<String> list = pileMerchantInfoService.queryByMerchantDeptIds(merchantDeptIds);
			if (CollectionUtils.isNotEmpty(list)) {
				stationIdList.addAll(list);
			}
		}
		log.info("后管首页基本信息查询 authorizedMap:{}, dto:{}", JSONObject.toJSONString(authorizedMap), JSONObject.toJSONString(dto));
		dto.setStationIdList(stationIdList);
		return pileBasicInfoMapper.getGeneralSituation(dto);
    }

	/**
	 * 通过会员id查询个人桩列表
	 * @param memberId
	 * @return
	 */
	@Override
	public List<PersonalPileInfoVO> getPileInfoByMemberId(String memberId) {
		List<PersonalPileInfoVO> list = pileBasicInfoMapper.getPileInfoByMemberId(memberId);
		if(CollectionUtils.isEmpty(list)){
			return null;
		}

		for (PersonalPileInfoVO personalPileInfoVO : list) {
			String pileSn = personalPileInfoVO.getPileSn();

			// 获取桩状态
			Map<String, String> pileStatus = pileConnectorInfoService.getPileStatus(Lists.newArrayList(pileSn));
			personalPileInfoVO.setPileStatus(pileStatus.get(pileSn));
			if (StringUtils.equals("1", personalPileInfoVO.getType())) {
				personalPileInfoVO.setType("管理员用户");
			}else {
				personalPileInfoVO.setType("普通用户");
			}
			if (StringUtils.equals("1", personalPileInfoVO.getSpeedType())) {
				personalPileInfoVO.setSpeedType("快充");
			}else {
				personalPileInfoVO.setSpeedType("慢充");
			}
		}
		return list;
	}

    @Override
    public List<PileBasicInfo> getPileListByStationId(String stationId) {
        return pileBasicInfoMapper.getPileListByStationId(stationId);
    }
}
