Browse Source

淮南的文件迁移

ftpmain
wang 1 day ago
parent
commit
c4d842cd74
  1. 4
      README.md
  2. 7
      config/application-external.yml
  3. 9
      src/main/java/com/threecloud/dataserviceyy/config/FtpSyncProperties.java
  4. 39
      src/main/java/com/threecloud/dataserviceyy/service/FtpSyncService.java

4
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`

7
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)
# ==================== 服务端口 ====================

9
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; }

39
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) {

Loading…
Cancel
Save