总体运营态势接口查询

This commit is contained in:
秦鸿展
2026-05-11 15:01:31 +08:00
parent 1afddbe531
commit 2b281bba90
8 changed files with 231 additions and 9 deletions
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.ComprehensiveSituationVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.CustomerContributionRankVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.WarehouseTransportSituationVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.overall.*;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.platform.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@@ -96,4 +97,41 @@ public final class BiReportSnapshotMapperSupport {
.platformAlarmDistribution(Collections.emptyList())
.build();
}
public static OverallOperationSituationVO emptyOverallOperationSituation() {
return OverallOperationSituationVO.builder()
.updateTime("")
.warehouse(OverallWarehouseOperationVO.builder()
.orderStatistics(OverallWarehouseOrderStatisticVO.builder()
.processedOrderCount(0L).changePercent(0d).build())
.coreCapability(OverallWarehouseCoreCapabilityVO.builder()
.totalWarehouses(0).selfOperatedCount(0).outsourcedCount(0)
.operatingArea(0).areaUnit("")
.build())
.orderTrendByMonth(Collections.emptyList())
.throughputTrendByMonth(Collections.emptyList())
.bizStatistics(OverallWarehouseBizStatisticVO.builder()
.customerCount(0L).coverageArea("")
.annualThroughput(0).throughputUnit("").throughputGrowth(0d)
.build())
.capabilityRanking(Collections.emptyList())
.build())
.map(OverallMapSectionVO.builder().nodes(Collections.emptyList()).build())
.transport(OverallTransportOperationVO.builder()
.orderSummary(OverallTransportOrderSummaryVO.builder()
.processedOrderCount(0L).changePercent(0d)
.annualFreight(0d).freightUnit("").freightGrowth(0d)
.build())
.capacityStatistics(OverallTransportCapacityVO.builder()
.totalVehicles(0).ownedVehicles(0).socialVehicles(0)
.totalDrivers(0).ownedDrivers(0).socialDrivers(0)
.build())
.orderTrendByMonth(Collections.emptyList())
.freightTrendByMonth(Collections.emptyList())
.orderDistribution(OverallTransportModeDistributionVO.builder()
.crossBorder(0L).domestic(0L).build())
.enterpriseRanking(Collections.emptyList())
.build())
.build();
}
}
@@ -3,7 +3,7 @@ package com.mhd.bi.domain.biSnapshotSync.repository.mapper;
import org.apache.ibatis.annotations.Param;
/**
* 三张 BI 快照表写入(定时同步任务使用)
* BI 快照表写入(定时同步任务使用)
*/
public interface BiSnapshotWriteMapper {
@@ -12,4 +12,6 @@ public interface BiSnapshotWriteMapper {
int insertWarehouseTransportSnapshot(@Param("payloadJson") String payloadJson, @Param("remark") String remark);
int insertPlatformSurveillanceSnapshot(@Param("payloadJson") String payloadJson, @Param("remark") String remark);
int insertOverallOperationSnapshot(@Param("payloadJson") String payloadJson, @Param("remark") String remark);
}
@@ -8,7 +8,7 @@ import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* 定时将业务快照写入 BI_COMPREHENSIVE_SNAPSHOT / BI_WAREHOUSE_TRANSPORT_SNAPSHOT / BI_PLATFORM_SURVEILLANCE_SNAPSHOT。
* 定时将业务快照写入 BI_COMPREHENSIVE_SNAPSHOT / BI_WAREHOUSE_TRANSPORT_SNAPSHOT / BI_PLATFORM_SURVEILLANCE_SNAPSHOT / BI_OVERALL_OPERATION_SNAPSHOT
* <p>默认关闭,需在配置中设置 {@code mhd.bi.snapshot-sync.enabled=true}。</p>
*/
@Slf4j
@@ -5,6 +5,7 @@ import com.mhd.bi.domain.biSnapshotSync.repository.mapper.BiSnapshotWriteMapper;
import com.mhd.bi.domain.biSnapshotSync.support.BiSnapshotWeeklyRandomDataBuilder;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.ComprehensiveSituationVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.WarehouseTransportSituationVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.overall.OverallOperationSituationVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.platform.PlatformSurveillanceVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -13,10 +14,10 @@ import org.springframework.stereotype.Service;
import java.util.Random;
/**
* BI 三张快照表定时同步。
* BI 快照表定时同步(综合态势 / 仓储运输 / 月台监测 / 总体运营态势)
* <p><b>当前(临时)</b>{@code build*} 使用 {@link BiSnapshotWeeklyRandomDataBuilder},每次执行使用新的 {@link Random}
* 故<b>同一天多次手动触发、以及每次定时任务执行</b>,生成的模拟数据均<b>不相同</b>(仍在基准 ±20% 内)。</p>
* <p><b>后续改造</b>:在三个 {@code build*} 中改为查库/Feign 聚合真实业务并组装 VO。</p>
* <p><b>后续改造</b>:在 {@code build*} 中改为查库/Feign 聚合真实业务并组装 VO。</p>
*/
@Slf4j
@Service
@@ -29,12 +30,13 @@ public class BiReportSnapshotSyncService {
private final ObjectMapper objectMapper;
/**
* 依次同步三张快照;单表失败不影响其它表,只记日志。
* 依次同步快照;单表失败不影响其它表,只记日志。
*/
public void syncAllSnapshots() {
syncComprehensiveSnapshot();
syncWarehouseTransportSnapshot();
syncPlatformSurveillanceSnapshot();
syncOverallOperationSnapshot();
}
public void syncComprehensiveSnapshot() {
@@ -79,6 +81,27 @@ public class BiReportSnapshotSyncService {
}
}
public void syncOverallOperationSnapshot() {
try {
OverallOperationSituationVO vo = buildOverallOperationSnapshot();
String json = objectMapper.writeValueAsString(vo);
int rows = biSnapshotWriteMapper.insertOverallOperationSnapshot(json, REMARK_SYNC);
if (rows < 1) {
log.warn("BI 总体运营态势快照 INSERT 影响行数为 {},请确认 NGWL_TEST_BI.BI_OVERALL_OPERATION_SNAPSHOT", rows);
}
log.info("BI 总体运营态势快照已写入, affectedRows={}", rows);
} catch (Exception e) {
log.error("BI 总体运营态势快照同步失败", e);
}
}
/**
* TODO 业务落地:改为查询真实数据组装 VO。临时实现见 {@link BiSnapshotWeeklyRandomDataBuilder#overallOperation(Random)}。
*/
protected OverallOperationSituationVO buildOverallOperationSnapshot() {
return BiSnapshotWeeklyRandomDataBuilder.overallOperation(new Random());
}
/**
* TODO 业务落地:改为查询真实数据组装 VO。临时实现见 {@link BiSnapshotWeeklyRandomDataBuilder#comprehensive(Random)}。
*/
@@ -3,6 +3,7 @@ package com.mhd.bi.domain.biSnapshotSync.support;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.ComprehensiveSituationVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.CustomerContributionRankVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.WarehouseTransportSituationVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.overall.*;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.platform.*;
import java.time.LocalDate;
@@ -232,6 +233,144 @@ public final class BiSnapshotWeeklyRandomDataBuilder {
.build();
}
/**
* 总体运营态势:与 {@code create_bi_overall_operation_dm.sql} 内置 PAYLOAD_JSON 一致(不随 Random 抖动)。
*/
public static OverallOperationSituationVO overallOperation(Random r) {
return overallReferenceDashboard();
}
/**
* 与产品约定返回值示例一致,供快照同步与联调。
*/
public static OverallOperationSituationVO overallReferenceDashboard() {
return OverallOperationSituationVO.builder()
.updateTime("2026-05-11 10:55:00")
.warehouse(OverallWarehouseOperationVO.builder()
.orderStatistics(OverallWarehouseOrderStatisticVO.builder()
.processedOrderCount(6767L)
.changePercent(5.4)
.build())
.coreCapability(OverallWarehouseCoreCapabilityVO.builder()
.totalWarehouses(10)
.selfOperatedCount(4)
.outsourcedCount(6)
.operatingArea(28)
.areaUnit("万m²")
.build())
.orderTrendByMonth(Arrays.asList(
OverallWarehouseOrderTrendMonthVO.builder().monthLabel("1月").inboundOrders(700L).outboundOrders(450L).build(),
OverallWarehouseOrderTrendMonthVO.builder().monthLabel("2月").inboundOrders(900L).outboundOrders(550L).build(),
OverallWarehouseOrderTrendMonthVO.builder().monthLabel("3月").inboundOrders(800L).outboundOrders(480L).build(),
OverallWarehouseOrderTrendMonthVO.builder().monthLabel("4月").inboundOrders(550L).outboundOrders(300L).build(),
OverallWarehouseOrderTrendMonthVO.builder().monthLabel("5月").inboundOrders(750L).outboundOrders(350L).build(),
OverallWarehouseOrderTrendMonthVO.builder().monthLabel("6月").inboundOrders(580L).outboundOrders(320L).build(),
OverallWarehouseOrderTrendMonthVO.builder().monthLabel("7月").inboundOrders(780L).outboundOrders(400L).build()
))
.throughputTrendByMonth(Arrays.asList(
OverallThroughputTrendMonthVO.builder().monthLabel("11月").throughput(10).build(),
OverallThroughputTrendMonthVO.builder().monthLabel("12月").throughput(14).build(),
OverallThroughputTrendMonthVO.builder().monthLabel("1月").throughput(23).build(),
OverallThroughputTrendMonthVO.builder().monthLabel("2月").throughput(22).build(),
OverallThroughputTrendMonthVO.builder().monthLabel("3月").throughput(17).build(),
OverallThroughputTrendMonthVO.builder().monthLabel("4月").throughput(18).build(),
OverallThroughputTrendMonthVO.builder().monthLabel("5月").throughput(9).build()
))
.bizStatistics(OverallWarehouseBizStatisticVO.builder()
.customerCount(582L)
.coverageArea("覆盖港珠澳")
.annualThroughput(26)
.throughputUnit("万吨")
.throughputGrowth(8.5)
.build())
.capabilityRanking(Arrays.asList(
OverallWarehouseCapabilityRankVO.builder().rank(1).name("君华仓").processedVolume("2,400单").throughput("5.2万吨").utilizationRate("85%").build(),
OverallWarehouseCapabilityRankVO.builder().rank(2).name("遂宁仓").processedVolume("1,800单").throughput("4.1万吨").utilizationRate("78%").build(),
OverallWarehouseCapabilityRankVO.builder().rank(3).name("横琴仓").processedVolume("1,200单").throughput("3.5万吨").utilizationRate("92%").build(),
OverallWarehouseCapabilityRankVO.builder().rank(4).name("新南仓").processedVolume("800单").throughput("2.2万吨").utilizationRate("65%").build(),
OverallWarehouseCapabilityRankVO.builder().rank(5).name("谷丰仓").processedVolume("567单").throughput("1.8万吨").utilizationRate("45%").build()
))
.build())
.map(OverallMapSectionVO.builder()
.nodes(Arrays.asList(
OverallMapNodeVO.builder()
.type("headquarters")
.name("总部")
.location(Arrays.asList(113.3, 22.5))
.build(),
OverallMapNodeVO.builder()
.type("businessUnit")
.name("业务单元")
.location(Arrays.asList(113.6, 22.8))
.tooltip(OverallMapTooltipVO.builder()
.title("通宇业务情况分析")
.data(Arrays.asList(
OverallMapTooltipDataItemVO.builder().label("在途车辆").value(3).build(),
OverallMapTooltipDataItemVO.builder().label("在途订单").value(11).build()
))
.build())
.build(),
OverallMapNodeVO.builder()
.type("warehouse")
.name("通宇保税仓")
.location(Arrays.asList(113.4, 22.3))
.tooltip(OverallMapTooltipVO.builder()
.title("通宇保税仓情况分析")
.data(Arrays.asList(
OverallMapTooltipDataItemVO.builder().label("入库作业").value(1).build(),
OverallMapTooltipDataItemVO.builder().label("出库作业").value(1).build()
))
.build())
.build()
))
.build())
.transport(OverallTransportOperationVO.builder()
.orderSummary(OverallTransportOrderSummaryVO.builder()
.processedOrderCount(5240L)
.changePercent(6.2)
.annualFreight(2.6)
.freightUnit("万吨")
.freightGrowth(8.5)
.build())
.capacityStatistics(OverallTransportCapacityVO.builder()
.totalVehicles(320)
.ownedVehicles(100)
.socialVehicles(220)
.totalDrivers(400)
.ownedDrivers(160)
.socialDrivers(240)
.build())
.orderTrendByMonth(Arrays.asList(
OverallTransportOrderTrendMonthVO.builder().monthLabel("1月").count(100L).build(),
OverallTransportOrderTrendMonthVO.builder().monthLabel("2月").count(120L).build(),
OverallTransportOrderTrendMonthVO.builder().monthLabel("3月").count(230L).build(),
OverallTransportOrderTrendMonthVO.builder().monthLabel("4月").count(110L).build(),
OverallTransportOrderTrendMonthVO.builder().monthLabel("5月").count(150L).build(),
OverallTransportOrderTrendMonthVO.builder().monthLabel("6月").count(200L).build()
))
.freightTrendByMonth(Arrays.asList(
OverallTransportFreightTrendMonthVO.builder().monthLabel("1月").freight(80).build(),
OverallTransportFreightTrendMonthVO.builder().monthLabel("2月").freight(110).build(),
OverallTransportFreightTrendMonthVO.builder().monthLabel("3月").freight(240).build(),
OverallTransportFreightTrendMonthVO.builder().monthLabel("4月").freight(100).build(),
OverallTransportFreightTrendMonthVO.builder().monthLabel("5月").freight(140).build(),
OverallTransportFreightTrendMonthVO.builder().monthLabel("6月").freight(190).build()
))
.orderDistribution(OverallTransportModeDistributionVO.builder()
.crossBorder(2400L)
.domestic(2300L)
.build())
.enterpriseRanking(Arrays.asList(
OverallTransportEnterpriseRankVO.builder().rank(1).name("通宇").processedVolume("2,400单").freight("5.2万吨").onTimeRate("85%").build(),
OverallTransportEnterpriseRankVO.builder().rank(2).name("南岐").processedVolume("1,800单").freight("4.1万吨").onTimeRate("78%").build(),
OverallTransportEnterpriseRankVO.builder().rank(3).name("谷丰").processedVolume("1,200单").freight("3.5万吨").onTimeRate("92%").build(),
OverallTransportEnterpriseRankVO.builder().rank(4).name("仓码").processedVolume("800单").freight("2.2万吨").onTimeRate("65%").build(),
OverallTransportEnterpriseRankVO.builder().rank(5).name("横琴").processedVolume("567单").freight("1.8万吨").onTimeRate("45%").build()
))
.build())
.build();
}
/**
* 基准与 SQL 脚本 alternate sample 一致
*/
@@ -3,10 +3,12 @@ package com.mhd.bi.interfaces.facadeApi.biReport;
import com.mhd.bi.domain.biSnapshotSync.service.BiReportSnapshotSyncService;
import com.mhd.bi.domain.biComprehensive.service.BiComprehensiveReportService;
import com.mhd.bi.domain.biPlatformSurveillance.service.BiPlatformSurveillanceReportService;
import com.mhd.bi.domain.biOverallOperation.service.BiOverallOperationReportService;
import com.mhd.bi.domain.biWarehouseTransport.service.BiWarehouseTransportReportService;
import com.mhd.bi.interfaces.facadeApi.biReport.dto.BiApiResult;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.ComprehensiveSituationVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.WarehouseTransportSituationVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.overall.OverallOperationSituationVO;
import com.mhd.bi.interfaces.facadeApi.biReport.vo.platform.PlatformSurveillanceVO;
import com.mhd.common.core.web.controller.BaseController;
import io.swagger.annotations.Api;
@@ -38,11 +40,14 @@ public class BiReportApi extends BaseController {
@Autowired
private BiPlatformSurveillanceReportService biPlatformSurveillanceReportService;
@Autowired
private BiOverallOperationReportService biOverallOperationReportService;
@Autowired
private BiReportSnapshotSyncService biReportSnapshotSyncService;
@ApiOperation(value = "手动触发快照同步", notes = "立即写入三张快照表;须带 X-BI-Access-Token")
@ApiOperation(value = "手动触发快照同步", notes = "立即写入各 BI 快照表(综合、仓储运输、月台监测、总体运营);须带 X-BI-Access-Token")
@PostMapping("/snapshotSync/run")
public BiApiResult<Void> runSnapshotSyncOnce() {
biReportSnapshotSyncService.syncAllSnapshots();
@@ -78,4 +83,14 @@ public class BiReportApi extends BaseController {
PlatformSurveillanceVO data = biPlatformSurveillanceReportService.loadLatestPlatformSurveillance();
return BiApiResult.ok(data);
}
/**
* 总体运营态势
*/
@ApiOperation(value = "总体运营态势查询", notes = "返回 DEL_FLAG=1 且 CREATE_TIME 最新的一条整包 JSON 解析结果")
@GetMapping("/overallOperation")
public BiApiResult<OverallOperationSituationVO> overallOperation() {
OverallOperationSituationVO data = biOverallOperationReportService.loadLatestOverallOperation();
return BiApiResult.ok(data);
}
}
@@ -5,7 +5,7 @@ import lombok.Data;
import lombok.NoArgsConstructor;
/**
* BI 接口统一响应(与前端约定:message 字段
* BI 接口统一响应(与前端示例:code + msg + data
*/
@Data
@NoArgsConstructor
@@ -14,11 +14,11 @@ public class BiApiResult<T> {
private int code = 200;
private String message = "success";
private String msg = "操作成功";
private T data;
public static <T> BiApiResult<T> ok(T data) {
return new BiApiResult<>(200, "success", data);
return new BiApiResult<>(200, "操作成功", data);
}
}
@@ -17,4 +17,9 @@
insert into NGWL_TEST_BI.BI_PLATFORM_SURVEILLANCE_SNAPSHOT (PAYLOAD_JSON, CREATE_TIME, UPDATE_TIME, DEL_FLAG, REMARK)
values (#{payloadJson}, SYSDATE, SYSDATE, 1, #{remark})
</insert>
<insert id="insertOverallOperationSnapshot">
insert into NGWL_TEST_BI.BI_OVERALL_OPERATION_SNAPSHOT (PAYLOAD_JSON, CREATE_TIME, UPDATE_TIME, DEL_FLAG, REMARK)
values (#{payloadJson}, SYSDATE, SYSDATE, 1, #{remark})
</insert>
</mapper>