mirror of
https://codeup.aliyun.com/67c68d4e484ca2f0a13ac3c1/ydc/jsowell-charger-web.git
synced 2026-06-16 13:19:57 +08:00
Merge branch 'feature-business-minigram' into dev
This commit is contained in:
@@ -6,11 +6,15 @@ import com.jsowell.common.core.page.PageResponse;
|
||||
import com.jsowell.common.enums.ykc.ReturnCodeEnum;
|
||||
import com.jsowell.common.exception.BusinessException;
|
||||
import com.jsowell.common.response.RestApiResponse;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.jsowell.pile.dto.MerchantOrderReportDTO;
|
||||
import com.jsowell.pile.dto.ParkingCouponRecordQueryDTO;
|
||||
import com.jsowell.pile.dto.business.BusinessEfficiencyQueryDTO;
|
||||
import com.jsowell.pile.dto.business.BusinessOperationAnalysisQueryDTO;
|
||||
import com.jsowell.pile.dto.business.BusinessScaleQueryDTO;
|
||||
import com.jsowell.pile.service.BusinessFinancialService;
|
||||
import com.jsowell.pile.vo.uniapp.business.BusinessEfficiencyAnalysisVO;
|
||||
import com.jsowell.pile.vo.uniapp.business.BusinessEfficiencyVO;
|
||||
import com.jsowell.pile.vo.uniapp.business.BusinessGunEfficiencyAnalysisVO;
|
||||
import com.jsowell.pile.vo.uniapp.business.BusinessOperationAnalysisVO;
|
||||
import com.jsowell.pile.vo.uniapp.business.BusinessScaleVO;
|
||||
@@ -148,4 +152,88 @@ public class BusinessFinancialController extends BaseController {
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询经营效率
|
||||
*
|
||||
* @param dto 查询参数
|
||||
* @return 经营效率数据(含指标卡片和曲线图)
|
||||
*/
|
||||
@PostMapping("/businessEfficiency")
|
||||
public RestApiResponse<?> getBusinessEfficiency(@RequestBody BusinessEfficiencyQueryDTO dto) {
|
||||
logger.info("查询经营效率 params:{}", JSONObject.toJSONString(dto));
|
||||
RestApiResponse<?> response;
|
||||
try {
|
||||
if (dto == null) {
|
||||
throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR);
|
||||
}
|
||||
BusinessEfficiencyVO result = businessFinancialService.getBusinessEfficiency(dto);
|
||||
response = new RestApiResponse<>(result);
|
||||
logger.info("查询经营效率成功 startTime:{}, endTime:{}, selectedMetricCode:{}",
|
||||
dto.getStartTime(), dto.getEndTime(), dto.getSelectedMetricCode());
|
||||
} catch (BusinessException e) {
|
||||
logger.warn("查询经营效率业务异常 code:{}, message:{}", e.getCode(), e.getMessage(), e);
|
||||
response = new RestApiResponse<>(e.getCode(), e.getMessage());
|
||||
} catch (Exception e) {
|
||||
logger.error("查询经营效率系统异常 params:{}", JSONObject.toJSONString(dto), e);
|
||||
response = new RestApiResponse<>(e);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询效率分析(单均效率 + 枪均效率)
|
||||
*
|
||||
* @param dto 查询参数
|
||||
* @return 效率分析数据(含单均效率和枪均效率两个维度)
|
||||
*/
|
||||
@PostMapping("/efficiencyAnalysis")
|
||||
public RestApiResponse<?> getEfficiencyAnalysis(@RequestBody BusinessOperationAnalysisQueryDTO dto) {
|
||||
logger.info("查询效率分析 params:{}", JSONObject.toJSONString(dto));
|
||||
RestApiResponse<?> response;
|
||||
try {
|
||||
if (dto == null) {
|
||||
throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR);
|
||||
}
|
||||
BusinessEfficiencyAnalysisVO result = businessFinancialService.getEfficiencyAnalysis(dto);
|
||||
response = new RestApiResponse<>(result);
|
||||
logger.info("查询效率分析成功 startTime:{}, endTime:{}",
|
||||
dto.getStartTime(), dto.getEndTime());
|
||||
} catch (BusinessException e) {
|
||||
logger.warn("查询效率分析业务异常 code:{}, message:{}", e.getCode(), e.getMessage(), e);
|
||||
response = new RestApiResponse<>(e.getCode(), e.getMessage());
|
||||
} catch (Exception e) {
|
||||
logger.error("查询效率分析系统异常 params:{}", JSONObject.toJSONString(dto), e);
|
||||
response = new RestApiResponse<>(e);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询场站订单排行
|
||||
*
|
||||
* @param dto 查询参数(含pageNum、pageSize)
|
||||
* @return 分页结果(场站订单排行列表,按订单数量降序)
|
||||
*/
|
||||
@PostMapping("/stationOrderRank")
|
||||
public RestApiResponse<?> getStationOrderRank(@RequestBody BusinessOperationAnalysisQueryDTO dto) {
|
||||
logger.info("查询场站订单排行 params:{}", JSONObject.toJSONString(dto));
|
||||
RestApiResponse<?> response;
|
||||
try {
|
||||
if (dto == null) {
|
||||
throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR);
|
||||
}
|
||||
PageResponse pageResponse = businessFinancialService.getStationOrderRank(dto);
|
||||
response = new RestApiResponse<>(ImmutableMap.of("pageResponse", pageResponse));
|
||||
logger.info("查询场站订单排行成功 startTime:{}, endTime:{}, total:{}",
|
||||
dto.getStartTime(), dto.getEndTime(), pageResponse.getTotal());
|
||||
} catch (BusinessException e) {
|
||||
logger.warn("查询场站订单排行业务异常 code:{}, message:{}", e.getCode(), e.getMessage(), e);
|
||||
response = new RestApiResponse<>(e.getCode(), e.getMessage());
|
||||
} catch (Exception e) {
|
||||
logger.error("查询场站订单排行系统异常 params:{}", JSONObject.toJSONString(dto), e);
|
||||
response = new RestApiResponse<>(e);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.jsowell.pile.dto.business;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 经营效率查询DTO
|
||||
*
|
||||
* @author zhangziao
|
||||
* @date 2026/4/16
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class BusinessEfficiencyQueryDTO {
|
||||
|
||||
/**
|
||||
* 开始时间,格式:yyyy-MM-dd
|
||||
*/
|
||||
private String startTime;
|
||||
|
||||
/**
|
||||
* 结束时间,格式:yyyy-MM-dd
|
||||
*/
|
||||
private String endTime;
|
||||
|
||||
/**
|
||||
* 站点id列表
|
||||
*/
|
||||
private List<String> stationIdList;
|
||||
|
||||
/**
|
||||
* 当前选中的指标编码,用于查询对应的曲线图数据
|
||||
* AVG_SERVICE_FEE_PER_DEGREE-度均服务费,
|
||||
* TIME_UTILIZATION-时间利用率,
|
||||
* GUN_AVG_ELECTRICITY-枪均电量,
|
||||
* POWER_UTILIZATION-功率利用率
|
||||
*/
|
||||
private String selectedMetricCode;
|
||||
}
|
||||
@@ -38,4 +38,14 @@ public class BusinessOperationAnalysisQueryDTO {
|
||||
* 当前选中的指标编码
|
||||
*/
|
||||
private String selectedMetricCode;
|
||||
|
||||
/**
|
||||
* 页码(用于场站排行分页)
|
||||
*/
|
||||
private Integer pageNum;
|
||||
|
||||
/**
|
||||
* 每页条数(用于场站排行分页)
|
||||
*/
|
||||
private Integer pageSize;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,10 @@ import com.jsowell.common.core.page.PageResponse;
|
||||
import com.jsowell.pile.dto.MerchantOrderReportDTO;
|
||||
import com.jsowell.pile.dto.ParkingCouponRecordQueryDTO;
|
||||
import com.jsowell.pile.dto.business.BusinessOperationAnalysisQueryDTO;
|
||||
import com.jsowell.pile.dto.business.BusinessEfficiencyQueryDTO;
|
||||
import com.jsowell.pile.dto.business.BusinessScaleQueryDTO;
|
||||
import com.jsowell.pile.vo.uniapp.business.BusinessEfficiencyAnalysisVO;
|
||||
import com.jsowell.pile.vo.uniapp.business.BusinessEfficiencyVO;
|
||||
import com.jsowell.pile.vo.uniapp.business.BusinessGunEfficiencyAnalysisVO;
|
||||
import com.jsowell.pile.vo.uniapp.business.BusinessOperationAnalysisVO;
|
||||
import com.jsowell.pile.vo.uniapp.business.BusinessScaleVO;
|
||||
@@ -45,4 +48,28 @@ public interface BusinessFinancialService {
|
||||
* @return 经营规模数据(含指标卡片和曲线图)
|
||||
*/
|
||||
BusinessScaleVO getBusinessScale(BusinessScaleQueryDTO dto);
|
||||
|
||||
/**
|
||||
* 查询经营效率
|
||||
*
|
||||
* @param dto 查询条件
|
||||
* @return 经营效率数据(含指标卡片和曲线图)
|
||||
*/
|
||||
BusinessEfficiencyVO getBusinessEfficiency(BusinessEfficiencyQueryDTO dto);
|
||||
|
||||
/**
|
||||
* 分页查询场站订单排行
|
||||
*
|
||||
* @param dto 查询条件(含pageNum、pageSize)
|
||||
* @return 分页结果(场站订单排行列表,按订单数量降序)
|
||||
*/
|
||||
PageResponse getStationOrderRank(BusinessOperationAnalysisQueryDTO dto);
|
||||
|
||||
/**
|
||||
* 查询效率分析(单均效率 + 枪均效率)
|
||||
*
|
||||
* @param dto 查询条件
|
||||
* @return 效率分析数据(含单均效率和枪均效率两个维度)
|
||||
*/
|
||||
BusinessEfficiencyAnalysisVO getEfficiencyAnalysis(BusinessOperationAnalysisQueryDTO dto);
|
||||
}
|
||||
|
||||
@@ -12,11 +12,13 @@ import com.jsowell.common.enums.ykc.ReturnCodeEnum;
|
||||
import com.jsowell.common.exception.BusinessException;
|
||||
import com.jsowell.pile.dto.MerchantOrderReportDTO;
|
||||
import com.jsowell.pile.dto.ParkingCouponRecordQueryDTO;
|
||||
import com.jsowell.pile.dto.business.BusinessEfficiencyQueryDTO;
|
||||
import com.jsowell.pile.dto.business.BusinessOperationAnalysisQueryDTO;
|
||||
import com.jsowell.pile.dto.business.BusinessOperationDateRangeDTO;
|
||||
import com.jsowell.pile.dto.business.BusinessOperationSummaryDTO;
|
||||
import com.jsowell.pile.dto.business.BusinessScaleQueryDTO;
|
||||
import com.jsowell.pile.domain.PileConnectorInfo;
|
||||
import com.jsowell.pile.domain.PileStationInfo;
|
||||
import com.jsowell.pile.domain.SettleOrderReport;
|
||||
import com.jsowell.pile.service.BusinessFinancialService;
|
||||
import com.jsowell.pile.service.CarCouponRecordService;
|
||||
@@ -25,13 +27,17 @@ import com.jsowell.pile.service.PileConnectorInfoService;
|
||||
import com.jsowell.pile.service.PileStationInfoService;
|
||||
import com.jsowell.pile.service.SettleOrderReportService;
|
||||
import com.jsowell.pile.util.UserUtils;
|
||||
import com.jsowell.pile.vo.base.ConnectorInfoVO;
|
||||
import com.jsowell.pile.vo.uniapp.business.BusinessEfficiencyAnalysisVO;
|
||||
import com.jsowell.pile.vo.uniapp.business.BusinessGunEfficiencyAnalysisVO;
|
||||
import com.jsowell.pile.vo.uniapp.business.BusinessEfficiencyVO;
|
||||
import com.jsowell.pile.vo.uniapp.business.BusinessOperationAnalysisVO;
|
||||
import com.jsowell.pile.vo.uniapp.business.BusinessOperationDiagnosisItemVO;
|
||||
import com.jsowell.pile.vo.uniapp.business.BusinessOperationMetricVO;
|
||||
import com.jsowell.pile.vo.uniapp.business.BusinessScaleChartVO;
|
||||
import com.jsowell.pile.vo.uniapp.business.BusinessScaleMetricVO;
|
||||
import com.jsowell.pile.vo.uniapp.business.BusinessScaleVO;
|
||||
import com.jsowell.pile.vo.uniapp.business.BusinessStationRankVO;
|
||||
import com.jsowell.pile.vo.web.MerchantOrderReportVO;
|
||||
import com.jsowell.pile.vo.web.ParkingCouponRecordVO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -74,6 +80,11 @@ public class BusinessFinancialServiceImpl implements BusinessFinancialService {
|
||||
private static final String SCALE_METRIC_SERVICE_AMOUNT = "SERVICE_AMOUNT";
|
||||
private static final String SCALE_METRIC_USE_ELECTRICITY = "USE_ELECTRICITY";
|
||||
|
||||
private static final String EFFICIENCY_METRIC_AVG_SERVICE_FEE_PER_DEGREE = "AVG_SERVICE_FEE_PER_DEGREE";
|
||||
private static final String EFFICIENCY_METRIC_TIME_UTILIZATION = "TIME_UTILIZATION";
|
||||
private static final String EFFICIENCY_METRIC_GUN_AVG_ELECTRICITY = "GUN_AVG_ELECTRICITY";
|
||||
private static final String EFFICIENCY_METRIC_POWER_UTILIZATION = "POWER_UTILIZATION";
|
||||
|
||||
/**
|
||||
* 财务查询通用线程池(支持多方法并行查询)
|
||||
* 核心线程数4:覆盖经营规模(2路)、我的钱包(3路)、经营分析(2路)、枪均效率(2路)等场景
|
||||
@@ -785,4 +796,509 @@ public class BusinessFinancialServiceImpl implements BusinessFinancialService {
|
||||
return BigDecimalUtils.nullToZero(report.getUseElectricity());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询效率分析(单均效率 + 枪均效率)
|
||||
* 单均效率:按订单维度计算平均指标
|
||||
* 枪均效率:按枪口×天数维度计算日均指标
|
||||
*
|
||||
* @param dto 查询条件
|
||||
* @return 效率分析数据
|
||||
*/
|
||||
@Override
|
||||
public BusinessEfficiencyAnalysisVO getEfficiencyAnalysis(BusinessOperationAnalysisQueryDTO dto) {
|
||||
if (dto == null) {
|
||||
return null;
|
||||
}
|
||||
if (StringUtils.isBlank(dto.getStartTime()) && StringUtils.isBlank(dto.getEndTime())) {
|
||||
LocalDate endDate = LocalDate.now();
|
||||
LocalDate startDate = endDate.minusDays(6);
|
||||
dto.setStartTime(startDate.toString());
|
||||
dto.setEndTime(endDate.toString());
|
||||
}
|
||||
|
||||
List<String> stationIdList = resolveStationIds(dto.getStationIdList());
|
||||
|
||||
// 并行查询订单汇总和枪口数量
|
||||
CompletableFuture<BusinessOperationSummaryDTO> summaryFuture = CompletableFuture.supplyAsync(
|
||||
() -> buildSummaryFromReports(
|
||||
queryRawReports(stationIdList, dto.getStartTime(), dto.getEndTime())),
|
||||
FINANCIAL_THREAD_POOL);
|
||||
CompletableFuture<Integer> connectorCountFuture = CompletableFuture.supplyAsync(
|
||||
() -> countConnectors(stationIdList), FINANCIAL_THREAD_POOL);
|
||||
|
||||
BusinessOperationSummaryDTO summary = summaryFuture.join();
|
||||
int connectorCount = connectorCountFuture.join();
|
||||
|
||||
long dayCount = calculateInclusiveDays(dto.getStartTime(), dto.getEndTime());
|
||||
|
||||
// ===== 单均效率指标 =====
|
||||
// 单均服务费 = 服务费总额 / 订单数量
|
||||
BigDecimal avgServiceFeePerOrder = BigDecimalUtils.safeDivide(
|
||||
summary.getServiceAmount(), summary.getOrderCount(), 2);
|
||||
// 单均充电量 = 充电电量总量 / 订单数量
|
||||
BigDecimal avgElectricityPerOrder = BigDecimalUtils.safeDivide(
|
||||
summary.getUseElectricity(), summary.getOrderCount(), 4);
|
||||
// 单均充电时长 = 总充电时长 / 订单数量
|
||||
BigDecimal avgChargeTimeMinutesPerOrder = BigDecimalUtils.safeDivide(
|
||||
summary.getChargeTime(), summary.getOrderCount(), 2);
|
||||
String avgChargeTimePerOrder = formatMinutesOnly(avgChargeTimeMinutesPerOrder);
|
||||
|
||||
// ===== 枪均效率指标 =====
|
||||
BigDecimal connectorCountBd = BigDecimal.valueOf(connectorCount);
|
||||
BigDecimal dayCountBd = BigDecimal.valueOf(dayCount);
|
||||
BigDecimal connectorDayCount = connectorCountBd.multiply(dayCountBd);
|
||||
|
||||
// 枪日均服务费 = 服务费总额 / (枪口数量 × 天数)
|
||||
BigDecimal gunDailyAvgServiceFee = BigDecimalUtils.safeDivide(
|
||||
summary.getServiceAmount(), connectorDayCount, 2);
|
||||
// 枪日均充电量 = 充电电量总量 / (枪口数量 × 天数)
|
||||
BigDecimal gunDailyAvgElectricity = BigDecimalUtils.safeDivide(
|
||||
summary.getUseElectricity(), connectorDayCount, 4);
|
||||
// 枪日均充电时长 = 总充电时长 / (枪口数量 × 天数)
|
||||
BigDecimal gunDailyAvgChargeTimeMinutes = BigDecimalUtils.safeDivide(
|
||||
summary.getChargeTime(), connectorDayCount, 2);
|
||||
String gunDailyAvgChargeTime = formatMinutesToHourMinute(gunDailyAvgChargeTimeMinutes);
|
||||
|
||||
// ===== 共用指标 =====
|
||||
// 度均服务费 = 服务费总额 / 充电电量总量
|
||||
BigDecimal avgServiceFeePerDegree = BigDecimalUtils.safeDivide(
|
||||
summary.getServiceAmount(), summary.getUseElectricity(), 4);
|
||||
// 平均功率 = 充电电量总量 × 60 / 总充电时长(分钟)
|
||||
BigDecimal avgPower = BigDecimalUtils.safeDivide(
|
||||
summary.getUseElectricity().multiply(new BigDecimal("60")),
|
||||
summary.getChargeTime(),
|
||||
4);
|
||||
|
||||
return BusinessEfficiencyAnalysisVO.builder()
|
||||
.startTime(dto.getStartTime())
|
||||
.endTime(dto.getEndTime())
|
||||
.avgServiceFeePerOrder(BigDecimalUtils.normalize(avgServiceFeePerOrder))
|
||||
.avgElectricityPerOrder(BigDecimalUtils.normalize(avgElectricityPerOrder))
|
||||
.avgChargeTimePerOrder(avgChargeTimePerOrder)
|
||||
.gunDailyAvgServiceFee(BigDecimalUtils.normalize(gunDailyAvgServiceFee))
|
||||
.gunDailyAvgElectricity(BigDecimalUtils.normalize(gunDailyAvgElectricity))
|
||||
.gunDailyAvgChargeTime(gunDailyAvgChargeTime)
|
||||
.avgServiceFeePerDegree(BigDecimalUtils.normalize(avgServiceFeePerDegree))
|
||||
.avgPower(BigDecimalUtils.normalize(avgPower))
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将分钟数格式化为xxm格式(用于单均充电时长)
|
||||
*
|
||||
* @param minutes 分钟数
|
||||
* @return 格式化结果
|
||||
*/
|
||||
private String formatMinutesOnly(BigDecimal minutes) {
|
||||
long totalMinutes = BigDecimalUtils.nullToZero(minutes)
|
||||
.setScale(0, RoundingMode.HALF_UP)
|
||||
.longValue();
|
||||
return totalMinutes + "m";
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询场站订单排行
|
||||
* 按站点分组统计订单数量,按订单数量降序排列,支持分页
|
||||
*
|
||||
* @param dto 查询条件(含pageNum、pageSize)
|
||||
* @return 分页结果
|
||||
*/
|
||||
@Override
|
||||
public PageResponse getStationOrderRank(BusinessOperationAnalysisQueryDTO dto) {
|
||||
if (dto == null) {
|
||||
return PageResponse.builder().pageNum(1).pageSize(10).list(new ArrayList<>()).total(0).pages(0).build();
|
||||
}
|
||||
if (StringUtils.isBlank(dto.getStartTime()) && StringUtils.isBlank(dto.getEndTime())) {
|
||||
LocalDate endDate = LocalDate.now();
|
||||
LocalDate startDate = endDate.minusDays(6);
|
||||
dto.setStartTime(startDate.toString());
|
||||
dto.setEndTime(endDate.toString());
|
||||
}
|
||||
|
||||
// 设置默认分页参数
|
||||
int pageNum = dto.getPageNum() != null && dto.getPageNum() > 0 ? dto.getPageNum() : 1;
|
||||
int pageSize = dto.getPageSize() != null && dto.getPageSize() > 0 ? dto.getPageSize() : 10;
|
||||
|
||||
List<String> stationIdList = resolveStationIds(dto.getStationIdList());
|
||||
|
||||
// 查询结算报表原始数据
|
||||
List<SettleOrderReport> reportList = queryRawReports(
|
||||
stationIdList, dto.getStartTime(), dto.getEndTime());
|
||||
|
||||
if (CollectionUtils.isEmpty(reportList)) {
|
||||
return PageResponse.builder().pageNum(pageNum).pageSize(pageSize).list(new ArrayList<>()).total(0).pages(0).build();
|
||||
}
|
||||
|
||||
// 按站点ID分组,累加订单数量
|
||||
Map<String, Integer> stationOrderCountMap = new LinkedHashMap<>();
|
||||
for (SettleOrderReport report : reportList) {
|
||||
String sId = report.getStationId();
|
||||
if (StringUtils.isBlank(sId)) {
|
||||
continue;
|
||||
}
|
||||
int chargeNum = BigDecimalUtils.parseOrZero(report.getChargeNum()).intValue();
|
||||
stationOrderCountMap.merge(sId, chargeNum, Integer::sum);
|
||||
}
|
||||
|
||||
// 批量查询站点名称(一次性查出所有站点,内存中按ID匹配,避免N+1查询)
|
||||
List<PileStationInfo> allStations = pileStationInfoService.selectPileStationInfoList(new PileStationInfo());
|
||||
Map<String, String> stationNameMap = new LinkedHashMap<>();
|
||||
for (PileStationInfo station : allStations) {
|
||||
stationNameMap.put(String.valueOf(station.getId()), station.getStationName());
|
||||
}
|
||||
|
||||
// 按订单数量降序排列并构建排行列表
|
||||
List<BusinessStationRankVO> rankList = stationOrderCountMap.entrySet().stream()
|
||||
.map(entry -> BusinessStationRankVO.builder()
|
||||
.stationId(entry.getKey())
|
||||
.stationName(stationNameMap.getOrDefault(entry.getKey(), "未知站点"))
|
||||
.orderCount(entry.getValue())
|
||||
.build())
|
||||
.sorted((a, b) -> Integer.compare(
|
||||
b.getOrderCount() != null ? b.getOrderCount() : 0,
|
||||
a.getOrderCount() != null ? a.getOrderCount() : 0))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 设置排行名次(基于全量数据的排名)
|
||||
for (int i = 0; i < rankList.size(); i++) {
|
||||
rankList.get(i).setRank(i + 1);
|
||||
}
|
||||
|
||||
// 手动分页
|
||||
long total = rankList.size();
|
||||
int pages = (int) Math.ceil((double) total / pageSize);
|
||||
int fromIndex = (pageNum - 1) * pageSize;
|
||||
int toIndex = Math.min(fromIndex + pageSize, rankList.size());
|
||||
List<BusinessStationRankVO> pageList = fromIndex < rankList.size()
|
||||
? rankList.subList(fromIndex, toIndex)
|
||||
: new ArrayList<>();
|
||||
|
||||
return PageResponse.builder()
|
||||
.pageNum(pageNum)
|
||||
.pageSize(pageSize)
|
||||
.list(pageList)
|
||||
.total(total)
|
||||
.pages(pages)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询经营效率
|
||||
* 优化:当前周期和上周期汇总并行查询,枪口数量与总额定功率并行查询
|
||||
*
|
||||
* @param dto 查询条件
|
||||
* @return 经营效率数据
|
||||
*/
|
||||
@Override
|
||||
public BusinessEfficiencyVO getBusinessEfficiency(BusinessEfficiencyQueryDTO dto) {
|
||||
if (dto == null) {
|
||||
return null;
|
||||
}
|
||||
if (StringUtils.isBlank(dto.getStartTime()) && StringUtils.isBlank(dto.getEndTime())) {
|
||||
LocalDate endDate = LocalDate.now();
|
||||
LocalDate startDate = endDate.minusDays(6);
|
||||
dto.setStartTime(startDate.toString());
|
||||
dto.setEndTime(endDate.toString());
|
||||
}
|
||||
|
||||
BusinessOperationDateRangeDTO range = buildDateRangeFromEfficiency(dto);
|
||||
List<String> stationIdList = resolveStationIds(dto.getStationIdList());
|
||||
|
||||
// 并行查询当前周期和上周期原始报表数据
|
||||
CompletableFuture<List<SettleOrderReport>> currentReportFuture = CompletableFuture.supplyAsync(
|
||||
() -> queryRawReports(stationIdList, range.getCurrentStart(), range.getCurrentEnd()),
|
||||
FINANCIAL_THREAD_POOL);
|
||||
CompletableFuture<List<SettleOrderReport>> previousReportFuture = CompletableFuture.supplyAsync(
|
||||
() -> queryRawReports(stationIdList, range.getPreviousStart(), range.getPreviousEnd()),
|
||||
FINANCIAL_THREAD_POOL);
|
||||
|
||||
// 等待报表查询完成
|
||||
List<SettleOrderReport> currentReports = currentReportFuture.join();
|
||||
List<SettleOrderReport> previousReports = previousReportFuture.join();
|
||||
|
||||
BusinessOperationSummaryDTO currentSummary = buildSummaryFromReports(currentReports);
|
||||
BusinessOperationSummaryDTO previousSummary = buildSummaryFromReports(previousReports);
|
||||
|
||||
Map<String, SettleOrderReport> currentDailyMap = buildDailyMapFromReports(currentReports);
|
||||
Map<String, SettleOrderReport> previousDailyMap = buildDailyMapFromReports(previousReports);
|
||||
|
||||
long dayCount = calculateInclusiveDays(range.getCurrentStart(), range.getCurrentEnd());
|
||||
|
||||
// 查询枪口数量和总额定功率
|
||||
ConnectorStats connectorStats = buildConnectorStats(stationIdList);
|
||||
int connectorCount = connectorStats.getConnectorCount();
|
||||
BigDecimal totalRatedPower = connectorStats.getTotalRatedPower();
|
||||
|
||||
// 构建指标卡片
|
||||
BigDecimal currentAvgServiceFeePerDegree = BigDecimalUtils.safeDivide(
|
||||
currentSummary.getServiceAmount(), currentSummary.getUseElectricity(), 2);
|
||||
BigDecimal previousAvgServiceFeePerDegree = BigDecimalUtils.safeDivide(
|
||||
previousSummary.getServiceAmount(), previousSummary.getUseElectricity(), 2);
|
||||
|
||||
BigDecimal currentTimeUtilization = calculateTimeUtilization(
|
||||
currentSummary.getChargeTime(), connectorCount, dayCount);
|
||||
BigDecimal previousTimeUtilization = calculateTimeUtilization(
|
||||
previousSummary.getChargeTime(), connectorCount, dayCount);
|
||||
|
||||
BigDecimal currentGunAvgElectricity = connectorCount > 0
|
||||
? BigDecimalUtils.safeDivide(currentSummary.getUseElectricity(),
|
||||
BigDecimal.valueOf(connectorCount), 2)
|
||||
: BigDecimal.ZERO;
|
||||
BigDecimal previousGunAvgElectricity = connectorCount > 0
|
||||
? BigDecimalUtils.safeDivide(previousSummary.getUseElectricity(),
|
||||
BigDecimal.valueOf(connectorCount), 2)
|
||||
: BigDecimal.ZERO;
|
||||
|
||||
BigDecimal currentPowerUtilization = calculatePowerUtilization(
|
||||
currentSummary.getUseElectricity(), currentSummary.getChargeTime(),
|
||||
connectorCount, dayCount, totalRatedPower);
|
||||
BigDecimal previousPowerUtilization = calculatePowerUtilization(
|
||||
previousSummary.getUseElectricity(), previousSummary.getChargeTime(),
|
||||
connectorCount, dayCount, totalRatedPower);
|
||||
|
||||
List<BusinessScaleMetricVO> metricList = new ArrayList<>();
|
||||
metricList.add(buildScaleMetric(EFFICIENCY_METRIC_AVG_SERVICE_FEE_PER_DEGREE, "度均服务费", "元",
|
||||
currentAvgServiceFeePerDegree, previousAvgServiceFeePerDegree));
|
||||
metricList.add(buildScaleMetric(EFFICIENCY_METRIC_TIME_UTILIZATION, "时间利用率", "%",
|
||||
currentTimeUtilization, previousTimeUtilization));
|
||||
metricList.add(buildScaleMetric(EFFICIENCY_METRIC_GUN_AVG_ELECTRICITY, "枪均电量", "度",
|
||||
currentGunAvgElectricity, previousGunAvgElectricity));
|
||||
metricList.add(buildScaleMetric(EFFICIENCY_METRIC_POWER_UTILIZATION, "功率利用率", "%",
|
||||
currentPowerUtilization, previousPowerUtilization));
|
||||
|
||||
// 构建选中指标的曲线图数据
|
||||
String selectedMetricCode = StringUtils.isBlank(dto.getSelectedMetricCode())
|
||||
? EFFICIENCY_METRIC_AVG_SERVICE_FEE_PER_DEGREE : dto.getSelectedMetricCode();
|
||||
BusinessScaleChartVO chartData = buildEfficiencyChartFromMaps(
|
||||
selectedMetricCode, range, currentDailyMap, previousDailyMap,
|
||||
connectorCount, totalRatedPower);
|
||||
|
||||
return BusinessEfficiencyVO.builder()
|
||||
.currentStartTime(range.getCurrentStart())
|
||||
.currentEndTime(range.getCurrentEnd())
|
||||
.previousStartTime(range.getPreviousStart())
|
||||
.previousEndTime(range.getPreviousEnd())
|
||||
.metricList(metricList)
|
||||
.chartData(chartData)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建经营效率日期区间
|
||||
*/
|
||||
private BusinessOperationDateRangeDTO buildDateRangeFromEfficiency(BusinessEfficiencyQueryDTO dto) {
|
||||
try {
|
||||
LocalDate currentStart = LocalDate.parse(dto.getStartTime());
|
||||
LocalDate currentEnd = LocalDate.parse(dto.getEndTime());
|
||||
if (currentEnd.isBefore(currentStart)) {
|
||||
throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR);
|
||||
}
|
||||
long days = ChronoUnit.DAYS.between(currentStart, currentEnd) + 1;
|
||||
LocalDate previousEnd = currentStart.minusDays(1);
|
||||
LocalDate previousStart = previousEnd.minusDays(days - 1);
|
||||
return BusinessOperationDateRangeDTO.builder()
|
||||
.currentStart(currentStart.toString())
|
||||
.currentEnd(currentEnd.toString())
|
||||
.previousStart(previousStart.toString())
|
||||
.previousEnd(previousEnd.toString())
|
||||
.build();
|
||||
} catch (BusinessException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建枪口统计信息(枪口数量 + 总额定功率)
|
||||
*/
|
||||
private ConnectorStats buildConnectorStats(List<String> stationIdList) {
|
||||
List<ConnectorInfoVO> connectors;
|
||||
if (stationIdList == null) {
|
||||
// 平台账号:先查询所有站点ID,再批量查询枪口信息
|
||||
List<PileStationInfo> allStations = pileStationInfoService.selectPileStationInfoList(new PileStationInfo());
|
||||
List<String> allStationIds = allStations.stream()
|
||||
.map(s -> String.valueOf(s.getId()))
|
||||
.collect(Collectors.toList());
|
||||
if (allStationIds.isEmpty()) {
|
||||
return new ConnectorStats(0, BigDecimal.ZERO);
|
||||
}
|
||||
connectors = pileConnectorInfoService.batchSelectConnectorList(allStationIds);
|
||||
} else if (stationIdList.isEmpty()) {
|
||||
return new ConnectorStats(0, BigDecimal.ZERO);
|
||||
} else {
|
||||
connectors = pileConnectorInfoService.batchSelectConnectorList(stationIdList);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isEmpty(connectors)) {
|
||||
return new ConnectorStats(0, BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
BigDecimal totalRatedPower = BigDecimal.ZERO;
|
||||
for (ConnectorInfoVO connector : connectors) {
|
||||
totalRatedPower = totalRatedPower.add(BigDecimalUtils.parseOrZero(connector.getRatedPower()));
|
||||
}
|
||||
|
||||
return new ConnectorStats(connectors.size(), totalRatedPower);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算时间利用率(%)
|
||||
* = 总充电时长(分钟) / (枪口数 × 天数 × 1440分钟) × 100
|
||||
*/
|
||||
private BigDecimal calculateTimeUtilization(BigDecimal chargeTime, int connectorCount, long dayCount) {
|
||||
if (connectorCount == 0 || dayCount == 0) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
BigDecimal totalAvailableMinutes = BigDecimal.valueOf(connectorCount)
|
||||
.multiply(BigDecimal.valueOf(dayCount))
|
||||
.multiply(new BigDecimal("1440"));
|
||||
BigDecimal utilization = BigDecimalUtils.safeDivide(
|
||||
BigDecimalUtils.nullToZero(chargeTime), totalAvailableMinutes, 4);
|
||||
return utilization.multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算功率利用率(%)
|
||||
* = 实际总能量 / 理论最大总能量 × 100
|
||||
* = useElectricity / (总额定功率 × 天数 × 24) × 100
|
||||
*/
|
||||
private BigDecimal calculatePowerUtilization(BigDecimal useElectricity, BigDecimal chargeTime,
|
||||
int connectorCount, long dayCount, BigDecimal totalRatedPower) {
|
||||
if (totalRatedPower.compareTo(BigDecimal.ZERO) == 0 || dayCount == 0) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
BigDecimal theoreticalMaxEnergy = totalRatedPower
|
||||
.multiply(BigDecimal.valueOf(dayCount))
|
||||
.multiply(new BigDecimal("24"));
|
||||
BigDecimal utilization = BigDecimalUtils.safeDivide(
|
||||
BigDecimalUtils.nullToZero(useElectricity), theoreticalMaxEnergy, 4);
|
||||
return utilization.multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从dailyMap构建经营效率曲线图数据
|
||||
* 每个指标按天计算(度均服务费=当天服务费/当天电量, 时间利用率=当天充电时长/可用时长, 等)
|
||||
*/
|
||||
private BusinessScaleChartVO buildEfficiencyChartFromMaps(String metricCode,
|
||||
BusinessOperationDateRangeDTO range,
|
||||
Map<String, SettleOrderReport> currentDailyMap,
|
||||
Map<String, SettleOrderReport> previousDailyMap,
|
||||
int connectorCount,
|
||||
BigDecimal totalRatedPower) {
|
||||
String metricName;
|
||||
String unit;
|
||||
switch (metricCode) {
|
||||
case EFFICIENCY_METRIC_TIME_UTILIZATION:
|
||||
metricName = "时间利用率";
|
||||
unit = "%";
|
||||
break;
|
||||
case EFFICIENCY_METRIC_GUN_AVG_ELECTRICITY:
|
||||
metricName = "枪均电量";
|
||||
unit = "度";
|
||||
break;
|
||||
case EFFICIENCY_METRIC_POWER_UTILIZATION:
|
||||
metricName = "功率利用率";
|
||||
unit = "%";
|
||||
break;
|
||||
default:
|
||||
metricName = "度均服务费";
|
||||
unit = "元";
|
||||
break;
|
||||
}
|
||||
|
||||
LocalDate currentStart = LocalDate.parse(range.getCurrentStart());
|
||||
LocalDate currentEnd = LocalDate.parse(range.getCurrentEnd());
|
||||
LocalDate previousStart = LocalDate.parse(range.getPreviousStart());
|
||||
|
||||
long dayCount = ChronoUnit.DAYS.between(currentStart, currentEnd) + 1;
|
||||
DateTimeFormatter displayFormatter = DateTimeFormatter.ofPattern("MM/dd");
|
||||
|
||||
List<BusinessScaleChartVO.ChartPoint> chartPoints = new ArrayList<>();
|
||||
for (long i = 0; i < dayCount; i++) {
|
||||
LocalDate currentDate = currentStart.plusDays(i);
|
||||
LocalDate previousDate = previousStart.plusDays(i);
|
||||
|
||||
SettleOrderReport currentReport = currentDailyMap.get(currentDate.toString());
|
||||
SettleOrderReport previousReport = previousDailyMap.get(previousDate.toString());
|
||||
|
||||
BigDecimal currentValue = calculateEfficiencyMetricValue(
|
||||
metricCode, currentReport, connectorCount, 1, totalRatedPower);
|
||||
BigDecimal previousValue = calculateEfficiencyMetricValue(
|
||||
metricCode, previousReport, connectorCount, 1, totalRatedPower);
|
||||
|
||||
chartPoints.add(BusinessScaleChartVO.ChartPoint.builder()
|
||||
.date(currentDate.format(displayFormatter))
|
||||
.fullDate(currentDate.toString())
|
||||
.value(BigDecimalUtils.normalize(currentValue))
|
||||
.previousValue(BigDecimalUtils.normalize(previousValue))
|
||||
.changeRate(BigDecimalUtils.calculateRate(
|
||||
BigDecimalUtils.nullToZero(currentValue),
|
||||
BigDecimalUtils.nullToZero(previousValue)))
|
||||
.build());
|
||||
}
|
||||
|
||||
return BusinessScaleChartVO.builder()
|
||||
.metricCode(metricCode)
|
||||
.metricName(metricName)
|
||||
.unit(unit)
|
||||
.chartData(chartPoints)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据指标编码计算单条报表记录对应的经营效率指标值
|
||||
*/
|
||||
private BigDecimal calculateEfficiencyMetricValue(String metricCode, SettleOrderReport report,
|
||||
int connectorCount, long dayCount,
|
||||
BigDecimal totalRatedPower) {
|
||||
if (report == null) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
BigDecimal serviceAmount = BigDecimalUtils.nullToZero(report.getServiceAmount());
|
||||
BigDecimal useElectricity = BigDecimalUtils.nullToZero(report.getUseElectricity());
|
||||
BigDecimal chargeTime = BigDecimalUtils.parseOrZero(report.getChargeTime());
|
||||
|
||||
switch (metricCode) {
|
||||
case EFFICIENCY_METRIC_AVG_SERVICE_FEE_PER_DEGREE:
|
||||
// 度均服务费 = 服务费 / 用电量
|
||||
return BigDecimalUtils.safeDivide(serviceAmount, useElectricity, 2);
|
||||
case EFFICIENCY_METRIC_TIME_UTILIZATION:
|
||||
// 时间利用率 = 充电时长 / (枪口数 × 1天 × 1440) × 100
|
||||
return calculateTimeUtilization(chargeTime, connectorCount, dayCount);
|
||||
case EFFICIENCY_METRIC_GUN_AVG_ELECTRICITY:
|
||||
// 枪均电量 = 用电量 / 枪口数
|
||||
return connectorCount > 0
|
||||
? BigDecimalUtils.safeDivide(useElectricity, BigDecimal.valueOf(connectorCount), 2)
|
||||
: BigDecimal.ZERO;
|
||||
case EFFICIENCY_METRIC_POWER_UTILIZATION:
|
||||
// 功率利用率 = 用电量 / (总额定功率 × 1天 × 24) × 100
|
||||
return calculatePowerUtilization(useElectricity, chargeTime,
|
||||
connectorCount, dayCount, totalRatedPower);
|
||||
default:
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 枪口统计信息内部类
|
||||
*/
|
||||
private static class ConnectorStats {
|
||||
private final int connectorCount;
|
||||
private final BigDecimal totalRatedPower;
|
||||
|
||||
ConnectorStats(int connectorCount, BigDecimal totalRatedPower) {
|
||||
this.connectorCount = connectorCount;
|
||||
this.totalRatedPower = totalRatedPower;
|
||||
}
|
||||
|
||||
int getConnectorCount() {
|
||||
return connectorCount;
|
||||
}
|
||||
|
||||
BigDecimal getTotalRatedPower() {
|
||||
return totalRatedPower;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3503,7 +3503,7 @@ public class OrderBasicInfoServiceImpl implements OrderBasicInfoService {
|
||||
logger.debug("redis中没有实时数据了,去数据库查");
|
||||
// redis中为空,去查库
|
||||
OrderMonitorData orderMonitorData = orderMonitorDataService.selectByTransactionCode(transactionCode);
|
||||
if (orderMonitorData != null) {
|
||||
if (orderMonitorData != null && StringUtils.isNotBlank(orderMonitorData.getMonitorData())) {
|
||||
String monitorData = orderMonitorData.getMonitorData();
|
||||
List<RealTimeMonitorData> dataList = JSON.parseArray(monitorData, RealTimeMonitorData.class);
|
||||
resultList.addAll(dataList);
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
package com.jsowell.pile.vo.uniapp.business;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 效率分析VO(包含单均效率和枪均效率两个维度的数据)
|
||||
*
|
||||
* @author Lemon
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class BusinessEfficiencyAnalysisVO {
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
private String startTime;
|
||||
|
||||
/**
|
||||
* 结束时间
|
||||
*/
|
||||
private String endTime;
|
||||
|
||||
// ========== 单均效率指标 ==========
|
||||
|
||||
/**
|
||||
* 单均服务费(元)
|
||||
* = 服务费总额 / 订单数量
|
||||
*/
|
||||
private BigDecimal avgServiceFeePerOrder;
|
||||
|
||||
/**
|
||||
* 单均充电量(度)
|
||||
* = 充电电量总量 / 订单数量
|
||||
*/
|
||||
private BigDecimal avgElectricityPerOrder;
|
||||
|
||||
/**
|
||||
* 单均充电时长,格式:xxm
|
||||
* = 总充电时长(分钟) / 订单数量
|
||||
*/
|
||||
private String avgChargeTimePerOrder;
|
||||
|
||||
// ========== 枪均效率指标 ==========
|
||||
|
||||
/**
|
||||
* 枪日均服务费(元)
|
||||
* = 服务费总额 / (枪口数量 × 天数)
|
||||
*/
|
||||
private BigDecimal gunDailyAvgServiceFee;
|
||||
|
||||
/**
|
||||
* 枪日均充电量(度)
|
||||
* = 充电电量总量 / (枪口数量 × 天数)
|
||||
*/
|
||||
private BigDecimal gunDailyAvgElectricity;
|
||||
|
||||
/**
|
||||
* 枪日均充电时长,格式:xxhxxm
|
||||
* = 总充电时长(分钟) / (枪口数量 × 天数)
|
||||
*/
|
||||
private String gunDailyAvgChargeTime;
|
||||
|
||||
// ========== 共用指标 ==========
|
||||
|
||||
/**
|
||||
* 度均服务费(元)
|
||||
* = 服务费总额 / 充电电量总量
|
||||
*/
|
||||
private BigDecimal avgServiceFeePerDegree;
|
||||
|
||||
/**
|
||||
* 平均功率(KW)
|
||||
* = 充电电量总量 × 60 / 总充电时长(分钟)
|
||||
*/
|
||||
private BigDecimal avgPower;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.jsowell.pile.vo.uniapp.business;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 经营效率VO
|
||||
*
|
||||
* @author zhangziao
|
||||
* @date 2026/4/16
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class BusinessEfficiencyVO {
|
||||
|
||||
/**
|
||||
* 当前周期开始时间
|
||||
*/
|
||||
private String currentStartTime;
|
||||
|
||||
/**
|
||||
* 当前周期结束时间
|
||||
*/
|
||||
private String currentEndTime;
|
||||
|
||||
/**
|
||||
* 上周期开始时间
|
||||
*/
|
||||
private String previousStartTime;
|
||||
|
||||
/**
|
||||
* 上周期结束时间
|
||||
*/
|
||||
private String previousEndTime;
|
||||
|
||||
/**
|
||||
* 指标卡片列表(度均服务费、时间利用率、枪均电量、功率利用率)
|
||||
*/
|
||||
private List<BusinessScaleMetricVO> metricList;
|
||||
|
||||
/**
|
||||
* 当前选中指标对应的曲线图数据
|
||||
*/
|
||||
private BusinessScaleChartVO chartData;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.jsowell.pile.vo.uniapp.business;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 场站排行VO
|
||||
*
|
||||
* @author zhangziao
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
public class BusinessStationRankVO {
|
||||
|
||||
/**
|
||||
* 排行名次
|
||||
*/
|
||||
private Integer rank;
|
||||
|
||||
/**
|
||||
* 站点ID
|
||||
*/
|
||||
private String stationId;
|
||||
|
||||
/**
|
||||
* 场站名称
|
||||
*/
|
||||
private String stationName;
|
||||
|
||||
/**
|
||||
* 订单总数
|
||||
*/
|
||||
private Integer orderCount;
|
||||
}
|
||||
Reference in New Issue
Block a user