From 19c89db26534758ef1872d79d5edc847a176d2bf Mon Sep 17 00:00:00 2001 From: Lemon Date: Wed, 1 Apr 2026 14:13:29 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20=E8=BF=90=E8=90=A5?= =?UTF-8?q?=E8=AF=8A=E6=96=AD=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../business/BusinessFinancialController.java | 41 ++++ .../jsowell/common/util/BigDecimalUtils.java | 100 ++++++++ .../BusinessOperationAnalysisQueryDTO.java | 41 ++++ .../BusinessOperationDateRangeDTO.java | 39 +++ .../business/BusinessOperationSummaryDTO.java | 55 +++++ .../service/BusinessFinancialService.java | 10 + .../impl/BusinessFinancialServiceImpl.java | 222 ++++++++++++++++++ .../business/BusinessOperationAnalysisVO.java | 51 ++++ .../BusinessOperationDiagnosisItemVO.java | 61 +++++ .../business/BusinessOperationMetricVO.java | 51 ++++ 10 files changed, 671 insertions(+) create mode 100644 jsowell-common/src/main/java/com/jsowell/common/util/BigDecimalUtils.java create mode 100644 jsowell-pile/src/main/java/com/jsowell/pile/dto/business/BusinessOperationAnalysisQueryDTO.java create mode 100644 jsowell-pile/src/main/java/com/jsowell/pile/dto/business/BusinessOperationDateRangeDTO.java create mode 100644 jsowell-pile/src/main/java/com/jsowell/pile/dto/business/BusinessOperationSummaryDTO.java create mode 100644 jsowell-pile/src/main/java/com/jsowell/pile/vo/uniapp/business/BusinessOperationAnalysisVO.java create mode 100644 jsowell-pile/src/main/java/com/jsowell/pile/vo/uniapp/business/BusinessOperationDiagnosisItemVO.java create mode 100644 jsowell-pile/src/main/java/com/jsowell/pile/vo/uniapp/business/BusinessOperationMetricVO.java diff --git a/jsowell-admin/src/main/java/com/jsowell/api/uniapp/business/BusinessFinancialController.java b/jsowell-admin/src/main/java/com/jsowell/api/uniapp/business/BusinessFinancialController.java index dab69e459..6d6d4e70a 100644 --- a/jsowell-admin/src/main/java/com/jsowell/api/uniapp/business/BusinessFinancialController.java +++ b/jsowell-admin/src/main/java/com/jsowell/api/uniapp/business/BusinessFinancialController.java @@ -8,7 +8,9 @@ import com.jsowell.common.exception.BusinessException; import com.jsowell.common.response.RestApiResponse; import com.jsowell.pile.dto.MerchantOrderReportDTO; import com.jsowell.pile.dto.ParkingCouponRecordQueryDTO; +import com.jsowell.pile.dto.business.BusinessOperationAnalysisQueryDTO; import com.jsowell.pile.service.BusinessFinancialService; +import com.jsowell.pile.vo.uniapp.business.BusinessOperationAnalysisVO; import com.jsowell.pile.vo.web.MerchantOrderReportVO; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -87,4 +89,43 @@ public class BusinessFinancialController extends BaseController { } return response; } + + /** + * 查询经营分析 + * + * @param dto 查询参数 + * @return 经营分析 + */ + @PostMapping("/operationAnalysis") + public RestApiResponse getBusinessOperationAnalysis(@RequestBody BusinessOperationAnalysisQueryDTO dto) { + logger.info("查询经营分析 params:{}", JSONObject.toJSONString(dto)); + RestApiResponse response; + try { + validateBusinessOperationQuery(dto); + BusinessOperationAnalysisVO result = businessFinancialService.getBusinessOperationAnalysis(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 查询参数 + */ + private void validateBusinessOperationQuery(BusinessOperationAnalysisQueryDTO dto) { + if (dto == null + || StringUtils.isBlank(dto.getStartTime()) + || StringUtils.isBlank(dto.getEndTime())) { + throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR); + } + } } diff --git a/jsowell-common/src/main/java/com/jsowell/common/util/BigDecimalUtils.java b/jsowell-common/src/main/java/com/jsowell/common/util/BigDecimalUtils.java new file mode 100644 index 000000000..27371878a --- /dev/null +++ b/jsowell-common/src/main/java/com/jsowell/common/util/BigDecimalUtils.java @@ -0,0 +1,100 @@ +package com.jsowell.common.util; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +/** + * BigDecimal工具类 + * + * @author Auto + * @Date 2026/4/1 + */ +public class BigDecimalUtils { + + /** + * 工具类不允许实例化 + */ + private BigDecimalUtils() { + } + + /** + * 空值转零 + * + * @param value 原始值 + * @return 非空数值 + */ + public static BigDecimal nullToZero(BigDecimal value) { + return value == null ? BigDecimal.ZERO : value; + } + + /** + * 安全除法 + * + * @param dividend 被除数 + * @param divisor 除数 + * @param scale 保留小数位 + * @return 计算结果 + */ + public static BigDecimal safeDivide(BigDecimal dividend, BigDecimal divisor, int scale) { + BigDecimal safeDividend = nullToZero(dividend); + BigDecimal safeDivisor = nullToZero(divisor); + if (safeDivisor.compareTo(BigDecimal.ZERO) == 0) { + return BigDecimal.ZERO; + } + return safeDividend.divide(safeDivisor, scale, RoundingMode.HALF_UP); + } + + /** + * 标准化数值显示 + * + * @param value 原始值 + * @return 标准化后的数值 + */ + public static BigDecimal normalize(BigDecimal value) { + BigDecimal safeValue = nullToZero(value); + if (safeValue.compareTo(BigDecimal.ZERO) == 0) { + return BigDecimal.ZERO; + } + return safeValue.stripTrailingZeros(); + } + + /** + * 将字符串安全转换为BigDecimal + * + * @param value 原始字符串 + * @return BigDecimal值 + */ + public static BigDecimal parseOrZero(String value) { + if (StringUtils.isBlank(value)) { + return BigDecimal.ZERO; + } + try { + return new BigDecimal(value.trim()); + } catch (Exception e) { + return BigDecimal.ZERO; + } + } + + /** + * 计算环比百分比 + * + * @param currentValue 当前周期值 + * @param previousValue 上周期值 + * @return 环比字符串 + */ + public static String calculateRate(BigDecimal currentValue, BigDecimal previousValue) { + BigDecimal safeCurrentValue = nullToZero(currentValue); + BigDecimal safePreviousValue = nullToZero(previousValue); + if (safePreviousValue.compareTo(BigDecimal.ZERO) == 0) { + return "0%"; + } + BigDecimal rate = safeCurrentValue.subtract(safePreviousValue) + .divide(safePreviousValue, 4, RoundingMode.HALF_UP) + .multiply(new BigDecimal("100")); + BigDecimal normalizedRate = normalize(rate); + if (normalizedRate.compareTo(BigDecimal.ZERO) > 0) { + return "+" + normalizedRate.toPlainString() + "%"; + } + return normalizedRate.toPlainString() + "%"; + } +} diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/dto/business/BusinessOperationAnalysisQueryDTO.java b/jsowell-pile/src/main/java/com/jsowell/pile/dto/business/BusinessOperationAnalysisQueryDTO.java new file mode 100644 index 000000000..e172e2891 --- /dev/null +++ b/jsowell-pile/src/main/java/com/jsowell/pile/dto/business/BusinessOperationAnalysisQueryDTO.java @@ -0,0 +1,41 @@ +package com.jsowell.pile.dto.business; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * 经营状态/经营诊断查询DTO + * + * @author Auto + * @Date 2026/4/1 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class BusinessOperationAnalysisQueryDTO { + + /** + * 开始时间,格式:yyyy-MM-dd + */ + private String startTime; + + /** + * 结束时间,格式:yyyy-MM-dd + */ + private String endTime; + + /** + * 站点id列表 + */ + private List stationIdList; + + /** + * 当前选中的指标编码 + */ + private String selectedMetricCode; +} diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/dto/business/BusinessOperationDateRangeDTO.java b/jsowell-pile/src/main/java/com/jsowell/pile/dto/business/BusinessOperationDateRangeDTO.java new file mode 100644 index 000000000..5fe90a8f7 --- /dev/null +++ b/jsowell-pile/src/main/java/com/jsowell/pile/dto/business/BusinessOperationDateRangeDTO.java @@ -0,0 +1,39 @@ +package com.jsowell.pile.dto.business; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 经营分析日期区间DTO + * + * @author Auto + * @Date 2026/4/1 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class BusinessOperationDateRangeDTO { + + /** + * 当前周期开始时间 + */ + private String currentStart; + + /** + * 当前周期结束时间 + */ + private String currentEnd; + + /** + * 上周期开始时间 + */ + private String previousStart; + + /** + * 上周期结束时间 + */ + private String previousEnd; +} diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/dto/business/BusinessOperationSummaryDTO.java b/jsowell-pile/src/main/java/com/jsowell/pile/dto/business/BusinessOperationSummaryDTO.java new file mode 100644 index 000000000..a237b2b30 --- /dev/null +++ b/jsowell-pile/src/main/java/com/jsowell/pile/dto/business/BusinessOperationSummaryDTO.java @@ -0,0 +1,55 @@ +package com.jsowell.pile.dto.business; + +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 经营分析汇总DTO + * + * @author Auto + * @Date 2026/4/1 + */ +@Data +public class BusinessOperationSummaryDTO { + + /** + * 订单总额 + */ + private BigDecimal orderAmount = BigDecimal.ZERO; + + /** + * 服务费总额 + */ + private BigDecimal serviceAmount = BigDecimal.ZERO; + + /** + * 总用电度数 + */ + private BigDecimal useElectricity = BigDecimal.ZERO; + + /** + * 订单量 + */ + private BigDecimal orderCount = BigDecimal.ZERO; + + /** + * 总充电时长 + */ + private BigDecimal chargeTime = BigDecimal.ZERO; + + /** + * 单均服务费 + */ + private BigDecimal avgServiceFee = BigDecimal.ZERO; + + /** + * 单均度数 + */ + private BigDecimal avgElectricity = BigDecimal.ZERO; + + /** + * 单均充电时长 + */ + private BigDecimal avgChargeTime = BigDecimal.ZERO; +} diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/BusinessFinancialService.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/BusinessFinancialService.java index 5f12db792..4b306a772 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/BusinessFinancialService.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/BusinessFinancialService.java @@ -3,6 +3,8 @@ package com.jsowell.pile.service; 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.vo.uniapp.business.BusinessOperationAnalysisVO; import com.jsowell.pile.vo.web.MerchantOrderReportVO; import com.jsowell.pile.vo.web.ParkingCouponRecordVO; @@ -16,4 +18,12 @@ public interface BusinessFinancialService { * @return 分页结果 */ PageResponse queryParkingCouponRecords(ParkingCouponRecordQueryDTO dto); + + /** + * 查询经营分析 + * + * @param dto 查询条件 + * @return 经营分析 + */ + BusinessOperationAnalysisVO getBusinessOperationAnalysis(BusinessOperationAnalysisQueryDTO dto); } diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/BusinessFinancialServiceImpl.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/BusinessFinancialServiceImpl.java index 2e069d914..550cee72d 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/BusinessFinancialServiceImpl.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/BusinessFinancialServiceImpl.java @@ -5,23 +5,37 @@ import com.github.pagehelper.PageInfo; import com.huifu.adapay.core.exception.BaseAdaPayException; import com.jsowell.adapay.service.AdapayService; import com.jsowell.adapay.vo.AdapayAccountBalanceVO; +import com.jsowell.common.util.BigDecimalUtils; import com.jsowell.common.core.domain.vo.AuthorizedDeptVO; import com.jsowell.common.core.page.PageResponse; +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.BusinessOperationAnalysisQueryDTO; +import com.jsowell.pile.dto.business.BusinessOperationDateRangeDTO; +import com.jsowell.pile.dto.business.BusinessOperationSummaryDTO; +import com.jsowell.pile.domain.SettleOrderReport; import com.jsowell.pile.service.BusinessFinancialService; import com.jsowell.pile.service.CarCouponRecordService; import com.jsowell.pile.service.ClearingWithdrawInfoService; import com.jsowell.pile.service.PileStationInfoService; import com.jsowell.pile.service.SettleOrderReportService; import com.jsowell.pile.util.UserUtils; +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.web.MerchantOrderReportVO; import com.jsowell.pile.vo.web.ParkingCouponRecordVO; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; import java.util.List; /** @@ -31,6 +45,13 @@ import java.util.List; @Service public class BusinessFinancialServiceImpl implements BusinessFinancialService { + private static final String METRIC_ORDER_AMOUNT = "ORDER_AMOUNT"; + private static final String METRIC_AVG_SERVICE_FEE = "AVG_SERVICE_FEE"; + private static final String METRIC_AVG_ELECTRICITY = "AVG_ELECTRICITY"; + private static final String FACTOR_ORDER_COUNT = "ORDER_COUNT"; + private static final String FACTOR_AVG_ELECTRICITY = "AVG_ELECTRICITY"; + private static final String FACTOR_AVG_CHARGE_TIME = "AVG_CHARGE_TIME"; + @Autowired private SettleOrderReportService settleOrderReportService; @@ -148,4 +169,205 @@ public class BusinessFinancialServiceImpl implements BusinessFinancialService { .total(pageInfo.getTotal()) .build(); } + + /** + * 查询经营分析 + * + * @param dto 查询条件 + * @return 经营分析 + */ + @Override + public BusinessOperationAnalysisVO getBusinessOperationAnalysis(BusinessOperationAnalysisQueryDTO dto) { + BusinessOperationDateRangeDTO range = buildDateRange(dto); + List stationIdList = resolveStationIds(dto.getStationIdList()); + BusinessOperationSummaryDTO currentSummary = buildOperationSummary( + stationIdList, range.getCurrentStart(), range.getCurrentEnd()); + BusinessOperationSummaryDTO previousSummary = buildOperationSummary( + stationIdList, range.getPreviousStart(), range.getPreviousEnd()); + + List metricList = new ArrayList<>(); + metricList.add(buildMetric(METRIC_ORDER_AMOUNT, "订单总额", + currentSummary.getOrderAmount(), previousSummary.getOrderAmount())); + metricList.add(buildMetric(METRIC_AVG_SERVICE_FEE, "单均服务费", + currentSummary.getAvgServiceFee(), previousSummary.getAvgServiceFee())); + metricList.add(buildMetric(METRIC_AVG_ELECTRICITY, "单均度数", + currentSummary.getAvgElectricity(), previousSummary.getAvgElectricity())); + + BusinessOperationDiagnosisItemVO diagnosisItem = buildSelectedDiagnosisItem(dto, currentSummary, previousSummary); + + return BusinessOperationAnalysisVO.builder() + .currentStartTime(range.getCurrentStart()) + .currentEndTime(range.getCurrentEnd()) + .previousStartTime(range.getPreviousStart()) + .previousEndTime(range.getPreviousEnd()) + .metricList(metricList) + .diagnosisItem(diagnosisItem) + .build(); + } + + /** + * 构建当前选中指标对应的最大影响因素 + * + * @param dto 查询条件 + * @param currentSummary 当前周期汇总 + * @param previousSummary 上周期汇总 + * @return 经营诊断指标 + */ + private BusinessOperationDiagnosisItemVO buildSelectedDiagnosisItem(BusinessOperationAnalysisQueryDTO dto, + BusinessOperationSummaryDTO currentSummary, + BusinessOperationSummaryDTO previousSummary) { + String selectedMetricCode = dto.getSelectedMetricCode(); + if (METRIC_AVG_SERVICE_FEE.equals(selectedMetricCode)) { + return buildDiagnosis(METRIC_AVG_SERVICE_FEE, "单均服务费", + FACTOR_AVG_ELECTRICITY, "单均度数", + currentSummary.getAvgElectricity(), previousSummary.getAvgElectricity()); + } + if (METRIC_AVG_ELECTRICITY.equals(selectedMetricCode)) { + return buildDiagnosis(METRIC_AVG_ELECTRICITY, "单均度数", + FACTOR_AVG_CHARGE_TIME, "单均充电时长", + currentSummary.getAvgChargeTime(), previousSummary.getAvgChargeTime()); + } + return buildDiagnosis(METRIC_ORDER_AMOUNT, "订单总额", + FACTOR_ORDER_COUNT, "订单量", + currentSummary.getOrderCount(), previousSummary.getOrderCount()); + } + + /** + * 构建经营状态指标项 + * + * @param metricCode 指标编码 + * @param metricName 指标名称 + * @param currentValue 当前周期值 + * @param previousValue 上周期值 + * @return 经营状态指标 + */ + private BusinessOperationMetricVO buildMetric(String metricCode, String metricName, + BigDecimal currentValue, BigDecimal previousValue) { + BigDecimal safeCurrentValue = BigDecimalUtils.nullToZero(currentValue); + BigDecimal safePreviousValue = BigDecimalUtils.nullToZero(previousValue); + BigDecimal changeValue = BigDecimalUtils.normalize(safeCurrentValue.subtract(safePreviousValue)); + return BusinessOperationMetricVO.builder() + .metricCode(metricCode) + .metricName(metricName) + .currentValue(BigDecimalUtils.normalize(safeCurrentValue)) + .previousValue(BigDecimalUtils.normalize(safePreviousValue)) + .changeValue(changeValue) + .changeRate(BigDecimalUtils.calculateRate(safeCurrentValue, safePreviousValue)) + .build(); + } + + /** + * 构建经营诊断指标项 + * + * @param metricCode 指标编码 + * @param metricName 指标名称 + * @param factorCode 影响因素编码 + * @param factorName 影响因素名称 + * @param currentValue 当前周期值 + * @param previousValue 上周期值 + * @return 经营诊断指标 + */ + private BusinessOperationDiagnosisItemVO buildDiagnosis(String metricCode, String metricName, + String factorCode, String factorName, + BigDecimal currentValue, BigDecimal previousValue) { + BigDecimal safeCurrentValue = BigDecimalUtils.nullToZero(currentValue); + BigDecimal safePreviousValue = BigDecimalUtils.nullToZero(previousValue); + BigDecimal changeValue = BigDecimalUtils.normalize(safeCurrentValue.subtract(safePreviousValue)); + return BusinessOperationDiagnosisItemVO.builder() + .metricCode(metricCode) + .metricName(metricName) + .factorCode(factorCode) + .factorName(factorName) + .currentValue(BigDecimalUtils.normalize(safeCurrentValue)) + .previousValue(BigDecimalUtils.normalize(safePreviousValue)) + .changeValue(changeValue) + .changeRate(BigDecimalUtils.calculateRate(safeCurrentValue, safePreviousValue)) + .build(); + } + + /** + * 根据查询条件构建当前周期和上周期日期区间 + * + * @param dto 查询条件 + * @return 日期区间 + */ + private BusinessOperationDateRangeDTO buildDateRange(BusinessOperationAnalysisQueryDTO 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); + } + } + + /** + * 解析本次查询可用的站点ID列表 + * + * @param stationIdList 前端传入站点ID列表 + * @return 实际查询站点ID列表 + */ + private List resolveStationIds(List stationIdList) { + if (!CollectionUtils.isEmpty(stationIdList)) { + return stationIdList; + } + try { + AuthorizedDeptVO authorizedMap = UserUtils.getAuthorizedMap(); + if (authorizedMap == null) { + return stationIdList; + } + if (!CollectionUtils.isEmpty(authorizedMap.getStationDeptIds())) { + return pileStationInfoService.queryByStationDeptIds(authorizedMap.getStationDeptIds()); + } + if (!CollectionUtils.isEmpty(authorizedMap.getMerchantDeptIds())) { + return pileStationInfoService.getStationIdsByMerchantIds(authorizedMap.getMerchantDeptIds()); + } + } catch (Exception e) { + log.warn("解析经营分析站点权限失败", e); + } + return stationIdList; + } + + /** + * 汇总指定周期内的经营指标 + * + * @param stationIdList 站点ID列表 + * @param startTime 开始时间 + * @param endTime 结束时间 + * @return 汇总结果 + */ + private BusinessOperationSummaryDTO buildOperationSummary(List stationIdList, + String startTime, + String endTime) { + List reportList = settleOrderReportService.queryOrderReport( + stationIdList, startTime, endTime); + if (CollectionUtils.isEmpty(reportList)) { + return new BusinessOperationSummaryDTO(); + } + BusinessOperationSummaryDTO summary = new BusinessOperationSummaryDTO(); + for (SettleOrderReport report : reportList) { + summary.setOrderAmount(summary.getOrderAmount().add(BigDecimalUtils.nullToZero(report.getTotalAmount()))); + summary.setServiceAmount(summary.getServiceAmount().add(BigDecimalUtils.nullToZero(report.getServiceAmount()))); + summary.setUseElectricity(summary.getUseElectricity().add(BigDecimalUtils.nullToZero(report.getUseElectricity()))); + summary.setOrderCount(summary.getOrderCount().add(BigDecimalUtils.parseOrZero(report.getChargeNum()))); + summary.setChargeTime(summary.getChargeTime().add(BigDecimalUtils.parseOrZero(report.getChargeTime()))); + } + summary.setAvgServiceFee(BigDecimalUtils.safeDivide(summary.getServiceAmount(), summary.getOrderCount(), 2)); + summary.setAvgElectricity(BigDecimalUtils.safeDivide(summary.getUseElectricity(), summary.getOrderCount(), 2)); + summary.setAvgChargeTime(BigDecimalUtils.safeDivide(summary.getChargeTime(), summary.getOrderCount(), 2)); + return summary; + } } diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/vo/uniapp/business/BusinessOperationAnalysisVO.java b/jsowell-pile/src/main/java/com/jsowell/pile/vo/uniapp/business/BusinessOperationAnalysisVO.java new file mode 100644 index 000000000..1a0893bdc --- /dev/null +++ b/jsowell-pile/src/main/java/com/jsowell/pile/vo/uniapp/business/BusinessOperationAnalysisVO.java @@ -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 Auto + * @Date 2026/4/1 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class BusinessOperationAnalysisVO { + + /** + * 当前周期开始时间 + */ + private String currentStartTime; + + /** + * 当前周期结束时间 + */ + private String currentEndTime; + + /** + * 上周期开始时间 + */ + private String previousStartTime; + + /** + * 上周期结束时间 + */ + private String previousEndTime; + + /** + * 顶部指标列表 + */ + private List metricList; + + /** + * 当前选中指标对应的最大影响因素 + */ + private BusinessOperationDiagnosisItemVO diagnosisItem; +} diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/vo/uniapp/business/BusinessOperationDiagnosisItemVO.java b/jsowell-pile/src/main/java/com/jsowell/pile/vo/uniapp/business/BusinessOperationDiagnosisItemVO.java new file mode 100644 index 000000000..ac66d2ca3 --- /dev/null +++ b/jsowell-pile/src/main/java/com/jsowell/pile/vo/uniapp/business/BusinessOperationDiagnosisItemVO.java @@ -0,0 +1,61 @@ +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 Auto + * @Date 2026/4/1 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class BusinessOperationDiagnosisItemVO { + + /** + * 指标编码 + */ + private String metricCode; + + /** + * 指标名称 + */ + private String metricName; + + /** + * 最大影响因素编码 + */ + private String factorCode; + + /** + * 最大影响因素名称 + */ + private String factorName; + + /** + * 当前周期值 + */ + private BigDecimal currentValue; + + /** + * 上周期值 + */ + private BigDecimal previousValue; + + /** + * 变化值 + */ + private BigDecimal changeValue; + + /** + * 环比 + */ + private String changeRate; +} diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/vo/uniapp/business/BusinessOperationMetricVO.java b/jsowell-pile/src/main/java/com/jsowell/pile/vo/uniapp/business/BusinessOperationMetricVO.java new file mode 100644 index 000000000..eb52264aa --- /dev/null +++ b/jsowell-pile/src/main/java/com/jsowell/pile/vo/uniapp/business/BusinessOperationMetricVO.java @@ -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.math.BigDecimal; + +/** + * 经营指标VO + * + * @author Auto + * @Date 2026/4/1 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class BusinessOperationMetricVO { + + /** + * 指标编码 + */ + private String metricCode; + + /** + * 指标名称 + */ + private String metricName; + + /** + * 当前周期值 + */ + private BigDecimal currentValue; + + /** + * 上周期值 + */ + private BigDecimal previousValue; + + /** + * 变化值 + */ + private BigDecimal changeValue; + + /** + * 环比 + */ + private String changeRate; +}