AppletHomeServiceImpl.java 30 KB

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