AppletHomeServiceImpl.java 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  1. package com.zsElectric.boot.business.service.impl;
  2. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  3. import com.baomidou.mybatisplus.core.metadata.IPage;
  4. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  5. import com.zsElectric.boot.business.mapper.BannerInfoMapper;
  6. import com.zsElectric.boot.business.mapper.PolicyFeeMapper;
  7. import com.zsElectric.boot.business.mapper.ThirdPartyStationInfoMapper;
  8. import com.zsElectric.boot.business.mapper.UserFirmMapper;
  9. import com.zsElectric.boot.charging.entity.ThirdPartyChargeStatus;
  10. import com.zsElectric.boot.charging.entity.ThirdPartyConnectorInfo;
  11. import com.zsElectric.boot.charging.entity.ThirdPartyEquipmentInfo;
  12. import com.zsElectric.boot.charging.mapper.ThirdPartyChargeStatusMapper;
  13. import com.zsElectric.boot.charging.mapper.ThirdPartyConnectorInfoMapper;
  14. import com.zsElectric.boot.charging.entity.ThirdPartyEquipmentPricePolicy;
  15. import com.zsElectric.boot.charging.entity.ThirdPartyPolicyInfo;
  16. import com.zsElectric.boot.charging.entity.ThirdPartyStationInfo;
  17. import com.zsElectric.boot.business.mapper.ThirdPartyEquipmentInfoMapper;
  18. import com.zsElectric.boot.charging.mapper.ThirdPartyEquipmentPricePolicyMapper;
  19. import com.zsElectric.boot.charging.mapper.ThirdPartyPolicyInfoMapper;
  20. import com.zsElectric.boot.business.model.entity.BannerInfo;
  21. import com.zsElectric.boot.business.model.entity.PolicyFee;
  22. import com.zsElectric.boot.business.model.entity.UserFirm;
  23. import com.zsElectric.boot.business.model.query.StationInfoQuery;
  24. import com.zsElectric.boot.business.model.vo.AppletConnectorListVO;
  25. import com.zsElectric.boot.business.model.vo.AppletStationDetailVO;
  26. import com.zsElectric.boot.business.model.vo.AppletStationPriceListVO;
  27. import com.zsElectric.boot.business.model.vo.BannerInfoVO;
  28. import com.zsElectric.boot.business.model.vo.StationInfoMapVO;
  29. import com.zsElectric.boot.business.model.vo.StationInfoVO;
  30. import com.zsElectric.boot.business.model.vo.applet.AppletChargingCostVO;
  31. import com.zsElectric.boot.business.model.vo.applet.AppletStationSearchVO;
  32. import com.zsElectric.boot.business.service.AppletHomeService;
  33. import com.zsElectric.boot.business.converter.BannerInfoConverter;
  34. import com.zsElectric.boot.security.util.SecurityUtils;
  35. import lombok.RequiredArgsConstructor;
  36. import lombok.extern.slf4j.Slf4j;
  37. import org.springframework.stereotype.Service;
  38. import java.math.BigDecimal;
  39. import java.time.LocalTime;
  40. import java.time.format.DateTimeFormatter;
  41. import java.util.ArrayList;
  42. import java.util.HashMap;
  43. import java.util.List;
  44. import java.util.Map;
  45. import java.util.stream.Collectors;
  46. @Slf4j
  47. @Service
  48. @RequiredArgsConstructor
  49. public class AppletHomeServiceImpl implements AppletHomeService {
  50. private final ThirdPartyStationInfoMapper thirdPartyStationInfoMapper;
  51. private final UserFirmMapper userFirmMapper;
  52. private final BannerInfoMapper bannerInfoMapper;
  53. private final BannerInfoConverter bannerInfoConverter;
  54. private final ThirdPartyConnectorInfoMapper thirdPartyConnectorInfoMapper;
  55. private final ThirdPartyEquipmentInfoMapper thirdPartyEquipmentInfoMapper;
  56. private final ThirdPartyEquipmentPricePolicyMapper thirdPartyEquipmentPricePolicyMapper;
  57. private final ThirdPartyPolicyInfoMapper thirdPartyPolicyInfoMapper;
  58. private final PolicyFeeMapper policyFeeMapper;
  59. private final ThirdPartyChargeStatusMapper thirdPartyChargeStatusMapper;
  60. /**
  61. * 时间格式化器 HHmmss
  62. */
  63. private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HHmmss");
  64. @Override
  65. public IPage<StationInfoVO> getStationInfoPage(StationInfoQuery queryParams) {
  66. // 查询用户是否为企业用户,获取企业ID
  67. Long firmId = null;
  68. boolean isFirmUser = false;
  69. if (queryParams.getUserId() != null) {
  70. UserFirm userFirm = userFirmMapper.selectOne(
  71. new LambdaQueryWrapper<UserFirm>()
  72. .eq(UserFirm::getUserId, queryParams.getUserId())
  73. .last("LIMIT 1")
  74. );
  75. if (userFirm != null) {
  76. firmId = userFirm.getFirmId();
  77. isFirmUser = true;
  78. }
  79. }
  80. // 获取当前时间(HHmmss格式)
  81. String currentTime = LocalTime.now().format(TIME_FORMATTER);
  82. // 构建分页对象
  83. Page<StationInfoVO> page = new Page<>(queryParams.getPageNum(), queryParams.getPageSize());
  84. // 执行查询
  85. IPage<StationInfoVO> resultPage = thirdPartyStationInfoMapper.selectAppletStationInfoPage(
  86. page, queryParams, currentTime, firmId
  87. );
  88. // 设置是否企业用户标识
  89. // 只有当用户属于企业且企业有设置价格时,才标记为企业用户
  90. final boolean finalIsFirmUser = isFirmUser;
  91. resultPage.getRecords().forEach(vo -> {
  92. // 如果是企业用户但企业价为null,说明该企业未设置价格,firmUser应为false
  93. boolean hasFirmPrice = vo.getEnterprisePrice() != null;
  94. vo.setFirmUser(finalIsFirmUser && hasFirmPrice);
  95. });
  96. return resultPage;
  97. }
  98. @Override
  99. public List<StationInfoMapVO> getStationInfoMapList(BigDecimal longitude, BigDecimal latitude) {
  100. // 获取当前时间(HHmmss格式)
  101. String currentTime = LocalTime.now().format(TIME_FORMATTER);
  102. // 查询站点列表(按距离排序)
  103. return thirdPartyStationInfoMapper.selectStationMapList(
  104. longitude, latitude, currentTime
  105. );
  106. }
  107. @Override
  108. public List<BannerInfoVO> getBannerList(Integer location) {
  109. // 查询启用状态的Banner,按排序字段降序
  110. List<BannerInfo> bannerList = bannerInfoMapper.selectList(
  111. new LambdaQueryWrapper<BannerInfo>()
  112. .eq(BannerInfo::getStatus, 1)
  113. .eq(BannerInfo::getLocation, location)
  114. .orderByDesc(BannerInfo::getSort)
  115. );
  116. return bannerInfoConverter.toVO(bannerList);
  117. }
  118. @Override
  119. public AppletStationDetailVO getStationDetail(Long stationId, BigDecimal longitude, BigDecimal latitude) {
  120. // 获取当前登录用户ID
  121. Long userId = SecurityUtils.getUserId();
  122. // 查询用户是否为企业用户,获取企业ID
  123. Long firmId = null;
  124. boolean isFirmUser = false;
  125. if (userId != null) {
  126. UserFirm userFirm = userFirmMapper.selectOne(
  127. new LambdaQueryWrapper<UserFirm>()
  128. .eq(UserFirm::getUserId, userId)
  129. .last("LIMIT 1")
  130. );
  131. if (userFirm != null) {
  132. firmId = userFirm.getFirmId();
  133. isFirmUser = true;
  134. }
  135. }
  136. // 获取当前时间(HHmmss格式)
  137. String currentTime = LocalTime.now().format(TIME_FORMATTER);
  138. // 查询站点详情基本信息
  139. AppletStationDetailVO result = thirdPartyStationInfoMapper.selectStationDetail(
  140. stationId, longitude, latitude, currentTime, firmId
  141. );
  142. if (result == null) {
  143. return null;
  144. }
  145. // 设置是否企业用户
  146. result.setFirmUser(isFirmUser);
  147. // 计算预计省多少(当前价 - 原价,如果为负则取绝对值)
  148. if (result.getCurrentPrice() != null && result.getOriginalPrice() != null) {
  149. BigDecimal saving = result.getOriginalPrice().subtract(result.getCurrentPrice());
  150. result.setEstimatedSaving(saving.compareTo(BigDecimal.ZERO) > 0 ? saving : BigDecimal.ZERO);
  151. result.setShowSpecialPriceTag(saving.compareTo(BigDecimal.ZERO) > 0);
  152. }
  153. // 查询站点对应的stationId
  154. ThirdPartyStationInfo stationInfo = thirdPartyStationInfoMapper.selectById(stationId);
  155. if (stationInfo == null) {
  156. return result;
  157. }
  158. // 根据站点stationId查询设备列表(third_party_equipment_info)
  159. List<ThirdPartyEquipmentInfo> equipmentList = thirdPartyEquipmentInfoMapper.selectList(
  160. new LambdaQueryWrapper<ThirdPartyEquipmentInfo>()
  161. .eq(ThirdPartyEquipmentInfo::getStationId, stationInfo.getStationId())
  162. );
  163. // 构建设备ID到设备类型的映射
  164. Map<String, Integer> equipmentTypeMap = equipmentList.stream()
  165. .collect(Collectors.toMap(
  166. ThirdPartyEquipmentInfo::getEquipmentId,
  167. e -> e.getEquipmentType() != null ? e.getEquipmentType() : 0,
  168. (v1, v2) -> v1
  169. ));
  170. // 根据设备列表的equipmentId查询充电接口信息(third_party_connector_info)
  171. List<ThirdPartyConnectorInfo> connectorList = new ArrayList<>();
  172. if (!equipmentList.isEmpty()) {
  173. List<String> equipmentIds = equipmentList.stream()
  174. .map(ThirdPartyEquipmentInfo::getEquipmentId)
  175. .collect(Collectors.toList());
  176. connectorList = thirdPartyConnectorInfoMapper.selectList(
  177. new LambdaQueryWrapper<ThirdPartyConnectorInfo>()
  178. .in(ThirdPartyConnectorInfo::getEquipmentId, equipmentIds)
  179. );
  180. }
  181. // 统计终端状态
  182. int idleCount = 0;
  183. int occupiedCount = 0;
  184. int offlineCount = 0;
  185. List<AppletStationDetailVO.ConnectorInfoVO> connectorVOList = new ArrayList<>();
  186. for (ThirdPartyConnectorInfo connector : connectorList) {
  187. AppletStationDetailVO.ConnectorInfoVO vo = new AppletStationDetailVO.ConnectorInfoVO();
  188. vo.setConnectorId(connector.getId());
  189. vo.setConnectorName(connector.getConnectorName());
  190. vo.setConnectorCode(connector.getConnectorId());
  191. // 设备分类:从设备表获取设备类型(1-直流设备,2-交流设备,3-交直流一体设备,4-无线设备,5-其他)
  192. Integer equipmentType = equipmentTypeMap.get(connector.getEquipmentId());
  193. if (equipmentType != null) {
  194. switch (equipmentType) {
  195. case 1:
  196. vo.setEquipmentType("直流设备");
  197. break;
  198. case 2:
  199. vo.setEquipmentType("交流设备");
  200. break;
  201. case 3:
  202. vo.setEquipmentType("交直流一体设备");
  203. break;
  204. case 4:
  205. vo.setEquipmentType("无线设备");
  206. break;
  207. case 5:
  208. vo.setEquipmentType("其他");
  209. break;
  210. default:
  211. vo.setEquipmentType("未知");
  212. }
  213. }
  214. // 从充电接口表获取实际状态
  215. // 0-离网,1-空闲,2-占用(未充电),3-占用(充电中),4-占用(预约锁定),255-故障
  216. Integer connectorStatus = connector.getStatus();
  217. if (connectorStatus == null) {
  218. // 默认为离网
  219. connectorStatus = 0;
  220. }
  221. vo.setStatus(connectorStatus);
  222. // 设置状态名称并统计
  223. switch (connectorStatus) {
  224. case 0:
  225. vo.setStatusName("离网");
  226. offlineCount++;
  227. break;
  228. case 1:
  229. vo.setStatusName("空闲");
  230. idleCount++;
  231. break;
  232. case 2:
  233. vo.setStatusName("占用(未充电)");
  234. occupiedCount++;
  235. break;
  236. case 3:
  237. vo.setStatusName("占用(充电中)");
  238. occupiedCount++;
  239. break;
  240. case 4:
  241. vo.setStatusName("占用(预约锁定)");
  242. occupiedCount++;
  243. break;
  244. case 255:
  245. vo.setStatusName("故障");
  246. offlineCount++;
  247. break;
  248. default:
  249. vo.setStatusName("未知");
  250. offlineCount++;
  251. }
  252. connectorVOList.add(vo);
  253. }
  254. result.setConnectorList(connectorVOList);
  255. result.setIdleCount(idleCount);
  256. result.setOccupiedCount(occupiedCount);
  257. result.setOfflineCount(offlineCount);
  258. return result;
  259. }
  260. @Override
  261. public AppletConnectorListVO getConnectorList(Long stationId) {
  262. // 查询站点信息
  263. ThirdPartyStationInfo stationInfo = thirdPartyStationInfoMapper.selectById(stationId);
  264. if (stationInfo == null) {
  265. return null;
  266. }
  267. AppletConnectorListVO result = new AppletConnectorListVO();
  268. result.setStationId(stationId);
  269. result.setStationName(stationInfo.getStationName());
  270. result.setTips(stationInfo.getStationTips());
  271. // 根据站点stationId查询设备列表
  272. List<ThirdPartyEquipmentInfo> equipmentList = thirdPartyEquipmentInfoMapper.selectList(
  273. new LambdaQueryWrapper<ThirdPartyEquipmentInfo>()
  274. .eq(ThirdPartyEquipmentInfo::getStationId, stationInfo.getStationId())
  275. );
  276. // 构建设备ID到设备类型的映射
  277. Map<String, Integer> equipmentTypeMap = equipmentList.stream()
  278. .collect(Collectors.toMap(
  279. ThirdPartyEquipmentInfo::getEquipmentId,
  280. e -> e.getEquipmentType() != null ? e.getEquipmentType() : 0,
  281. (v1, v2) -> v1
  282. ));
  283. // 查询充电接口信息
  284. List<ThirdPartyConnectorInfo> connectorList = new ArrayList<>();
  285. if (!equipmentList.isEmpty()) {
  286. List<String> equipmentIds = equipmentList.stream()
  287. .map(ThirdPartyEquipmentInfo::getEquipmentId)
  288. .collect(Collectors.toList());
  289. connectorList = thirdPartyConnectorInfoMapper.selectList(
  290. new LambdaQueryWrapper<ThirdPartyConnectorInfo>()
  291. .in(ThirdPartyConnectorInfo::getEquipmentId, equipmentIds)
  292. );
  293. }
  294. // 统计终端状态
  295. int idleCount = 0;
  296. int occupiedCount = 0;
  297. int offlineCount = 0;
  298. List<AppletConnectorListVO.ConnectorItemVO> connectorVOList = new ArrayList<>();
  299. for (ThirdPartyConnectorInfo connector : connectorList) {
  300. AppletConnectorListVO.ConnectorItemVO vo = new AppletConnectorListVO.ConnectorItemVO();
  301. vo.setConnectorId(connector.getId());
  302. vo.setConnectorName(connector.getConnectorName());
  303. vo.setConnectorCode(connector.getConnectorId());
  304. // 设备分类
  305. Integer equipmentType = equipmentTypeMap.get(connector.getEquipmentId());
  306. vo.setEquipmentType(getEquipmentTypeName(equipmentType));
  307. // 状态处理
  308. Integer connectorStatus = connector.getStatus();
  309. if (connectorStatus == null) {
  310. connectorStatus = 0;
  311. }
  312. vo.setStatus(connectorStatus);
  313. vo.setStatusName(getStatusName(connectorStatus));
  314. // 统计
  315. switch (connectorStatus) {
  316. case 1:
  317. idleCount++;
  318. break;
  319. case 2:
  320. case 3:
  321. case 4:
  322. occupiedCount++;
  323. break;
  324. default:
  325. offlineCount++;
  326. }
  327. connectorVOList.add(vo);
  328. }
  329. result.setConnectorList(connectorVOList);
  330. result.setIdleCount(idleCount);
  331. result.setOccupiedCount(occupiedCount);
  332. result.setOfflineCount(offlineCount);
  333. return result;
  334. }
  335. @Override
  336. public AppletStationPriceListVO getStationPriceList(Long stationId) {
  337. // 查询站点信息
  338. ThirdPartyStationInfo stationInfo = thirdPartyStationInfoMapper.selectById(stationId);
  339. if (stationInfo == null) {
  340. log.warn("站点信息不存在,stationId: {}", stationId);
  341. return null;
  342. }
  343. log.info("查询站点价格列表,stationId: {}, stationName: {}, station_id字段: {}",
  344. stationId, stationInfo.getStationName(), stationInfo.getStationId());
  345. AppletStationPriceListVO result = new AppletStationPriceListVO();
  346. result.setStationId(stationId);
  347. result.setStationName(stationInfo.getStationName());
  348. result.setTips(stationInfo.getStationTips());
  349. // 获取当前登录用户ID
  350. Long userId = SecurityUtils.getUserId();
  351. log.info("当前用户ID: {}", userId);
  352. // 查询用户是否为企业用户,获取企业ID
  353. Long firmId = null;
  354. if (userId != null) {
  355. UserFirm userFirm = userFirmMapper.selectOne(
  356. new LambdaQueryWrapper<UserFirm>()
  357. .eq(UserFirm::getUserId, userId)
  358. .last("LIMIT 1")
  359. );
  360. if (userFirm != null) {
  361. firmId = userFirm.getFirmId();
  362. log.info("用户所属企业ID: {}", firmId);
  363. }
  364. }
  365. // 获取当前时间(HHmmss格式)
  366. String currentTime = LocalTime.now().format(TIME_FORMATTER);
  367. log.info("当前时间: {}", currentTime);
  368. // 查询站点对应的价格策略
  369. // 1. 先查询充电接口
  370. ThirdPartyConnectorInfo connector = thirdPartyConnectorInfoMapper.selectOne(
  371. new LambdaQueryWrapper<ThirdPartyConnectorInfo>()
  372. .eq(ThirdPartyConnectorInfo::getStationId, stationInfo.getStationId())
  373. .last("LIMIT 1")
  374. );
  375. if (connector == null) {
  376. log.warn("未找到充电接口信息,station_id: {}", stationInfo.getStationId());
  377. result.setPriceList(new ArrayList<>());
  378. return result;
  379. }
  380. log.info("找到充电接口,connectorId: {}", connector.getConnectorId());
  381. // 2. 查询价格策略
  382. ThirdPartyEquipmentPricePolicy pricePolicy = thirdPartyEquipmentPricePolicyMapper.selectOne(
  383. new LambdaQueryWrapper<ThirdPartyEquipmentPricePolicy>()
  384. .eq(ThirdPartyEquipmentPricePolicy::getConnectorId, connector.getConnectorId())
  385. .eq(ThirdPartyEquipmentPricePolicy::getIsDeleted, 0)
  386. .last("LIMIT 1")
  387. );
  388. if (pricePolicy == null) {
  389. log.warn("未找到价格策略,connectorId: {}", connector.getConnectorId());
  390. result.setPriceList(new ArrayList<>());
  391. return result;
  392. }
  393. log.info("找到价格策略,pricePolicyId: {}", pricePolicy.getId());
  394. // 3. 查询价格明细列表
  395. List<ThirdPartyPolicyInfo> policyInfoList = thirdPartyPolicyInfoMapper.selectList(
  396. new LambdaQueryWrapper<ThirdPartyPolicyInfo>()
  397. .eq(ThirdPartyPolicyInfo::getPricePolicyId, pricePolicy.getId())
  398. .eq(ThirdPartyPolicyInfo::getIsDeleted, 0)
  399. .orderByAsc(ThirdPartyPolicyInfo::getStartTime)
  400. );
  401. log.info("查询到价格明细记录数: {}", policyInfoList.size());
  402. // 如果没有查询到价格策略明细,说明该站点未配置价格策略,直接返回空列表
  403. if (policyInfoList.isEmpty()) {
  404. log.warn("third_party_policy_info表中没有价格策略数据,pricePolicyId: {}", pricePolicy.getId());
  405. result.setPriceList(new ArrayList<>());
  406. result.setHasEnterprisePrice(false);
  407. return result;
  408. }
  409. // 4. 如果是企业用户,查询企业价格
  410. Map<String, BigDecimal> enterprisePriceMap = new HashMap<>();
  411. boolean hasEnterprisePrice = false;
  412. if (firmId != null) {
  413. List<PolicyFee> policyFeeList = policyFeeMapper.selectList(
  414. new LambdaQueryWrapper<PolicyFee>()
  415. .eq(PolicyFee::getStationInfoId, stationId)
  416. .eq(PolicyFee::getSalesType, 1) // 1-企业
  417. .eq(PolicyFee::getFirmId, firmId)
  418. .eq(PolicyFee::getIsDeleted, 0)
  419. );
  420. log.info("查询企业价格记录数: {}, stationInfoId: {}, firmId: {}",
  421. policyFeeList.size(), stationId, firmId);
  422. // 如果查询到企业价格记录,设置标志为true
  423. if (!policyFeeList.isEmpty()) {
  424. hasEnterprisePrice = true;
  425. }
  426. // 构建企业价格映射 (startTime -> enterprisePrice)
  427. for (PolicyFee policyFee : policyFeeList) {
  428. // 查找对应的时段价格信息
  429. ThirdPartyPolicyInfo matchedPolicyInfo = policyInfoList.stream()
  430. .filter(info -> info.getStartTime().equals(policyFee.getStartTime()))
  431. .findFirst()
  432. .orElse(null);
  433. if (matchedPolicyInfo != null) {
  434. // 企业价格 = 电费 + 服务费 + 运营费 + 综合销售费
  435. BigDecimal elecPrice = matchedPolicyInfo.getElecPrice() != null ? matchedPolicyInfo.getElecPrice() : BigDecimal.ZERO;
  436. BigDecimal servicePrice = matchedPolicyInfo.getServicePrice() != null ? matchedPolicyInfo.getServicePrice() : BigDecimal.ZERO;
  437. BigDecimal opFee = policyFee.getOpFee() != null ? policyFee.getOpFee() : BigDecimal.ZERO;
  438. BigDecimal compSalesFee = policyFee.getCompSalesFee() != null ? policyFee.getCompSalesFee() : BigDecimal.ZERO;
  439. BigDecimal enterprisePrice = elecPrice.add(servicePrice).add(opFee).add(compSalesFee);
  440. enterprisePriceMap.put(policyFee.getStartTime(), enterprisePrice);
  441. log.debug("企业价格计算 - 时段: {}, 电费: {}, 服务费: {}, 运营费: {}, 综合销售费: {}, 企业价: {}",
  442. policyFee.getStartTime(), elecPrice, servicePrice, opFee, compSalesFee, enterprisePrice);
  443. } else {
  444. log.warn("未找到匹配的价格策略明细,startTime: {}", policyFee.getStartTime());
  445. }
  446. }
  447. }
  448. // 设置是否有企业价格
  449. result.setHasEnterprisePrice(hasEnterprisePrice);
  450. log.info("是否有企业价格: {}", hasEnterprisePrice);
  451. // 5. 构建价格列表
  452. List<AppletStationPriceListVO.PriceItemVO> priceList = new ArrayList<>();
  453. for (int i = 0; i < policyInfoList.size(); i++) {
  454. ThirdPartyPolicyInfo policyInfo = policyInfoList.get(i);
  455. AppletStationPriceListVO.PriceItemVO priceItem = new AppletStationPriceListVO.PriceItemVO();
  456. // 时段格式化:HHmmss -> HH:mm
  457. String startTime = formatTime(policyInfo.getStartTime());
  458. // 下一个时段的开始时间作为当前时段的结束时间
  459. String endTime = (i + 1 < policyInfoList.size())
  460. ? formatTime(policyInfoList.get(i + 1).getStartTime())
  461. : "24:00";
  462. priceItem.setTimePeriod(startTime + "-" + endTime);
  463. priceItem.setPeriodFlag(policyInfo.getPeriodFlag());
  464. priceItem.setPeriodFlagName(getPeriodFlagName(policyInfo.getPeriodFlag()));
  465. priceItem.setElecPrice(policyInfo.getElecPrice());
  466. priceItem.setServicePrice(policyInfo.getServicePrice());
  467. // 合计充电价 = 电费 + 服务费
  468. BigDecimal elecPrice = policyInfo.getElecPrice() != null ? policyInfo.getElecPrice() : BigDecimal.ZERO;
  469. BigDecimal servicePrice = policyInfo.getServicePrice() != null ? policyInfo.getServicePrice() : BigDecimal.ZERO;
  470. priceItem.setTotalPrice(elecPrice.add(servicePrice));
  471. // 设置企业价格(如果有)
  472. BigDecimal enterprisePrice = enterprisePriceMap.get(policyInfo.getStartTime());
  473. priceItem.setEnterprisePrice(enterprisePrice);
  474. // 判断是否为当前时段
  475. priceItem.setCurrentPeriod(isCurrentPeriod(policyInfo.getStartTime(),
  476. (i + 1 < policyInfoList.size()) ? policyInfoList.get(i + 1).getStartTime() : null,
  477. currentTime));
  478. priceList.add(priceItem);
  479. }
  480. result.setPriceList(priceList);
  481. return result;
  482. }
  483. /**
  484. * 获取设备类型名称
  485. */
  486. private String getEquipmentTypeName(Integer equipmentType) {
  487. if (equipmentType == null) {
  488. return "未知";
  489. }
  490. switch (equipmentType) {
  491. case 1:
  492. return "直流设备";
  493. case 2:
  494. return "交流设备";
  495. case 3:
  496. return "交直流一体设备";
  497. case 4:
  498. return "无线设备";
  499. case 5:
  500. return "其他";
  501. default:
  502. return "未知";
  503. }
  504. }
  505. /**
  506. * 获取状态名称
  507. */
  508. private String getStatusName(Integer status) {
  509. if (status == null) {
  510. return "未知";
  511. }
  512. switch (status) {
  513. case 0:
  514. return "离网";
  515. case 1:
  516. return "空闲";
  517. case 2:
  518. return "占用(未充电)";
  519. case 3:
  520. return "占用(充电中)";
  521. case 4:
  522. return "占用(预约锁定)";
  523. case 255:
  524. return "故障";
  525. default:
  526. return "未知";
  527. }
  528. }
  529. /**
  530. * 获取时段标志名称
  531. */
  532. private String getPeriodFlagName(Integer periodFlag) {
  533. if (periodFlag == null) {
  534. return "";
  535. }
  536. switch (periodFlag) {
  537. case 1:
  538. return "尖";
  539. case 2:
  540. return "峰";
  541. case 3:
  542. return "平";
  543. case 4:
  544. return "谷";
  545. default:
  546. return "";
  547. }
  548. }
  549. /**
  550. * 格式化时间 HHmmss -> HH:mm
  551. */
  552. private String formatTime(String time) {
  553. if (time == null || time.length() < 4) {
  554. return "00:00";
  555. }
  556. return time.substring(0, 2) + ":" + time.substring(2, 4);
  557. }
  558. /**
  559. * 判断是否为当前时段
  560. */
  561. private boolean isCurrentPeriod(String startTime, String nextStartTime, String currentTime) {
  562. if (startTime == null || currentTime == null) {
  563. return false;
  564. }
  565. // 当前时间 >= 开始时间 且 当前时间 < 下一个时段开始时间
  566. if (currentTime.compareTo(startTime) >= 0) {
  567. if (nextStartTime == null || currentTime.compareTo(nextStartTime) < 0) {
  568. return true;
  569. }
  570. }
  571. return false;
  572. }
  573. @Override
  574. public AppletChargingCostVO getCurrentChargingCost() {
  575. // 获取当前登录用户ID
  576. Long userId = SecurityUtils.getUserId();
  577. if (userId == null) {
  578. return null;
  579. }
  580. return thirdPartyStationInfoMapper.selectCurrentChargingCost(userId);
  581. }
  582. @Override
  583. public List<AppletStationSearchVO> searchStations(String keyword, BigDecimal longitude, BigDecimal latitude) {
  584. // 关键词为空或空字符串,返回空列表
  585. if (keyword == null || keyword.trim().isEmpty()) {
  586. return new ArrayList<>();
  587. }
  588. // 调用Mapper查询
  589. return thirdPartyStationInfoMapper.searchStations(keyword.trim(), longitude, latitude);
  590. }
  591. }