| | |
| | | result.put("endMode", order.getEndMode()); |
| | | result.put("phone", order.getPhone()); |
| | | result.put("licensePlate", order.getPlateNum()); |
| | | result.put("startSoc", "-"); |
| | | result.put("endSoc", "-"); |
| | | // SOC 展示口径:优先展示结算回填的开始/结束 SOC;历史订单未采集时保持占位符 |
| | | result.put("startSoc", order.getStartSoc() == null ? "-" : order.getStartSoc().toPlainString()); |
| | | result.put("endSoc", order.getEndSoc() == null ? "-" : order.getEndSoc().toPlainString()); |
| | | if (order.getStartTime() != null && order.getEndTime() != null) { |
| | | result.put("chargingSecond", ChronoUnit.SECONDS.between(order.getStartTime(), order.getEndTime())); |
| | | } |
| | |
| | | final BigDecimal svcTotal = serviceChargeTotal; |
| | | final BigDecimal discountElecTotal = discountElectricTotal; |
| | | final BigDecimal discountSvcTotal = discountServiceTotal; |
| | | // SOC 回填(与 VIN 结算同口径):取订单最早/最新实时监控上报,读取失败不阻断结算 |
| | | final BigDecimal startSoc = getMonitoringSocQuietly(code, "asc"); |
| | | final BigDecimal endSoc = getMonitoringSocQuietly(code, "desc"); |
| | | // 剩余金额口径:可用金额基数(建单写入的 charge_amount) - 本单金额; |
| | | // 改造前创建的老订单无基数时以本单金额兜底(剩余金额记 0),并顺带补齐 charge_amount |
| | | final BigDecimal chargeBase = order.getChargeAmount() != null ? order.getChargeAmount() : orderAmount; |
| | |
| | | update.setStatus(ORDER_STATUS_FINISHED); |
| | | if (order.getEndMode() == null) { |
| | | update.setEndMode(1); |
| | | } |
| | | // SOC 回填:监控数据缺失/查询异常时不覆盖既有值,与 VIN 结算行为一致 |
| | | if (startSoc != null) { |
| | | update.setStartSoc(startSoc); |
| | | } |
| | | if (endSoc != null) { |
| | | update.setEndSoc(endSoc); |
| | | } |
| | | if (preferentialBackfill) { |
| | | // 历史订单(快照为空)实时查询结果回填订单快照列,保证后续补偿重算口径一致 |
| | |
| | | } |
| | | |
| | | /** |
| | | * 容错读取订单最早/最新监控记录的 SOC(与 VIN 结算同口径): |
| | | * Mongo 数据缺失、SOC 未上报或查询异常返回 null,不阻断主结算流程。 |
| | | */ |
| | | private BigDecimal getMonitoringSocQuietly(String code, String sort) { |
| | | if (uploadRealTimeMonitoringDataService == null) { |
| | | return null; |
| | | } |
| | | try { |
| | | UploadRealTimeMonitoringData monitoringData = uploadRealTimeMonitoringDataService.getDataByOrderCode(code, sort); |
| | | return monitoringData == null || monitoringData.getSoc() == null |
| | | ? null : BigDecimal.valueOf(monitoringData.getSoc().longValue()); |
| | | } catch (Exception ex) { |
| | | log.error("[SD结算] 查询监控SOC失败 code={} sort={}", code, sort, ex); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 结算刷卡账户资金(实扣冻结口径,与 VIN 链路同构): |
| | | * 1) 分配模式:解锁卡片锁定额并按实际消费扣减(允许扣成负数),差额退回卡账户; |
| | | * 2) 共享模式:解锁企业账户锁定额并按实际消费扣减,差额退回企业账户; |