HChargeRecsManager.createChargeRecs 方法被调用。
createChargeRecs 接口共有 5个调用入口,对应 4种业务场景。以下是详细梳理:
HChargeRecsManager.createChargeRecs()
│
├─ 1️⃣ APP启动充电命令 → NotificationStartChargeCommand4DbListener
│ ↓
│ HChargeOrderServiceImpl.createChargeOrder4StartCharge()
│
├─ 2️⃣ 启充结果-成功(新增) → NotificationStartChargeResultListener
│ ↓
│ NotificationStartChargeResultHandler.chargingOrder()
│ [记录不存在时新增]
│
├─ 3️⃣ 启充结果-失败(新增) → NotificationStartChargeResultListener
│ ↓
│ NotificationStartChargeResultHandler.handleStartChargeFail()
│ [记录不存在时新增]
│
├─ 4️⃣ 充电订单完成(新增) → NotificationChargeOrderInfoListener
│ ↓
│ NotificationChargeOrderInfoHandler.chargeOrderInfoResult()
│ [记录不存在时新增]
│
└─ 5️⃣ 历史数据迁移 → ReceiveChargeOrderInfoListener
↓
NotificationChargeOrderInfoHandler.doCreateChargeOrder4Migrate()
调用链路:
Kafka Topic: GEP_SUEZ_SERVICE_START_CHARGE_ORDER (启动充电命令)
↓
NotificationStartChargeCommand4DbListener.onMessage() [第42行]
↓
HChargeOrderServiceImpl.createChargeOrder4StartCharge() [第68行]
↓
hChargeRecsManager.createChargeRecs(entity)
核心代码: HChargeOrderServiceImpl.java:68
@Override
public void createChargeOrder4StartCharge(CreateChargeOrderRequest request) {
// 1. 构建实体
HChargeRecsEntity entity = buildChargeRecsEntity(request);
// 2. 设置状态为"启动中"
entity.setStatus(hChargeRecsStateService.startCharge());
// 3. 生成平台订单号
entity.setOrderNo(idService.defaultOrderNo());
// 4. 创建充电记录
boolean insertResult = hChargeRecsManager.createChargeRecs(entity);
}
触发条件:
GEP_SUEZ_SERVICE_START_CHARGE_ORDER特点:
RECS_STARTING)调用链路:
Kafka Topic: GEP_DEVICE4H_NOTIFY_START_CHARGE_RESULT (启充结果上报)
↓
NotificationStartChargeResultListener.onMessage() [第35行]
↓
NotificationStartChargeResultHandler.handle()
↓
NotificationStartChargeResultHandler.chargingOrder() [第190行]
↓
hChargeRecsManager.createChargeRecs(newEntity) [记录不存在时]
核心代码: NotificationStartChargeResultHandler.java:190
private void chargingOrder(StartChargeResultModel model, EquipmentOwnerInfo equipmentOwnerInfo) {
// 1. 查询是否已存在记录
Optional<HChargeRecsEntity> hChargeRecsOpt =
hChargeRecsManager.getLatestHChargeRecsByStartChargeSeq(
model.getDeviceSN(), model.getProviderNo(), model.getBizOrderId(), null);
if (hChargeRecsOpt.isPresent()) {
// 存在则更新
// ... update logic
} else {
// 不存在:新增
newEntity.setOrderNo(idService.defaultOrderNo());
newEntity.setStatus(hChargeRecsStateService.startSuccess());
// 补充用户信息
if (StringUtils.isBlank(newEntity.getChannelId())) {
newEntity.setChannelId(SourceTypeKeyEnum.getChannelIdBySourceTypeKey(
equipmentOwnerInfo.getSourceTypeKey()));
}
if (StringUtils.isBlank(newEntity.getUserId())) {
newEntity.setUserId(equipmentOwnerInfo.getUserId());
}
// 创建充电记录
boolean createResult = hChargeRecsManager.createChargeRecs(newEntity);
}
}
触发条件:
GEP_DEVICE4H_NOTIFY_START_CHARGE_RESULT特点:
RECS_CHARGING)调用链路:
Kafka Topic: GEP_DEVICE4H_NOTIFY_START_CHARGE_RESULT (启充结果上报)
↓
NotificationStartChargeResultListener.onMessage() [第35行]
↓
NotificationStartChargeResultHandler.handle()
↓
NotificationStartChargeResultHandler.handleStartChargeFail() [第320行]
↓
hChargeRecsManager.createChargeRecs(newEntity) [记录不存在时]
核心代码: NotificationStartChargeResultHandler.java:320
private void handleStartChargeFail(StartChargeResultModel model, EquipmentOwnerInfo equipmentOwnerInfo) {
// 1. 构建失败实体
HChargeRecsEntity newEntity = buildHChargeRecsEntityFromStartChargeResultFail(model, equipmentOwnerInfo);
// 2. 查询是否已存在
Optional<HChargeRecsEntity> hChargeRecsOpt =
hChargeRecsManager.getLatestHChargeRecsByStartChargeSeq(...);
if (hChargeRecsOpt.isPresent()) {
// 存在则更新状态为"已关闭"
// ... update logic
} else {
// 不存在:新增
newEntity.setOrderNo(idService.defaultOrderNo());
newEntity.setStatus(hChargeRecsStateService.closeOrder()); // 已关闭状态
// 补充用户信息
if (StringUtils.isBlank(newEntity.getUserId())) {
newEntity.setUserId(equipmentOwnerInfo.getUserId());
}
if (StringUtils.isBlank(newEntity.getChannelId())) {
newEntity.setChannelId(SourceTypeKeyEnum.getChannelIdBySourceTypeKey(
equipmentOwnerInfo.getSourceTypeKey()));
}
// 创建充电记录
boolean createResult = hChargeRecsManager.createChargeRecs(newEntity);
}
}
触发条件:
GEP_DEVICE4H_NOTIFY_START_CHARGE_RESULT特点:
RECS_CLOSED)调用链路:
Kafka Topic: GEP_DEVICE4H_NOTIFY_CHARGE_ORDER_INFO (充电订单完成上报)
↓
NotificationChargeOrderInfoListener.onMessage() [第35行]
↓
NotificationChargeOrderInfoHandler.handle()
↓
NotificationChargeOrderInfoHandler.chargeOrderInfoResult() [第165行]
↓
hChargeRecsManager.createChargeRecs(newOne) [记录不存在时]
核心代码: NotificationChargeOrderInfoHandler.java:165
private void chargeOrderInfoResult(ChargeOrderInfoModel model, EquipmentOwnerInfo equipmentOwnerInfo) {
// 1. 构建订单实体
HChargeRecsEntity newOne = buildHChargeRecsEntity(model, equipmentOwnerInfo);
// 2. 查询是否已存在
Optional<HChargeRecsEntity> hChargeRecsEntityOption =
hChargeRecsManager.getLatestHChargeRecsByStartChargeSeq(
model.getDeviceSN(), model.getProviderNo(), model.getBizOrderId(), null);
if (hChargeRecsEntityOption.isPresent()) {
// 存在则更新(补全结束时间、电量等)
// ... update logic
} else {
// 不存在:新增
newOne.setOrderNo(idService.defaultOrderNo());
newOne.setRemark(ORDER_COMPLETE_REMARK); // "订单完成"
newOne.setStatus(hChargeRecsStateService.completeOrder()); // 已完成状态
// 补充用户信息
if (StringUtils.isBlank(newOne.getUserId())) {
newOne.setUserId(equipmentOwnerInfo.getUserId());
}
if (StringUtils.isBlank(newOne.getChannelId())) {
newOne.setChannelId(SourceTypeKeyEnum.getChannelIdBySourceTypeKey(
equipmentOwnerInfo.getSourceTypeKey()));
}
// 创建充电记录
boolean createResult = hChargeRecsManager.createChargeRecs(newOne);
}
}
触发条件:
GEP_DEVICE4H_NOTIFY_CHARGE_ORDER_INFO特点:
RECS_COMPLETE)调用链路:
Kafka Topic: HCHARGE_ORDER (历史订单同步)
↓
ReceiveChargeOrderInfoListener.onMessage() [第51行]
↓
NotificationChargeOrderInfoHandler.handleOrderFromMigrate()
↓
NotificationChargeOrderInfoHandler.doCreateChargeOrder4Migrate() [第296行]
↓
hChargeRecsManager.createChargeRecs(newOne)
核心代码: NotificationChargeOrderInfoHandler.java:296
private void doCreateChargeOrder4Migrate(MigrateChargeOrderInfoDTO chargeOrderInfoDTO) {
// 1. 构建迁移实体
HChargeRecsEntity newOne = buildHChargeRecsEntity(chargeOrderInfoDTO);
try {
// 2. 直接创建(不检查是否存在,由上层控制)
boolean createChargeRecsResult = hChargeRecsManager.createChargeRecs(newOne);
log.info("createChargeRecs result={},equipmentId={},startChargeSeq={}",
createChargeRecsResult, newOne.getEquipmentId(), newOne.getStartChargeSeq());
} catch (Exception e) {
log.error("createChargeOrder4Migrate exception, newEntity={}", JSON.toJSONString(newOne), e);
}
}
上层调用逻辑: NotificationChargeOrderInfoHandler.java:270-290
// 非强制更新:只创建不存在的
private void handleOrderWithoutForceFromMigrate(List<MigrateChargeOrderInfoDTO> chargeOrderInfoDTOList) {
chargeOrderInfoDTOList.forEach(chargeOrderInfo -> {
Optional<HChargeRecsEntity> hChargeRecsEntityOption =
hChargeRecsManager.getLatestHChargeRecsByStartChargeSeq(
chargeOrderInfo.getEquipmentId(), null,
chargeOrderInfo.getStartChargeSeq(), chargeOrderInfo.getStatus());
// 不存在才创建
if (!hChargeRecsEntityOption.isPresent()) {
doCreateChargeOrder4Migrate(chargeOrderInfo);
}
});
}
// 强制更新:覆盖已存在的
private void handleOrderWithForceFromMigrate(List<MigrateChargeOrderInfoDTO> chargeOrderInfoDTOList) {
chargeOrderInfoDTOList.forEach(chargeOrderInfo -> {
Optional<HChargeRecsEntity> hChargeRecsEntityOption = ...;
if (hChargeRecsEntityOption.isPresent()) {
// 存在则更新
doUpdateChargeOrder4Migrate(hChargeRecsEntityOption.get(), chargeOrderInfo);
} else {
// 不存在则创建
doCreateChargeOrder4Migrate(chargeOrderInfo);
}
});
}
触发条件:
HCHARGE_ORDERSyncChargeOrderInfoModel特点:
| 方式 | 触发场景 | Kafka Topic | 订单状态 | 适用充电模式 | 是否先查后写 | 典型场景 |
|---|---|---|---|---|---|---|
| 1. APP启动命令 | APP下发启充指令 | GEP_SUEZ_SERVICE_START_CHARGE_ORDER | 启动中 | 仅APP | ❌ 直接创建 | 正常APP充电流程 |
| 2. 启充成功 | IoT上报启充成功 | GEP_DEVICE4H_NOTIFY_START_CHARGE_RESULT | 充电中 | 全部模式 | ✅ 先查后写 | 非APP模式或APP兜底 |
| 3. 启充失败 | IoT上报启充失败 | GEP_DEVICE4H_NOTIFY_START_CHARGE_RESULT | 已关闭 | 全部模式 | ✅ 先查后写 | 记录失败订单 |
| 4. 订单完成 | IoT上报订单完成 | GEP_DEVICE4H_NOTIFY_CHARGE_ORDER_INFO | 已完成 | 全部模式 | ✅ 先查后写 | 异常兜底场景 |
| 5. 数据迁移 | 历史数据同步 | HCHARGE_ORDER | 原状态 | 全部模式 | ⚠️ 上层控制 | 系统迁移/数据导入 |
startChargeSeq(充电流水号)判断是否存在启动中(1) → 充电中(2) → 已完成(3)
↘ 已关闭(4)
equipmentOwnerAndSharerCacheService 补充用户信息所有方式都通过 idService.defaultOrderNo() 生成平台订单号,确保唯一性
HChargeRecsManagerImpl 内部使用雪花算法生成主键ID:
if (Objects.isNull(entity.getId())) {
entity.setId(Long.valueOf(idService.defaultIdWithSnowFlake()));
}
这套设计实现了充电订单从启充→充电→完成的全生命周期管理,同时支持异常兜底和历史数据迁移,保证了数据的完整性和一致性。