| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978 |
- package com.zsElectric.boot.business.service.impl;
- import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
- import com.baomidou.mybatisplus.core.metadata.IPage;
- import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
- import com.zsElectric.boot.business.mapper.BannerInfoMapper;
- import com.zsElectric.boot.business.mapper.ChargeOrderInfoMapper;
- import com.zsElectric.boot.business.mapper.DiscountsActivityMapper;
- import com.zsElectric.boot.business.mapper.PolicyFeeMapper;
- import com.zsElectric.boot.business.mapper.ThirdPartyStationInfoMapper;
- import com.zsElectric.boot.business.mapper.UserAccountMapper;
- import com.zsElectric.boot.business.mapper.UserFirmMapper;
- import com.zsElectric.boot.system.mapper.DictItemMapper;
- import com.zsElectric.boot.charging.entity.ThirdPartyChargeStatus;
- import com.zsElectric.boot.charging.entity.ThirdPartyConnectorInfo;
- import com.zsElectric.boot.charging.entity.ThirdPartyEquipmentInfo;
- import com.zsElectric.boot.charging.mapper.ThirdPartyChargeStatusMapper;
- import com.zsElectric.boot.charging.mapper.ThirdPartyConnectorInfoMapper;
- import com.zsElectric.boot.charging.entity.ThirdPartyEquipmentPricePolicy;
- import com.zsElectric.boot.charging.entity.ThirdPartyPolicyInfo;
- import com.zsElectric.boot.charging.entity.ThirdPartyStationInfo;
- import com.zsElectric.boot.business.mapper.ThirdPartyEquipmentInfoMapper;
- import com.zsElectric.boot.charging.mapper.ThirdPartyEquipmentPricePolicyMapper;
- import com.zsElectric.boot.charging.mapper.ThirdPartyPolicyInfoMapper;
- import com.zsElectric.boot.business.model.entity.BannerInfo;
- import com.zsElectric.boot.business.model.entity.ChargeOrderInfo;
- import com.zsElectric.boot.business.model.entity.DiscountsActivity;
- import com.zsElectric.boot.business.model.entity.PolicyFee;
- import com.zsElectric.boot.business.model.entity.UserAccount;
- import com.zsElectric.boot.business.model.entity.UserFirm;
- import com.zsElectric.boot.system.model.entity.DictItem;
- import com.zsElectric.boot.business.model.query.StationInfoQuery;
- import com.zsElectric.boot.business.model.vo.AppletConnectorListVO;
- import com.zsElectric.boot.business.model.vo.AppletStationDetailVO;
- import com.zsElectric.boot.business.model.vo.AppletStationPriceListVO;
- import com.zsElectric.boot.business.model.vo.BannerInfoVO;
- import com.zsElectric.boot.business.model.vo.StationInfoMapVO;
- import com.zsElectric.boot.business.model.vo.StationInfoVO;
- import com.zsElectric.boot.business.model.vo.applet.AppletChargingCostVO;
- import com.zsElectric.boot.business.model.vo.applet.AppletConnectorDetailVO;
- import com.zsElectric.boot.business.model.vo.applet.AppletStationSearchVO;
- import com.zsElectric.boot.business.service.AppletHomeService;
- import com.zsElectric.boot.business.converter.BannerInfoConverter;
- import com.zsElectric.boot.security.util.SecurityUtils;
- import lombok.RequiredArgsConstructor;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.stereotype.Service;
- import java.math.BigDecimal;
- import java.math.RoundingMode;
- import java.time.LocalTime;
- import java.time.format.DateTimeFormatter;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.stream.Collectors;
- @Slf4j
- @Service
- @RequiredArgsConstructor
- public class AppletHomeServiceImpl implements AppletHomeService {
- private final ThirdPartyStationInfoMapper thirdPartyStationInfoMapper;
- private final UserFirmMapper userFirmMapper;
- private final UserAccountMapper userAccountMapper;
- private final BannerInfoMapper bannerInfoMapper;
- private final BannerInfoConverter bannerInfoConverter;
- private final ThirdPartyConnectorInfoMapper thirdPartyConnectorInfoMapper;
- private final ThirdPartyEquipmentInfoMapper thirdPartyEquipmentInfoMapper;
- private final ThirdPartyEquipmentPricePolicyMapper thirdPartyEquipmentPricePolicyMapper;
- private final ThirdPartyPolicyInfoMapper thirdPartyPolicyInfoMapper;
- private final PolicyFeeMapper policyFeeMapper;
- private final ThirdPartyChargeStatusMapper thirdPartyChargeStatusMapper;
- private final ChargeOrderInfoMapper chargeOrderInfoMapper;
- private final DiscountsActivityMapper discountsActivityMapper;
- private final DictItemMapper dictItemMapper;
- /**
- * 时间格式化器 HHmmss
- */
- private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HHmmss");
- @Override
- public IPage<StationInfoVO> getStationInfoPage(StationInfoQuery queryParams) {
-
- // 查询用户是否为企业用户,获取企业ID
- Long firmId = null;
- boolean isFirmUser = false;
- if (queryParams.getUserId() != null) {
- UserFirm userFirm = userFirmMapper.selectOne(
- new LambdaQueryWrapper<UserFirm>()
- .eq(UserFirm::getUserId, queryParams.getUserId())
- .last("LIMIT 1")
- );
- if (userFirm != null) {
- firmId = userFirm.getFirmId();
- isFirmUser = true;
- }
- }
-
- // 获取当前时间(HHmmss格式)
- String currentTime = LocalTime.now().format(TIME_FORMATTER);
-
- // 构建分页对象
- Page<StationInfoVO> page = new Page<>(queryParams.getPageNum(), queryParams.getPageSize());
-
- // 执行查询
- IPage<StationInfoVO> resultPage = thirdPartyStationInfoMapper.selectAppletStationInfoPage(
- page, queryParams, currentTime, firmId
- );
-
- // 设置是否企业用户标识
- // 只有当用户属于企业且企业有设置价格时,才标记为企业用户
- final boolean finalIsFirmUser = isFirmUser;
- resultPage.getRecords().forEach(vo -> {
- // 如果是企业用户但企业价为null,说明该企业未设置价格,firmUser应为false
- boolean hasFirmPrice = vo.getEnterprisePrice() != null;
- vo.setFirmUser(finalIsFirmUser && hasFirmPrice);
- });
-
- return resultPage;
- }
- @Override
- public List<StationInfoMapVO> getStationInfoMapList(BigDecimal longitude, BigDecimal latitude) {
- // 获取当前时间(HHmmss格式)
- String currentTime = LocalTime.now().format(TIME_FORMATTER);
-
- // 查询站点列表(按距离排序)
- return thirdPartyStationInfoMapper.selectStationMapList(
- longitude, latitude, currentTime
- );
- }
- @Override
- public List<BannerInfoVO> getBannerList(Integer location) {
- // 查询启用状态的Banner,按排序字段降序
- List<BannerInfo> bannerList = bannerInfoMapper.selectList(
- new LambdaQueryWrapper<BannerInfo>()
- .eq(BannerInfo::getStatus, 1)
- .eq(BannerInfo::getLocation, location)
- .orderByDesc(BannerInfo::getSort)
- );
- return bannerInfoConverter.toVO(bannerList);
- }
- @Override
- public AppletStationDetailVO getStationDetail(Long stationId, BigDecimal longitude, BigDecimal latitude) {
- // 获取当前登录用户ID
- Long userId = SecurityUtils.getUserId();
-
- // 查询用户是否为企业用户,获取企业ID
- Long firmId = null;
- boolean isFirmUser = false;
- if (userId != null) {
- UserFirm userFirm = userFirmMapper.selectOne(
- new LambdaQueryWrapper<UserFirm>()
- .eq(UserFirm::getUserId, userId)
- .last("LIMIT 1")
- );
- if (userFirm != null) {
- firmId = userFirm.getFirmId();
- isFirmUser = true;
- }
- }
-
- // 获取当前时间(HHmmss格式)
- String currentTime = LocalTime.now().format(TIME_FORMATTER);
-
- // 查询站点详情基本信息
- AppletStationDetailVO result = thirdPartyStationInfoMapper.selectStationDetail(
- stationId, longitude, latitude, currentTime, firmId
- );
-
- if (result == null) {
- return null;
- }
-
- // 设置是否企业用户
- result.setFirmUser(isFirmUser);
-
- // 计算预计省多少(当前价 - 原价,如果为负则取绝对值)
- if (result.getCurrentPrice() != null && result.getOriginalPrice() != null) {
- BigDecimal saving = result.getOriginalPrice().subtract(result.getCurrentPrice());
- result.setEstimatedSaving(saving.compareTo(BigDecimal.ZERO) > 0 ? saving : BigDecimal.ZERO);
- result.setShowSpecialPriceTag(saving.compareTo(BigDecimal.ZERO) > 0);
- }
-
- // 查询站点对应的stationId
- ThirdPartyStationInfo stationInfo = thirdPartyStationInfoMapper.selectById(stationId);
- if (stationInfo == null) {
- return result;
- }
-
- // 根据站点stationId查询设备列表(third_party_equipment_info)
- List<ThirdPartyEquipmentInfo> equipmentList = thirdPartyEquipmentInfoMapper.selectList(
- new LambdaQueryWrapper<ThirdPartyEquipmentInfo>()
- .eq(ThirdPartyEquipmentInfo::getStationId, stationInfo.getStationId())
- );
-
- // 构建设备ID到设备类型的映射
- Map<String, Integer> equipmentTypeMap = equipmentList.stream()
- .collect(Collectors.toMap(
- ThirdPartyEquipmentInfo::getEquipmentId,
- e -> e.getEquipmentType() != null ? e.getEquipmentType() : 0,
- (v1, v2) -> v1
- ));
-
- // 根据设备列表的equipmentId查询充电接口信息(third_party_connector_info)
- List<ThirdPartyConnectorInfo> connectorList = new ArrayList<>();
- if (!equipmentList.isEmpty()) {
- List<String> equipmentIds = equipmentList.stream()
- .map(ThirdPartyEquipmentInfo::getEquipmentId)
- .collect(Collectors.toList());
- connectorList = thirdPartyConnectorInfoMapper.selectList(
- new LambdaQueryWrapper<ThirdPartyConnectorInfo>()
- .in(ThirdPartyConnectorInfo::getEquipmentId, equipmentIds)
- );
- }
-
- // 统计终端状态
- int idleCount = 0;
- int occupiedCount = 0;
- int offlineCount = 0;
-
- List<AppletStationDetailVO.ConnectorInfoVO> connectorVOList = new ArrayList<>();
- for (ThirdPartyConnectorInfo connector : connectorList) {
- AppletStationDetailVO.ConnectorInfoVO vo = new AppletStationDetailVO.ConnectorInfoVO();
- vo.setConnectorId(connector.getId());
- vo.setConnectorName(connector.getConnectorName());
- vo.setConnectorCode(connector.getConnectorId());
-
- // 设备分类:从设备表获取设备类型(1-直流设备,2-交流设备,3-交直流一体设备,4-无线设备,5-其他)
- Integer equipmentType = equipmentTypeMap.get(connector.getEquipmentId());
- if (equipmentType != null) {
- switch (equipmentType) {
- case 1:
- vo.setEquipmentType("直流设备");
- break;
- case 2:
- vo.setEquipmentType("交流设备");
- break;
- case 3:
- vo.setEquipmentType("交直流一体设备");
- break;
- case 4:
- vo.setEquipmentType("无线设备");
- break;
- case 5:
- vo.setEquipmentType("其他");
- break;
- default:
- vo.setEquipmentType("未知");
- }
- }
-
- // 从充电接口表获取实际状态
- // 0-离网,1-空闲,2-占用(未充电),3-占用(充电中),4-占用(预约锁定),255-故障
- Integer connectorStatus = connector.getStatus();
- if (connectorStatus == null) {
- // 默认为离网
- connectorStatus = 0;
- }
- vo.setStatus(connectorStatus);
-
- // 设置状态名称并统计
- switch (connectorStatus) {
- case 0:
- vo.setStatusName("离网");
- offlineCount++;
- break;
- case 1:
- vo.setStatusName("空闲");
- idleCount++;
- break;
- case 2:
- vo.setStatusName("占用(未充电)");
- occupiedCount++;
- break;
- case 3:
- vo.setStatusName("占用(充电中)");
- occupiedCount++;
- break;
- case 4:
- vo.setStatusName("占用(预约锁定)");
- occupiedCount++;
- break;
- case 255:
- vo.setStatusName("故障");
- offlineCount++;
- break;
- default:
- vo.setStatusName("未知");
- offlineCount++;
- }
-
- connectorVOList.add(vo);
- }
-
- result.setConnectorList(connectorVOList);
- result.setIdleCount(idleCount);
- result.setOccupiedCount(occupiedCount);
- result.setOfflineCount(offlineCount);
-
- return result;
- }
- @Override
- public AppletConnectorListVO getConnectorList(Long stationId) {
- // 查询站点信息
- ThirdPartyStationInfo stationInfo = thirdPartyStationInfoMapper.selectById(stationId);
- if (stationInfo == null) {
- return null;
- }
-
- AppletConnectorListVO result = new AppletConnectorListVO();
- result.setStationId(stationId);
- result.setStationName(stationInfo.getStationName());
- result.setTips(stationInfo.getStationTips());
-
- // 根据站点stationId查询设备列表
- List<ThirdPartyEquipmentInfo> equipmentList = thirdPartyEquipmentInfoMapper.selectList(
- new LambdaQueryWrapper<ThirdPartyEquipmentInfo>()
- .eq(ThirdPartyEquipmentInfo::getStationId, stationInfo.getStationId())
- );
-
- // 构建设备ID到设备类型的映射
- Map<String, Integer> equipmentTypeMap = equipmentList.stream()
- .collect(Collectors.toMap(
- ThirdPartyEquipmentInfo::getEquipmentId,
- e -> e.getEquipmentType() != null ? e.getEquipmentType() : 0,
- (v1, v2) -> v1
- ));
-
- // 查询充电接口信息
- List<ThirdPartyConnectorInfo> connectorList = new ArrayList<>();
- if (!equipmentList.isEmpty()) {
- List<String> equipmentIds = equipmentList.stream()
- .map(ThirdPartyEquipmentInfo::getEquipmentId)
- .collect(Collectors.toList());
- connectorList = thirdPartyConnectorInfoMapper.selectList(
- new LambdaQueryWrapper<ThirdPartyConnectorInfo>()
- .in(ThirdPartyConnectorInfo::getEquipmentId, equipmentIds)
- );
- }
-
- // 统计终端状态
- int idleCount = 0;
- int occupiedCount = 0;
- int offlineCount = 0;
-
- List<AppletConnectorListVO.ConnectorItemVO> connectorVOList = new ArrayList<>();
- for (ThirdPartyConnectorInfo connector : connectorList) {
- AppletConnectorListVO.ConnectorItemVO vo = new AppletConnectorListVO.ConnectorItemVO();
- vo.setConnectorId(connector.getId());
- vo.setConnectorName(connector.getConnectorName());
- vo.setConnectorCode(connector.getConnectorId());
-
- // 设备分类
- Integer equipmentType = equipmentTypeMap.get(connector.getEquipmentId());
- vo.setEquipmentType(getEquipmentTypeName(equipmentType));
-
- // 状态处理
- Integer connectorStatus = connector.getStatus();
- if (connectorStatus == null) {
- connectorStatus = 0;
- }
- vo.setStatus(connectorStatus);
- vo.setStatusName(getStatusName(connectorStatus));
-
- // 统计
- switch (connectorStatus) {
- case 1:
- idleCount++;
- break;
- case 2:
- case 3:
- case 4:
- occupiedCount++;
- break;
- default:
- offlineCount++;
- }
-
- connectorVOList.add(vo);
- }
-
- result.setConnectorList(connectorVOList);
- result.setIdleCount(idleCount);
- result.setOccupiedCount(occupiedCount);
- result.setOfflineCount(offlineCount);
-
- return result;
- }
- @Override
- public AppletStationPriceListVO getStationPriceList(Long stationId) {
- // 查询站点信息
- ThirdPartyStationInfo stationInfo = thirdPartyStationInfoMapper.selectById(stationId);
- if (stationInfo == null) {
- log.warn("站点信息不存在,stationId: {}", stationId);
- return null;
- }
-
- log.info("查询站点价格列表,stationId: {}, stationName: {}, station_id字段: {}",
- stationId, stationInfo.getStationName(), stationInfo.getStationId());
-
- AppletStationPriceListVO result = new AppletStationPriceListVO();
- result.setStationId(stationId);
- result.setStationName(stationInfo.getStationName());
- result.setTips(stationInfo.getStationTips());
-
- // 获取当前登录用户ID
- Long userId = SecurityUtils.getUserId();
- log.info("当前用户ID: {}", userId);
-
- // 查询用户是否为企业用户,获取企业ID
- Long firmId = null;
- if (userId != null) {
- UserFirm userFirm = userFirmMapper.selectOne(
- new LambdaQueryWrapper<UserFirm>()
- .eq(UserFirm::getUserId, userId)
- .last("LIMIT 1")
- );
- if (userFirm != null) {
- firmId = userFirm.getFirmId();
- log.info("用户所属企业ID: {}", firmId);
- }
- }
-
- // 获取当前时间(HHmmss格式)
- String currentTime = LocalTime.now().format(TIME_FORMATTER);
- log.info("当前时间: {}", currentTime);
-
- // 查询站点对应的价格策略
- // 1. 先查询充电接口
- ThirdPartyConnectorInfo connector = thirdPartyConnectorInfoMapper.selectOne(
- new LambdaQueryWrapper<ThirdPartyConnectorInfo>()
- .eq(ThirdPartyConnectorInfo::getStationId, stationInfo.getStationId())
- .last("LIMIT 1")
- );
-
- if (connector == null) {
- log.warn("未找到充电接口信息,station_id: {}", stationInfo.getStationId());
- result.setPriceList(new ArrayList<>());
- return result;
- }
-
- log.info("找到充电接口,connectorId: {}", connector.getConnectorId());
-
- // 2. 查询价格策略
- ThirdPartyEquipmentPricePolicy pricePolicy = thirdPartyEquipmentPricePolicyMapper.selectOne(
- new LambdaQueryWrapper<ThirdPartyEquipmentPricePolicy>()
- .eq(ThirdPartyEquipmentPricePolicy::getConnectorId, connector.getConnectorId())
- .eq(ThirdPartyEquipmentPricePolicy::getIsDeleted, 0)
- .last("LIMIT 1")
- );
-
- if (pricePolicy == null) {
- log.warn("未找到价格策略,connectorId: {}", connector.getConnectorId());
- result.setPriceList(new ArrayList<>());
- return result;
- }
-
- log.info("找到价格策略,pricePolicyId: {}", pricePolicy.getId());
-
- // 3. 查询价格明细列表
- List<ThirdPartyPolicyInfo> policyInfoList = thirdPartyPolicyInfoMapper.selectList(
- new LambdaQueryWrapper<ThirdPartyPolicyInfo>()
- .eq(ThirdPartyPolicyInfo::getPricePolicyId, pricePolicy.getId())
- .eq(ThirdPartyPolicyInfo::getIsDeleted, 0)
- .orderByAsc(ThirdPartyPolicyInfo::getStartTime)
- );
-
- log.info("查询到价格明细记录数: {}", policyInfoList.size());
-
- // 如果没有查询到价格策略明细,说明该站点未配置价格策略,直接返回空列表
- if (policyInfoList.isEmpty()) {
- log.warn("third_party_policy_info表中没有价格策略数据,pricePolicyId: {}", pricePolicy.getId());
- result.setPriceList(new ArrayList<>());
- result.setHasEnterprisePrice(false);
- return result;
- }
-
- // 4. 如果是企业用户,查询企业价格
- Map<String, BigDecimal> enterprisePriceMap = new HashMap<>();
- boolean hasEnterprisePrice = false;
- if (firmId != null) {
- List<PolicyFee> policyFeeList = policyFeeMapper.selectList(
- new LambdaQueryWrapper<PolicyFee>()
- .eq(PolicyFee::getStationInfoId, stationId)
- .eq(PolicyFee::getSalesType, 1) // 1-企业
- .eq(PolicyFee::getFirmId, firmId)
- .eq(PolicyFee::getIsDeleted, 0)
- );
-
- log.info("查询企业价格记录数: {}, stationInfoId: {}, firmId: {}",
- policyFeeList.size(), stationId, firmId);
-
- // 如果查询到企业价格记录,设置标志为true
- if (!policyFeeList.isEmpty()) {
- hasEnterprisePrice = true;
- }
-
- // 构建企业价格映射 (startTime -> enterprisePrice)
- for (PolicyFee policyFee : policyFeeList) {
- // 查找对应的时段价格信息
- ThirdPartyPolicyInfo matchedPolicyInfo = policyInfoList.stream()
- .filter(info -> info.getStartTime().equals(policyFee.getStartTime()))
- .findFirst()
- .orElse(null);
-
- if (matchedPolicyInfo != null) {
- // 企业价格 = 电费 + 服务费 + 运营费 + 综合销售费
- BigDecimal elecPrice = matchedPolicyInfo.getElecPrice() != null ? matchedPolicyInfo.getElecPrice() : BigDecimal.ZERO;
- BigDecimal servicePrice = matchedPolicyInfo.getServicePrice() != null ? matchedPolicyInfo.getServicePrice() : BigDecimal.ZERO;
- BigDecimal opFee = policyFee.getOpFee() != null ? policyFee.getOpFee() : BigDecimal.ZERO;
- BigDecimal compSalesFee = policyFee.getCompSalesFee() != null ? policyFee.getCompSalesFee() : BigDecimal.ZERO;
-
- BigDecimal enterprisePrice = elecPrice.add(servicePrice).add(opFee).add(compSalesFee);
- enterprisePriceMap.put(policyFee.getStartTime(), enterprisePrice);
- log.debug("企业价格计算 - 时段: {}, 电费: {}, 服务费: {}, 运营费: {}, 综合销售费: {}, 企业价: {}",
- policyFee.getStartTime(), elecPrice, servicePrice, opFee, compSalesFee, enterprisePrice);
- } else {
- log.warn("未找到匹配的价格策略明细,startTime: {}", policyFee.getStartTime());
- }
- }
- }
-
- // 设置是否有企业价格
- result.setHasEnterprisePrice(hasEnterprisePrice);
- log.info("是否有企业价格: {}", hasEnterprisePrice);
-
- // 5. 构建价格列表
- List<AppletStationPriceListVO.PriceItemVO> priceList = new ArrayList<>();
- for (int i = 0; i < policyInfoList.size(); i++) {
- ThirdPartyPolicyInfo policyInfo = policyInfoList.get(i);
- AppletStationPriceListVO.PriceItemVO priceItem = new AppletStationPriceListVO.PriceItemVO();
-
- // 时段格式化:HHmmss -> HH:mm
- String startTime = formatTime(policyInfo.getStartTime());
- // 下一个时段的开始时间作为当前时段的结束时间
- String endTime = (i + 1 < policyInfoList.size())
- ? formatTime(policyInfoList.get(i + 1).getStartTime())
- : "24:00";
- priceItem.setTimePeriod(startTime + "-" + endTime);
-
- priceItem.setPeriodFlag(policyInfo.getPeriodFlag());
- priceItem.setPeriodFlagName(getPeriodFlagName(policyInfo.getPeriodFlag()));
- priceItem.setElecPrice(policyInfo.getElecPrice());
- priceItem.setServicePrice(policyInfo.getServicePrice());
-
- // 合计充电价 = 电费 + 服务费
- BigDecimal elecPrice = policyInfo.getElecPrice() != null ? policyInfo.getElecPrice() : BigDecimal.ZERO;
- BigDecimal servicePrice = policyInfo.getServicePrice() != null ? policyInfo.getServicePrice() : BigDecimal.ZERO;
- priceItem.setTotalPrice(elecPrice.add(servicePrice));
-
- // 设置企业价格(如果有)
- BigDecimal enterprisePrice = enterprisePriceMap.get(policyInfo.getStartTime());
- priceItem.setEnterprisePrice(enterprisePrice);
-
- // 判断是否为当前时段
- priceItem.setCurrentPeriod(isCurrentPeriod(policyInfo.getStartTime(),
- (i + 1 < policyInfoList.size()) ? policyInfoList.get(i + 1).getStartTime() : null,
- currentTime));
-
- priceList.add(priceItem);
- }
-
- result.setPriceList(priceList);
- return result;
- }
-
- /**
- * 获取设备类型名称
- */
- private String getEquipmentTypeName(Integer equipmentType) {
- if (equipmentType == null) {
- return "未知";
- }
- switch (equipmentType) {
- case 1:
- return "直流设备";
- case 2:
- return "交流设备";
- case 3:
- return "交直流一体设备";
- case 4:
- return "无线设备";
- case 5:
- return "其他";
- default:
- return "未知";
- }
- }
-
- /**
- * 获取状态名称
- */
- private String getStatusName(Integer status) {
- if (status == null) {
- return "未知";
- }
- switch (status) {
- case 0:
- return "离网";
- case 1:
- return "空闲";
- case 2:
- return "占用(未充电)";
- case 3:
- return "占用(充电中)";
- case 4:
- return "占用(预约锁定)";
- case 255:
- return "故障";
- default:
- return "未知";
- }
- }
-
- /**
- * 获取时段标志名称
- */
- private String getPeriodFlagName(Integer periodFlag) {
- if (periodFlag == null) {
- return "";
- }
- switch (periodFlag) {
- case 1:
- return "尖";
- case 2:
- return "峰";
- case 3:
- return "平";
- case 4:
- return "谷";
- default:
- return "";
- }
- }
-
- /**
- * 格式化时间 HHmmss -> HH:mm
- */
- private String formatTime(String time) {
- if (time == null || time.length() < 4) {
- return "00:00";
- }
- return time.substring(0, 2) + ":" + time.substring(2, 4);
- }
-
- /**
- * 判断是否为当前时段
- */
- private boolean isCurrentPeriod(String startTime, String nextStartTime, String currentTime) {
- if (startTime == null || currentTime == null) {
- return false;
- }
- // 当前时间 >= 开始时间 且 当前时间 < 下一个时段开始时间
- if (currentTime.compareTo(startTime) >= 0) {
- if (nextStartTime == null || currentTime.compareTo(nextStartTime) < 0) {
- return true;
- }
- }
- return false;
- }
- @Override
- public AppletChargingCostVO getCurrentChargingCost() {
- // 获取当前登录用户ID
- Long userId = SecurityUtils.getUserId();
- if (userId == null) {
- return null;
- }
- return thirdPartyStationInfoMapper.selectCurrentChargingCost(userId);
- }
- @Override
- public List<AppletStationSearchVO> searchStations(String keyword, BigDecimal longitude, BigDecimal latitude) {
- // 关键词为空或空字符串,返回空列表
- if (keyword == null || keyword.trim().isEmpty()) {
- return new ArrayList<>();
- }
- // 调用Mapper查询
- return thirdPartyStationInfoMapper.searchStations(keyword.trim(), longitude, latitude);
- }
- @Override
- public AppletConnectorDetailVO getConnectorDetail(Long connectorId) {
- // 获取当前登录用户ID
- Long userId = SecurityUtils.getUserId();
-
- // 获取当前时间(HHmmss格式)
- String currentTime = LocalTime.now().format(TIME_FORMATTER);
-
- // 查询用户余额
- BigDecimal userBalance = null;
- if (userId != null) {
- UserAccount userAccount = userAccountMapper.selectOne(
- new LambdaQueryWrapper<UserAccount>()
- .eq(UserAccount::getUserId, userId)
- .eq(UserAccount::getIsDeleted, 0)
- );
- if (userAccount != null) {
- userBalance = userAccount.getBalance();
- }
- }
-
- // 查询新用户优惠金额(仅当用户为新用户时)
- BigDecimal newUserDiscount = null;
- if (userId != null) {
- // 检查用户是否有充电订单
- Long orderCount = chargeOrderInfoMapper.selectCount(
- new LambdaQueryWrapper<ChargeOrderInfo>()
- .eq(ChargeOrderInfo::getUserId, userId)
- .eq(ChargeOrderInfo::getIsDeleted, 0)
- );
-
- // 如果是新用户(没有订单),查询新用户首单优惠金额
- if (orderCount == 0) {
- // 查询c_discounts_activity表,type=1(新用户首单立减)且status=1(启用)的数据
- List<DiscountsActivity> discountActivities = discountsActivityMapper.selectList(
- new LambdaQueryWrapper<DiscountsActivity>()
- .eq(DiscountsActivity::getType, 1) // 1-新用户首单立减
- .eq(DiscountsActivity::getStatus, 1) // 1-启用
- .eq(DiscountsActivity::getIsDeleted, 0)
- );
-
- // 计算所有启用的新用户优惠金额总和
- if (!discountActivities.isEmpty()) {
- newUserDiscount = discountActivities.stream()
- .map(DiscountsActivity::getDiscount)
- .filter(discount -> discount != null)
- .reduce(BigDecimal.ZERO, BigDecimal::add);
-
- log.info("新用户首单优惠金额 - userId: {}, discount: {}", userId, newUserDiscount);
- }
- }
- }
-
- // 调用Mapper方法,一次SQL查询获取所有信息
- AppletConnectorDetailVO result = thirdPartyConnectorInfoMapper.selectConnectorDetailById(
- connectorId, userId, currentTime, userBalance, newUserDiscount
- );
-
- if (result == null) {
- log.warn("充电接口不存在,connectorId: {}", connectorId);
- }
-
- return result;
- }
- @Override
- public BigDecimal calculateAvailableChargingAmount(Long connectorId) {
- // 获取当前登录用户ID
- Long userId = SecurityUtils.getUserId();
- if (userId == null) {
- log.warn("未登录用户,无法计算可用充电金额");
- return BigDecimal.ZERO;
- }
-
- // 1. 查询当前用户余额
- UserAccount userAccount = userAccountMapper.selectOne(
- new LambdaQueryWrapper<UserAccount>()
- .eq(UserAccount::getUserId, userId)
- .eq(UserAccount::getIsDeleted, 0)
- );
- if (userAccount == null || userAccount.getBalance() == null) {
- log.warn("用户账户不存在或余额为空 - userId: {}", userId);
- return BigDecimal.ZERO;
- }
- BigDecimal userBalance = userAccount.getBalance();
-
- // 2. 从字典表查询安全价(safety_fee)
- DictItem safetyFeeItem = dictItemMapper.selectOne(
- new LambdaQueryWrapper<DictItem>()
- .eq(DictItem::getDictCode, "safety_fee")
- .eq(DictItem::getStatus, 1)
- .last("LIMIT 1")
- );
- BigDecimal safetyFee = safetyFeeItem != null && safetyFeeItem.getValue() != null
- ? new BigDecimal(safetyFeeItem.getValue())
- : BigDecimal.ZERO;
-
- // 计算扣除安全价后的余额
- BigDecimal balanceAfterSafety = userBalance.subtract(safetyFee);
- if (balanceAfterSafety.compareTo(BigDecimal.ZERO) <= 0) {
- log.info("用户余额不足 - userId: {}, balance: {}, safetyFee: {}", userId, userBalance, safetyFee);
- return BigDecimal.ZERO;
- }
-
- // 3. 查询充电接口、设备、站点信息
- ThirdPartyConnectorInfo connectorInfo = thirdPartyConnectorInfoMapper.selectById(connectorId);
- if (connectorInfo == null) {
- log.warn("充电接口不存在 - connectorId: {}", connectorId);
- return BigDecimal.ZERO;
- }
-
- ThirdPartyEquipmentInfo equipmentInfo = thirdPartyEquipmentInfoMapper.selectOne(
- new LambdaQueryWrapper<ThirdPartyEquipmentInfo>()
- .eq(ThirdPartyEquipmentInfo::getEquipmentId, connectorInfo.getEquipmentId())
- .eq(ThirdPartyEquipmentInfo::getIsDeleted, 0)
- .last("LIMIT 1")
- );
- if (equipmentInfo == null) {
- log.warn("设备信息不存在 - equipmentId: {}", connectorInfo.getEquipmentId());
- return BigDecimal.ZERO;
- }
-
- ThirdPartyStationInfo stationInfo = thirdPartyStationInfoMapper.selectOne(
- new LambdaQueryWrapper<ThirdPartyStationInfo>()
- .eq(ThirdPartyStationInfo::getStationId, equipmentInfo.getStationId())
- .eq(ThirdPartyStationInfo::getIsDeleted, 0)
- .last("LIMIT 1")
- );
- if (stationInfo == null) {
- log.warn("站点信息不存在 - stationId: {}", equipmentInfo.getStationId());
- return BigDecimal.ZERO;
- }
-
- // 4. 查询价格策略
- ThirdPartyEquipmentPricePolicy pricePolicy = thirdPartyEquipmentPricePolicyMapper.selectOne(
- new LambdaQueryWrapper<ThirdPartyEquipmentPricePolicy>()
- .eq(ThirdPartyEquipmentPricePolicy::getConnectorId, connectorInfo.getConnectorId())
- .eq(ThirdPartyEquipmentPricePolicy::getIsDeleted, 0)
- .last("LIMIT 1")
- );
- if (pricePolicy == null) {
- log.warn("价格策略不存在 - connectorId: {}", connectorInfo.getConnectorId());
- return BigDecimal.ZERO;
- }
-
- // 5. 查询所有时段的价格信息(按开始时间排序)
- List<ThirdPartyPolicyInfo> policyInfoList = thirdPartyPolicyInfoMapper.selectList(
- new LambdaQueryWrapper<ThirdPartyPolicyInfo>()
- .eq(ThirdPartyPolicyInfo::getPricePolicyId, pricePolicy.getId())
- .eq(ThirdPartyPolicyInfo::getIsDeleted, 0)
- .orderByAsc(ThirdPartyPolicyInfo::getStartTime)
- );
- if (policyInfoList.isEmpty()) {
- log.warn("价格策略明细不存在 - pricePolicyId: {}", pricePolicy.getId());
- return BigDecimal.ZERO;
- }
-
- // 6. 查询用户是否为企业用户
- UserFirm userFirm = userFirmMapper.selectOne(
- new LambdaQueryWrapper<UserFirm>()
- .eq(UserFirm::getUserId, userId)
- .eq(UserFirm::getIsDeleted, 0)
- .last("LIMIT 1")
- );
-
- // 7. 跨时段计算可用充电金额
- // 公式:可用余额 = 当前用户余额 - 安全价 - [(度数 × 运营费) + (度数 × 增值费用)]
- // 其中:度数 = (余额 - 安全价) / (电费 + 服务费)
-
- BigDecimal remainingBalance = balanceAfterSafety; // 剩余可用余额(用于计算度数)
- BigDecimal totalOpFeeCost = BigDecimal.ZERO; // 总运营费
- BigDecimal totalValueAddedCost = BigDecimal.ZERO; // 总增值费用
-
- // 遍历每个时段,计算在该时段能充多少度电及对应的费用
- for (ThirdPartyPolicyInfo policyInfo : policyInfoList) {
- // 获取电费、服务费
- BigDecimal elecPrice = policyInfo.getElecPrice() != null ? policyInfo.getElecPrice() : BigDecimal.ZERO;
- BigDecimal servicePrice = policyInfo.getServicePrice() != null ? policyInfo.getServicePrice() : BigDecimal.ZERO;
- BigDecimal basePrice = elecPrice.add(servicePrice); // 基础价格 = 电费 + 服务费
-
- if (basePrice.compareTo(BigDecimal.ZERO) == 0) {
- continue; // 跳过基础价格为0的时段
- }
-
- // 查询该时段的运营费
- PolicyFee policyFee;
- if (userFirm != null) {
- policyFee = policyFeeMapper.selectOne(
- new LambdaQueryWrapper<PolicyFee>()
- .eq(PolicyFee::getStationInfoId, stationInfo.getId())
- .eq(PolicyFee::getStartTime, policyInfo.getStartTime())
- .eq(PolicyFee::getSalesType, 1)
- .eq(PolicyFee::getFirmId, userFirm.getFirmId())
- .eq(PolicyFee::getIsDeleted, 0)
- .last("LIMIT 1")
- );
- } else {
- policyFee = policyFeeMapper.selectOne(
- new LambdaQueryWrapper<PolicyFee>()
- .eq(PolicyFee::getStationInfoId, stationInfo.getId())
- .eq(PolicyFee::getStartTime, policyInfo.getStartTime())
- .eq(PolicyFee::getSalesType, 0)
- .eq(PolicyFee::getIsDeleted, 0)
- .last("LIMIT 1")
- );
- }
-
- BigDecimal opFee = (policyFee != null && policyFee.getOpFee() != null)
- ? policyFee.getOpFee()
- : BigDecimal.ZERO;
-
- // 查询增值费用
- BigDecimal valueAddedFee = BigDecimal.ZERO;
- if (policyInfo.getPeriodFlag() != null) {
- String periodLabel = "";
- switch (policyInfo.getPeriodFlag()) {
- case 1: periodLabel = "尖"; break;
- case 2: periodLabel = "峰"; break;
- case 3: periodLabel = "平"; break;
- case 4: periodLabel = "谷"; break;
- }
-
- if (!periodLabel.isEmpty()) {
- DictItem valueAddedItem = dictItemMapper.selectOne(
- new LambdaQueryWrapper<DictItem>()
- .eq(DictItem::getDictCode, "time_period_flag")
- .eq(DictItem::getLabel, periodLabel)
- .eq(DictItem::getStatus, 1)
- .last("LIMIT 1")
- );
- if (valueAddedItem != null && valueAddedItem.getValue() != null) {
- valueAddedFee = new BigDecimal(valueAddedItem.getValue());
- }
- }
- }
-
- // 计算在当前时段能充多少度电(使用剩余余额)
- // 度数 = 剩余余额 / (电费 + 服务费)
- BigDecimal kwh = remainingBalance.divide(basePrice, 4, RoundingMode.HALF_UP);
-
- // 如果剩余余额不足以充电,结束计算
- if (kwh.compareTo(BigDecimal.ZERO) <= 0) {
- break;
- }
-
- // 计算该时段的运营费和增值费用
- BigDecimal periodOpFeeCost = kwh.multiply(opFee);
- BigDecimal periodValueAddedCost = kwh.multiply(valueAddedFee);
-
- totalOpFeeCost = totalOpFeeCost.add(periodOpFeeCost);
- totalValueAddedCost = totalValueAddedCost.add(periodValueAddedCost);
-
- // 更新剩余余额(减去当前时段的所有费用)
- // 当前时段总费用 = (电费 + 服务费) * 度数 + 运营费 + 增值费用
- BigDecimal periodBaseCost = kwh.multiply(basePrice);
- BigDecimal periodTotalCost = periodBaseCost.add(periodOpFeeCost).add(periodValueAddedCost);
- remainingBalance = remainingBalance.subtract(periodTotalCost);
-
- log.debug("时段计算 - startTime: {}, 电费: {}, 服务费: {}, 运营费: {}, 增值费: {}, 度数: {}, 该时段费用: {}, 剩余余额: {}",
- policyInfo.getStartTime(), elecPrice, servicePrice, opFee, valueAddedFee, kwh, periodTotalCost, remainingBalance);
-
- // 如果剩余余额小于等于0,结束计算
- if (remainingBalance.compareTo(BigDecimal.ZERO) <= 0) {
- break;
- }
- }
-
- // 8. 计算最终可用余额
- BigDecimal availableAmount = userBalance.subtract(safetyFee).subtract(totalOpFeeCost).subtract(totalValueAddedCost);
-
- // 确保不为负数
- if (availableAmount.compareTo(BigDecimal.ZERO) < 0) {
- availableAmount = BigDecimal.ZERO;
- }
-
- // 保留 2 位小数
- availableAmount = availableAmount.setScale(2, RoundingMode.HALF_UP);
-
- log.info("可用充电金额计算完成 - userId: {}, connectorId: {}, userBalance: {}, safetyFee: {}, " +
- "totalOpFeeCost: {}, totalValueAddedCost: {}, availableAmount: {}",
- userId, connectorId, userBalance, safetyFee, totalOpFeeCost, totalValueAddedCost, availableAmount);
-
- return availableAmount;
- }
- }
|