diff --git a/config/application-external.yml b/config/application-external.yml index 8ee4a35..c57f234 100644 --- a/config/application-external.yml +++ b/config/application-external.yml @@ -33,7 +33,12 @@ oss: vaa-sync: download-path: ./vaa-recordings retain-days: 10 - # 每次回看昨天00:00到当前时间,防止录音盒延迟生成文件造成漏拉 + # 以下地市直接上传录音盒原始文件,不执行G.729转PCM;多个地市用英文逗号分隔 + transcode-excluded-city-codes: "340800" # 安庆市 + # 以下地市每次同步向前回看7天;已有call_record_id会自动去重 + extended-lookback-city-codes: "340800" # 安庆市 + extended-lookback-days: 7 + # 定时执行周期;普通地市回看1天,安庆按上面的配置回看7天 sync-interval-cron: "0 0 0/8 * * ?" # ==================== 日志配置 ==================== diff --git a/src/main/java/com/threecloud/dataserviceyy/service/VaaSyncService.java b/src/main/java/com/threecloud/dataserviceyy/service/VaaSyncService.java index e27ccca..787ddbf 100644 --- a/src/main/java/com/threecloud/dataserviceyy/service/VaaSyncService.java +++ b/src/main/java/com/threecloud/dataserviceyy/service/VaaSyncService.java @@ -60,6 +60,15 @@ public class VaaSyncService { private String downloadPath; @Value("${vaa-sync.retain-days:10}") private int retainDays; + /** 这些地市的录音保持原始编码上传,不执行 G.729 转码(逗号分隔) */ + @Value("${vaa-sync.transcode-excluded-city-codes:}") + private String transcodeExcludedCityCodes; + /** 需要扩大历史回看范围的地市编码(逗号分隔) */ + @Value("${vaa-sync.extended-lookback-city-codes:}") + private String extendedLookbackCityCodes; + /** 上述地市每次同步向前回看的天数 */ + @Value("${vaa-sync.extended-lookback-days:7}") + private int extendedLookbackDays; /** * 定时同步任务 @@ -197,7 +206,7 @@ public class VaaSyncService { // 8. 上传OSS(复用原OSS文件名覆盖,业务表无需更新) String ossFileName = extractOssFileName(record.getRecordingFilePath(), fileName); String ossPath = "voice/" + cityCode + "/" + new SimpleDateFormat("yyyy-MM-dd").format(callStartTime) + "/"; - OssFileResponse ossResponse = uploadRecording(localFile.toFile(), ossFileName, ossPath); + OssFileResponse ossResponse = uploadRecording(localFile.toFile(), ossFileName, ossPath, cityCode); String previewUrl = ossResponse.getFileUrl(); if (previewUrl == null || previewUrl.trim().isEmpty()) { throw new IllegalStateException("OSS上传成功但未返回文件地址: " + ossFileName); @@ -227,14 +236,19 @@ public class VaaSyncService { * @param localFile 本地录音文件 * @param fileName OSS 上的文件名(保持原文件名,业务表无需更新) * @param ossPath OSS 存储目录 + * @param cityCode 地市编码,用于判断该地市是否禁用转码 * @return OSS 上传结果 */ - private OssFileResponse uploadRecording(File localFile, String fileName, String ossPath) { + private OssFileResponse uploadRecording(File localFile, String fileName, String ossPath, String cityCode) { File uploadFile = localFile; File transcodedFile = null; boolean uploadSucceeded = false; try { - if (g729Converter.isG729(localFile)) { + boolean skipTranscode = isTranscodeExcluded(cityCode); + if (skipTranscode) { + logger.info("【录音】地市 {} 已配置跳过转码,直接上传原始文件: {} ({} 字节)", + cityCode, fileName, localFile.length()); + } else if (g729Converter.isG729(localFile)) { try { transcodedFile = new File(localFile.getParentFile(), localFile.getName() + ".pcm.wav"); if (transcodedFile.isFile()) { @@ -270,6 +284,31 @@ public class VaaSyncService { } } + /** 判断当前地市是否配置为跳过录音转码。 */ + private boolean isTranscodeExcluded(String cityCode) { + if (!StringUtils.hasText(cityCode) || !StringUtils.hasText(transcodeExcludedCityCodes)) { + return false; + } + for (String configuredCityCode : transcodeExcludedCityCodes.split(",")) { + if (cityCode.equals(configuredCityCode.trim())) { + return true; + } + } + return false; + } + + /** 默认回看1天,配置的地市使用扩展天数。 */ + private int resolveLookbackDays(String cityCode) { + if (StringUtils.hasText(cityCode) && StringUtils.hasText(extendedLookbackCityCodes)) { + for (String configuredCityCode : extendedLookbackCityCodes.split(",")) { + if (cityCode.equals(configuredCityCode.trim())) { + return Math.max(1, extendedLookbackDays); + } + } + } + return 1; + } + /** * 从 call_record_id(格式:设备编号_录音ID)中提取录音盒上的录音ID */ @@ -373,9 +412,12 @@ public class VaaSyncService { Map extNumbers = getExtensionNumbers(deviceHost, authToken); // 步骤3:计算同步时间范围 - // 每次回看到昨天00:00,兼容录音盒延迟生成/延迟可见的录音。 + // 默认回看到昨天00:00;配置了扩展回看的地市可向前查询更多天。 // 已入库数据由 call_record_id 批量去重,不会重复下载和入库。 - Date lastSyncTime = startOfYesterday(); + int lookbackDays = resolveLookbackDays(cityCode); + Date lastSyncTime = startOfDaysAgo(lookbackDays); + logger.info("【设备】录音查询回看范围: cityCode={}, lookbackDays={}, startTime={}", + cityCode, lookbackDays, lastSyncTime); Date savedSyncTime = SyncTimeUtil.readLastSyncTime(downloadPath, deviceId); // 若历史上有失败记录尚未跨过,保留更早的补拉起点,直到后续处理成功。 if (savedSyncTime != null && savedSyncTime.before(lastSyncTime)) { @@ -549,7 +591,7 @@ public class VaaSyncService { // 上传到OSS(地市+日期目录);上传失败时整条处理失败,下轮重新拉取。 String ossPath = "voice/" + cityCode + "/" + new SimpleDateFormat("yyyy-MM-dd").format(callStartTime) + "/"; - OssFileResponse ossResponse = uploadRecording(localFile.toFile(), fileName, ossPath); + OssFileResponse ossResponse = uploadRecording(localFile.toFile(), fileName, ossPath, cityCode); String previewUrl = ossResponse.getFileUrl(); if (previewUrl == null || previewUrl.trim().isEmpty()) { throw new IllegalStateException("OSS上传成功但未返回文件地址: " + fileName); @@ -694,12 +736,10 @@ public class VaaSyncService { return candidate; } - /** - * 返回服务器当地时区的昨天00:00:00。 - */ - private Date startOfYesterday() { + /** 返回服务器当地时区指定天数前的00:00:00。 */ + private Date startOfDaysAgo(int days) { Calendar calendar = Calendar.getInstance(); - calendar.add(Calendar.DAY_OF_MONTH, -1); + calendar.add(Calendar.DAY_OF_MONTH, -Math.max(1, days)); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0);