diff --git a/README.md b/README.md index 2fee012..eaa488b 100644 --- a/README.md +++ b/README.md @@ -160,6 +160,7 @@ ftp-sync: ftp-source-dir: /record/ # txt目录 ftp-record-dir: /recordfile/ # mp3目录 ftp-archive-dir: /processed/ # 归档目录 + archive-by-date: true # 是否在归档目录下按yyyyMMdd建立子目录 vaa-sync: oss: @@ -213,6 +214,7 @@ tail -f logs/app.log | `ftp-source-dir` | ✓ | txt源目录(处理后归档) | | `ftp-record-dir` | ✓ | mp3/wav文件目录 | | `ftp-archive-dir` | ✓ | 处理完的txt移动到此目录 | +| `archive-by-date` | | 是否按文件日期建立归档子目录,默认true;false时直接放入归档目录 | ### FTP全局配置(ftp-sync.*) @@ -254,7 +256,7 @@ kssj※jssj※hjls※hjzls※zjhm※bjhm※thsc※...※thfx | 6 | bjhm | 被叫号码 | 12345678 | | 7 | thsc | 通话时长(秒) | 30 | | ... | ... | 中间字段 | ... | -| 10 | thfx | 通话方向 | 1=呼入/0=呼出 | +| 10 | thfx | 通话方向 | 1=呼出/0=呼入 | **录音文件**:`{ftpRecordDir}/{yyyyMMdd}/{hjls}_{hjzls}.mp3` diff --git a/config/application-external.yml b/config/application-external.yml index c5f911f..04e3f23 100644 --- a/config/application-external.yml +++ b/config/application-external.yml @@ -64,7 +64,9 @@ ftp-sync: ftp-password: yyfile ftp-source-dir: /sound_log/ ftp-record-dir: /rec/ - ftp-archive-dir: /voice_record/processed/ + # 淮南处理完成的TXT直接移到 /voice_record/,不再按日期创建子目录 + ftp-archive-dir: /voice_record/ + archive-by-date: false phone-area-code: "0554" # 淮南索引第8列=来源单位名称,第9列=来源单位ID(位置从1开始) org-mapping-enabled: true @@ -85,13 +87,14 @@ ftp-sync: # 蚌埠录音实际位于FTP根目录的 /yyyyMMdd/ 下,不是 /rec/yyyyMMdd/ ftp-record-dir: / ftp-archive-dir: /voice_record/processed/ + archive-by-date: true phone-area-code: "0552" # 蚌埠索引格式已确认与淮南一致:第8列=来源单位名称,第9列=来源单位ID org-mapping-enabled: true source-org-name-position: 8 source-org-id-position: 9 # 未完成人工机构映射时使用的org_code,请填写系统要求的完整数字编码;禁止填340300 - default-org-code: "" # 请填写完整数字编码并保留引号 + default-org-code: "340300" # 请填写完整数字编码并保留引号 passive-mode: true # 是否被动模式:true=被动模式(PASV,默认),false=主动模式(PORT) # ==================== 服务端口 ==================== diff --git a/src/main/java/com/threecloud/dataserviceyy/config/FtpSyncProperties.java b/src/main/java/com/threecloud/dataserviceyy/config/FtpSyncProperties.java index 4cf3737..dbde3db 100644 --- a/src/main/java/com/threecloud/dataserviceyy/config/FtpSyncProperties.java +++ b/src/main/java/com/threecloud/dataserviceyy/config/FtpSyncProperties.java @@ -94,6 +94,12 @@ public class FtpSyncProperties { private String ftpRecordDir; /** 归档目录(处理完的txt移到这里) */ private String ftpArchiveDir; + /** + * 归档时是否按TXT文件名前8位日期创建子目录。 + * true:归档到 ftpArchiveDir/yyyyMMdd/文件名(默认,兼容原有行为) + * false:直接归档到 ftpArchiveDir/文件名 + */ + private boolean archiveByDate = true; /** * 电话区号前缀(处理主被叫号码时去除) * - 配正确区号(如合肥 0551):号码以 0551 开头则去除 @@ -141,6 +147,9 @@ public class FtpSyncProperties { public String getFtpArchiveDir() { return ftpArchiveDir; } public void setFtpArchiveDir(String ftpArchiveDir) { this.ftpArchiveDir = ftpArchiveDir; } + public boolean isArchiveByDate() { return archiveByDate; } + public void setArchiveByDate(boolean archiveByDate) { this.archiveByDate = archiveByDate; } + public String getPhoneAreaCode() { return phoneAreaCode; } public void setPhoneAreaCode(String phoneAreaCode) { this.phoneAreaCode = phoneAreaCode; } diff --git a/src/main/java/com/threecloud/dataserviceyy/service/FtpSyncService.java b/src/main/java/com/threecloud/dataserviceyy/service/FtpSyncService.java index 95b3a03..8d02de2 100644 --- a/src/main/java/com/threecloud/dataserviceyy/service/FtpSyncService.java +++ b/src/main/java/com/threecloud/dataserviceyy/service/FtpSyncService.java @@ -46,7 +46,7 @@ import java.util.*; * thsc : 通话时长(秒) * sourceOrgName : 来源单位名称(淮南格式第8列,如孔店派出所) * sourceOrgId : 来源单位ID(淮南格式第9列,不是设备编号) - * thfx : 通话方向 1=呼入 0=呼出 + * thfx : 通话方向 1=呼出 0=呼入 * * 录音文件命名:{hjls}_{hjzls}.mp3 * 录音文件路径:{ftpRecordDir}/{yyyyMMdd}/{hjls}_{hjzls}.mp3 @@ -341,7 +341,7 @@ public class FtpSyncService { String bjhm = fields[5].trim(); // bjhm : 被叫号码 String thscStr = fields[6].trim();// thsc : 通话时长(秒) // fields[7]、fields[8] 由地市配置决定;淮南分别为来源单位名称、来源单位ID。 - String thfx = fields[9].trim(); // thfx : 通话方向(1=呼入,0=呼出 - 老系统特殊编码) + String thfx = fields[9].trim(); // thfx : 通话方向(1=呼出,0=呼入) // 淮南等配置启用的地市,从索引列中提取厂家单位信息并维护映射表。 FtpOrgMapping orgMapping = resolveOrgMapping(city, fields, orgMappingCache); @@ -359,9 +359,13 @@ public class FtpSyncService { } int thsc = parseInt(thscStr, 0); - // thfx 转换:老系统"0"=呼出,其他(含1)=呼入 - // 数据库规范:1=呼入,2=呼出(所以 isOutgoing=true 时存"2") - boolean isOutgoing = thfx.contains("0"); + // FTP源数据:1=呼出、0=呼入;数据库规范:1=呼入、2=呼出。 + // 方向值异常时不能猜测,否则会造成方向及主被叫号码错误。 + if (!"0".equals(thfx) && !"1".equals(thfx)) { + logger.warn("【FTP行】通话方向无效,跳过: thfx={}, hjls={}", thfx, hjls); + return 0; + } + boolean isOutgoing = "1".equals(thfx); // 录音文件名 = hjls_hjzls.mp3(如:12345_67890.mp3) String recordFileName = hjls + "_" + hjzls + ".mp3"; // 唯一标识 = 地市编码_FTP_呼叫流水(防重键) @@ -502,8 +506,9 @@ public class FtpSyncService { rec.setCallEndTime(callEndTime); // 通话结束时间 rec.setCallDuration(duration); // 通话时长(秒) rec.setCallDirection(isOutgoing ? DIR_OUTGOING : DIR_INCOMING); // 通话方向:1呼入/2呼出 - rec.setCallTel(isOutgoing ? zjhm : bjhm); // 主叫号码 - rec.setCalledTel(isOutgoing ? bjhm : zjhm); // 被叫号码 + // TXT第5列zjhm、第6列bjhm已经分别是主叫和被叫,不能根据呼入/呼出交换。 + rec.setCallTel(zjhm); // 主叫号码 + rec.setCalledTel(bjhm); // 被叫号码 rec.setCallStatus(CALL_STATUS_OK); // 通话状态:1=正常接通 rec.setRecordingFileSize(fileSize); // 文件大小(字节) rec.setRecordingFilePath(ossUrl); // OSS访问URL @@ -619,7 +624,8 @@ public class FtpSyncService { } /** - * 将已处理完成的TXT移入按日期分目录的备份目录。 + * 将已处理完成的TXT移入备份目录。 + * archive-by-date=true 时按文件日期分目录;false 时直接放入归档根目录。 * 待就绪或失败的TXT不会调用此方法,会继续留在源目录中等待下次同步。 */ private void archiveProcessedTxt(FTPClient ftp, TxtCandidate candidate, FtpCityConfig city) { @@ -628,16 +634,21 @@ public class FtpSyncService { return; } String fileName = candidate.file.getName(); - String dateDir = fileName.length() >= 8 && fileName.substring(0, 8).matches("\\d{8}") - ? fileName.substring(0, 8) - : "unknown-date"; String archiveRoot = city.getFtpArchiveDir(); - String archiveDateDir = joinPath(archiveRoot, dateDir); + String archiveTargetDir = archiveRoot; + if (city.isArchiveByDate()) { + String dateDir = fileName.length() >= 8 && fileName.substring(0, 8).matches("\\d{8}") + ? fileName.substring(0, 8) + : "unknown-date"; + archiveTargetDir = joinPath(archiveRoot, dateDir); + } String fromPath = joinPath(candidate.directory, fileName); - String toPath = joinPath(archiveDateDir, fileName); + String toPath = joinPath(archiveTargetDir, fileName); try { FtpUtil.ensureDir(ftp, archiveRoot); - FtpUtil.ensureDir(ftp, archiveDateDir); + if (!archiveRoot.equals(archiveTargetDir)) { + FtpUtil.ensureDir(ftp, archiveTargetDir); + } FtpUtil.rename(ftp, fromPath, toPath); logger.info("【FTP归档】已处理TXT已移入备份目录: {} -> {}", fromPath, toPath); } catch (Exception e) {