This commit is contained in:
Guoqs
2024-07-24 13:49:18 +08:00
12 changed files with 382 additions and 956 deletions

View File

@@ -2,30 +2,46 @@
# 查询站点的数据统计
```TEXT
接口地址:
请求方式:
请求方式:GET
```
入参
### 入参
| 字段名 | 类型 | 是否必传 | 备注 |
| ------ | ---- | -------- | ---- |
| | | | |
| 字段名 | 类型 | 是否必传 | 备注 |
| ---------- | ------ | -------- | -------- |
| merchantId | String | N | 运营商id |
| startTime | String | N | 开始时间 |
| endTime | String | N | 结束时间 |
反参
### 反参
| 字段名 | 类型 | 是否必传 | 备注 |
| ------ | ---- | -------- | ------------------- |
| | | Y | 充电度数(度) |
| | | Y | 充电总额(元) |
| | | Y | 订单量(单) |
| | | Y | 充电枪可使用率(% |
| | | Y | 充电中(设备数量) |
| | | Y | 空闲(设备数量) |
| | | Y | 占用(设备数量) |
| | | Y | 挂起(设备数量) |
| | | Y | 离线(设备数量) |
| | | Y | 故障(设备数量) |
| 字段名 | 类型 | 是否必传 | 备注 |
| ---------------------- | --------------------------- | -------- | ---------------- |
| stationStatisticsInfos | List<StationStatisticsInfo> | Y | 站点统计信息集合 |
#### StationStatisticsInfo
| 字段名 | 类型 | 是否必传 | 备注 |
| --------------------- | ---------- | -------- | ----------------------- |
| stationId | String | Y | 站点id |
| stationName | String | Y | 站点名称 |
| chargeDegree | BigDecimal | Y | 充电度数(度) |
| chargeAmount | BigDecimal | Y | 充电总金额(元) |
| orderQuantity | Integer | Y | 订单数量(单) |
| connectorAvailability | String | Y | ==充电枪可使用率(%== |
| chargingConnectorNum | Integer | Y | 充电中(枪口数量) |
| freeConnectorNum | Integer | Y | 空闲(枪口数量) |
| occupiedConnectorNum | Integer | Y | 占用(枪口数量) |
| hangingConnectorNum | Integer | Y | 挂起(枪口数量) |
| offlineConnectorNum | Integer | Y | 离线(枪口数量) |
| faultConnectorNum | Integer | Y | 故障(枪口数量) |
<img src="C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20240723100712169.png" alt="image-20240723100712169" style="zoom: 25%;" />
# 站点经营分析统计图
@@ -223,3 +239,18 @@
| | | Y | 充电量(度) |
| | | Y | 停止原因 |
1、预约充电结束时间不选择即为充满自停
2、充电中的数据下拉不刷新
3、预约充电显示预约状态成功预约中失败
4、预约充电订单目前不显示实时充电数据
5、桩主需要能看到桩的实时状态

View File

@@ -1,16 +1,19 @@
package com.jsowell.api.uniapp.business;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.collect.ImmutableMap;
import com.jsowell.common.core.controller.BaseController;
import com.jsowell.common.response.RestApiResponse;
import com.jsowell.pile.dto.StationStatisticsInfoDTO;
import com.jsowell.pile.service.PileStationInfoService;
import com.jsowell.pile.vo.uniapp.business.StationStatisticsInfosVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* TODO
* 运营端小程序站点信息Controller
*
* @author Lemon
* @Date 2024/7/16 13:44:06
@@ -22,15 +25,22 @@ public class BusinessStationInfoController extends BaseController {
@Autowired
private PileStationInfoService pileStationInfoService;
@GetMapping("/getStationStatisticsInfos/{merchantId}")
public RestApiResponse<?> getStationStatisticsInfos(@PathVariable("merchantId") String merchantId) {
/**
* 获取站点统计信息
* @param dto
* @return
*/
@PostMapping("/getStationStatisticsInfos")
public RestApiResponse<?> getStationStatisticsInfos(@RequestBody StationStatisticsInfoDTO dto) {
RestApiResponse<?> response = null;
try {
pileStationInfoService.getStationStatisticsInfos(merchantId);
List<StationStatisticsInfosVO> stationStatisticsInfos = pileStationInfoService.getStationStatisticsInfos(dto);
response = new RestApiResponse<>(ImmutableMap.of("stationStatisticsInfos", stationStatisticsInfos));
} catch (Exception e) {
logger.error("获取站点统计信息 error", e);
response = new RestApiResponse<>(e);
}
logger.info("获取站点统计信息 params:{}, result:{}", JSONObject.toJSONString(dto), response);
return response;
}
}

View File

@@ -578,7 +578,9 @@ public class PileService {
// reservedInfo.setStartTime(DateUtils.parseDate(dto.getStartTime()));
reservedInfo.setStartTime(Time.valueOf(dto.getStartTime()));
// reservedInfo.setEndTime(DateUtils.parseDate(dto.getEndTime()));
reservedInfo.setEndTime(Time.valueOf(dto.getEndTime()));
if (StringUtils.isNotBlank(dto.getEndTime())) {
reservedInfo.setEndTime(Time.valueOf(dto.getEndTime()));
}
if (StringUtils.isNotBlank(dto.getFreq())) {
reservedInfo.setReservationType("recurring");
reservedInfo.setFreq(dto.getFreq());

View File

@@ -9,7 +9,7 @@ spring:
# redis 配置
redis:
# 地址
host: 192.168.2.2
host: 192.168.2.46
# 端口默认为6379
port: 6379
# 数据库索引
@@ -36,9 +36,9 @@ spring:
druid:
# 主库数据源
master:
# url: jdbc:mysql://192.168.2.2:3306/jsowell_dev?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
# url: jdbc:mysql://192.168.2.46:3306/jsowell_dev?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
# username: jsowell_dev
url: jdbc:mysql://192.168.2.2:3306/jsowell_prd_copy?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
url: jdbc:mysql://192.168.2.46:3306/jsowell_prd_copy?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: jsowell_prd_copy
password: 123456
# 从库数据源

View File

@@ -8,7 +8,7 @@ spring:
# redis 配置
redis:
# 地址
host: 192.168.2.2
host: 192.168.2.46
# 端口默认为6379
port: 6379
# 数据库索引
@@ -35,9 +35,9 @@ spring:
druid:
# 主库数据源
master:
# url: jdbc:mysql://192.168.2.2:3306/jsowell_dev?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
# url: jdbc:mysql://192.168.2.46:3306/jsowell_dev?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
# username: jsowell_dev
url: jdbc:mysql://192.168.2.2:3306/jsowell_prd_copy?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
url: jdbc:mysql://192.168.2.46:3306/jsowell_prd_copy?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: jsowell_prd_copy
password: 123456
# 从库数据源

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,24 @@
package com.jsowell.pile.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* TODO
*
* @author Lemon
* @Date 2024/7/23 15:52:34
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class StationStatisticsInfoDTO {
private String merchantId;
private String startTime;
private String endTime;
}

View File

@@ -118,4 +118,6 @@ public interface PileStationInfoMapper {
List<NXJTStationInfoVO> NXJTQueryStationsInfo(@Param("dto") NXJTQueryStationInfoDTO dto);
PileStationInfo queryInfoByDeptId(@Param("deptId") String deptId);
List<PileStationInfo> getStationInfosByMerchantIds(@Param("list") List<String> merchantIds);
}

View File

@@ -5,6 +5,7 @@ import com.jsowell.pile.domain.PileStationInfo;
import com.jsowell.pile.dto.FastCreateStationDTO;
import com.jsowell.pile.dto.QueryStationDTO;
import com.jsowell.pile.dto.QueryStationInfoDTO;
import com.jsowell.pile.dto.StationStatisticsInfoDTO;
import com.jsowell.pile.dto.amap.GetStationInfoDTO;
import com.jsowell.pile.dto.lutongyunting.BindParkingPlatformDTO;
import com.jsowell.pile.dto.ningxiajiaotou.NXJTQueryStationInfoDTO;
@@ -150,11 +151,13 @@ public interface PileStationInfoService {
//↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 后管小程序 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓
//↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 后管小程序 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
public List<PileStationInfo> getStationInfosByMerchantIds(List<String> merchantIds);
/**
* 获取站点统计信息
* @param merchantId
* @param dto
*/
List<StationStatisticsInfosVO> getStationStatisticsInfos(String merchantId);
List<StationStatisticsInfosVO> getStationStatisticsInfos(StationStatisticsInfoDTO dto);
}

View File

@@ -10,29 +10,29 @@ import com.jsowell.common.core.domain.entity.SysUser;
import com.jsowell.common.core.domain.vo.AuthorizedDeptVO;
import com.jsowell.common.core.page.PageResponse;
import com.jsowell.common.core.redis.RedisCache;
import com.jsowell.common.enums.thirdparty.BusinessInformationExchangeEnum;
import com.jsowell.common.enums.ykc.PileConnectorDataBaseStatusEnum;
import com.jsowell.common.enums.ykc.ReturnCodeEnum;
import com.jsowell.common.exception.BusinessException;
import com.jsowell.common.util.*;
import com.jsowell.common.util.ip.AddressUtils;
import com.jsowell.pile.domain.PileBasicInfo;
import com.jsowell.pile.domain.PileStationInfo;
import com.jsowell.pile.domain.SettleOrderReport;
import com.jsowell.pile.domain.ThirdpartyParkingConfig;
import com.jsowell.pile.dto.FastCreateStationDTO;
import com.jsowell.pile.dto.QueryStationDTO;
import com.jsowell.pile.dto.QueryStationInfoDTO;
import com.jsowell.pile.dto.*;
import com.jsowell.pile.dto.amap.GetStationInfoDTO;
import com.jsowell.pile.dto.lutongyunting.BindParkingPlatformDTO;
import com.jsowell.pile.dto.ningxiajiaotou.NXJTQueryStationInfoDTO;
import com.jsowell.pile.mapper.PileStationInfoMapper;
import com.jsowell.pile.service.*;
import com.jsowell.pile.util.UserUtils;
import com.jsowell.pile.vo.base.MerchantInfoVO;
import com.jsowell.pile.vo.base.PileInfoVO;
import com.jsowell.pile.vo.base.StationInfoVO;
import com.jsowell.pile.vo.base.ThirdPartyStationInfoVO;
import com.jsowell.pile.vo.SupStationStatsVO;
import com.jsowell.pile.vo.base.*;
import com.jsowell.pile.vo.ningxiajiaotou.NXJTStationInfoVO;
import com.jsowell.pile.vo.uniapp.business.StationStatisticsInfosVO;
import com.jsowell.pile.vo.uniapp.customer.CurrentTimePriceDetails;
import com.jsowell.pile.vo.web.MerchantOrderReportVO;
import com.jsowell.pile.vo.web.PileStationVO;
import com.jsowell.system.service.SysDeptService;
import com.jsowell.system.service.SysUserService;
@@ -44,9 +44,13 @@ import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
@@ -88,6 +92,9 @@ public class PileStationInfoServiceImpl implements PileStationInfoService {
@Autowired
private OrderBasicInfoService orderBasicInfoService;
@Autowired
private SettleOrderReportService settleOrderReportService;
/**
* 查询充电站信息
@@ -623,16 +630,115 @@ public class PileStationInfoServiceImpl implements PileStationInfoService {
return pileStationInfoMapper.queryInfoByDeptId(deptId);
}
@Override
public List<PileStationInfo> getStationInfosByMerchantIds(List<String> merchantIds){
return pileStationInfoMapper.getStationInfosByMerchantIds(merchantIds);
}
/**
* 获取站点统计信息
* @param merchantId
* @param dto
*/
@Override
public List<StationStatisticsInfosVO> getStationStatisticsInfos(String merchantId) {
// 根据运营商id查出所有站点id
public List<StationStatisticsInfosVO> getStationStatisticsInfos(StationStatisticsInfoDTO dto) {
String merchantId = dto.getMerchantId();
// 获取当前登录账号的运营商权限
List<MerchantInfoVO> merchantInfoVOList = UserUtils.getMerchantInfoVOList();
List<String> merchantIds = new ArrayList<>();
List<StationStatisticsInfosVO> resultList = new ArrayList<>();
if (StringUtils.isBlank(merchantId)) {
merchantIds = merchantInfoVOList.stream()
.map(MerchantInfoVO::getMerchantId)
.collect(Collectors.toList());
}else {
merchantIds.add(merchantId);
}
// 根据运营商ids查出所有站点id
List<PileStationInfo> pileStationInfos = getStationInfosByMerchantIds(merchantIds);
if (CollectionUtils.isEmpty(pileStationInfos)) {
// 未查到该运营商下的站点
throw new BusinessException(ReturnCodeEnum.CODE_SELECT_INFO_IS_NULL);
}
List<String> stationIds = pileStationInfos.stream()
.map(x -> String.valueOf(x.getId()))
.collect(Collectors.toList());
// 创建DecimalFormat对象并设置格式
DecimalFormat df = new DecimalFormat("0.00%");
// 根据站点ids查询站点营收报表
List<SettleOrderReport> list = settleOrderReportService.queryOrderReport(stationIds, dto.getStartTime(), dto.getEndTime());
if (CollectionUtils.isEmpty(list)) {
throw new BusinessException(ReturnCodeEnum.CODE_SELECT_INFO_IS_NULL);
}
// 根据站点id分组将充电度数、充电金额、充电次数进行累加
Map<String, SettleOrderReport> collect = list.stream()
.sorted(Comparator.comparing(SettleOrderReport::getStationId))
// .filter(vo -> vo.getChargingTime() != null && vo.getTotalPower() != null)
.collect(Collectors.toMap(SettleOrderReport::getStationId, Function.identity(),
(a, b) -> {
a.setUseElectricity(a.getUseElectricity().add(b.getUseElectricity()));
a.setTotalAmount(a.getTotalAmount().add(b.getTotalAmount()));
a.setChargeNum(String.valueOf(Integer.parseInt(a.getChargeNum()) + Integer.parseInt(b.getChargeNum())));
return a;
}));
return null;
for (Map.Entry<String, SettleOrderReport> entry: collect.entrySet()) {
String stationId = entry.getKey();
SettleOrderReport report = entry.getValue();
// 查询枪口列表
List<ConnectorInfoVO> uniAppConnectorList = pileConnectorInfoService.getUniAppConnectorList(Long.parseLong(stationId));
int chargingConnectorNum = Constants.zero; // 充电中
int freeConnectorNum = Constants.zero; // 空闲
int occupiedConnectorNum = Constants.zero; // 占用
int hangingConnectorNum = Constants.zero; // 挂起
int offlineConnectorNum = Constants.zero; // 离线
int faultConnectorNum = Constants.zero; // 故障
for (ConnectorInfoVO connectorInfoVO : uniAppConnectorList) {
String connectorStatus = connectorInfoVO.getConnectorStatus();
if (StringUtils.equals(PileConnectorDataBaseStatusEnum.FREE.getValue(), connectorStatus)) {
// 空闲
freeConnectorNum += 1;
}else if (StringUtils.equals(PileConnectorDataBaseStatusEnum.OCCUPIED_NOT_CHARGED.getValue(), connectorStatus)) {
// 占用(未充电)
occupiedConnectorNum += 1;
}else if (StringUtils.equals(PileConnectorDataBaseStatusEnum.OCCUPIED_CHARGING.getValue(), connectorStatus)) {
// 充电中
chargingConnectorNum += 1;
}else if (StringUtils.equals(PileConnectorDataBaseStatusEnum.OFF_NETWORK.getValue(), connectorStatus)) {
// 离线
offlineConnectorNum += 1;
}else if(StringUtils.equals(PileConnectorDataBaseStatusEnum.FAULT.getValue(), connectorStatus)) {
// 故障
faultConnectorNum += 1;
}
}
// 计算枪口可使用率
int totalConnectorNum = uniAppConnectorList.size();
double connectorAvailability = (double) freeConnectorNum / totalConnectorNum;
String format = df.format(connectorAvailability);
StationStatisticsInfosVO vo = StationStatisticsInfosVO.builder()
.stationId(stationId)
// .stationName(pileStationInfo.getStationName())
.chargeDegree(report.getUseElectricity())
.chargeAmount(report.getTotalAmount())
.orderQuantity(Integer.parseInt(report.getChargeNum()))
.connectorAvailability(format)
.chargingConnectorNum(chargingConnectorNum)
.freeConnectorNum(freeConnectorNum)
.occupiedConnectorNum(occupiedConnectorNum)
.hangingConnectorNum(hangingConnectorNum)
.offlineConnectorNum(offlineConnectorNum)
.faultConnectorNum(faultConnectorNum)
.build();
resultList.add(vo);
}
return resultList;
}
}

View File

@@ -18,6 +18,17 @@ import java.math.BigDecimal;
@AllArgsConstructor
@Builder
public class StationStatisticsInfosVO {
/**
* 站点id
*/
private String stationId;
/**
* 站点名称
*/
private String stationName;
/**
* 充电度数
*/
@@ -41,30 +52,30 @@ public class StationStatisticsInfosVO {
/**
* 充电中的设备数量
*/
private Integer chargingPileNum;
private Integer chargingConnectorNum;
/**
* 空闲中的设备数量
*/
private Integer freePileNum;
private Integer freeConnectorNum;
/**
* 占用中的设备数量
*/
private Integer occupiedPileNum;
private Integer occupiedConnectorNum;
/**
* 挂起中的设备数量
*/
private Integer hangingPileNum;
private Integer hangingConnectorNum;
/**
* 离线设备数量
*/
private Integer offlinePileNum;
private Integer offlineConnectorNum;
/**
* 故障桩数量
*/
private Integer faultPileNum;
private Integer faultConnectorNum;
}

View File

@@ -597,4 +597,14 @@
where del_flag = '0'
and dept_id = #{deptId,jdbcType=VARCHAR}
</select>
<select id="getStationInfosByMerchantIds" resultMap="PileStationInfoResult">
<include refid="selectPileStationInfoVo"/>
<if test="list != null and list.size() != 0">
where merchant_id in
<foreach collection="list" item="merchantId" open="(" separator="," close=")">
#{merchantId,jdbcType=VARCHAR}
</foreach>
</if>
</select>
</mapper>