feat: 完善RJ数据自动调度
This commit is contained in:
+14
-15
@@ -21,25 +21,22 @@
|
||||
|
||||
| 格式 | 示例 | 数据日期 |
|
||||
|------|------|----------|
|
||||
| `XXX_YYYYMMDDHHMM_YYYYMMDDHHMM` | `CapacityReportData2.6_202605110000_202605120000.zip` | 第一个时间戳 `202605110000` → 2026-05-11 |
|
||||
| `XXX_YYYYMMDDHHMM` | `CapacityReportData2.6_202605110000.zip` | 时间戳 `202605110000` → 2026-05-11 |
|
||||
| `XXX_YYYYMMDDHHMM_YYYYMMDDHHMM` | `CapacityReportData2.6_202605110000_202605120000.zip` | 覆盖起止时间范围,结束零点按右开区间处理 → 2026-05-11 |
|
||||
| `XXX_YYYYMMDDHHMM` | `CapacityReportData2.6_202605110000.zip` | 视为单日文件 → 2026-05-11 |
|
||||
|
||||
### 2.2 解析逻辑
|
||||
|
||||
复用项目已有的正则 `_ZIP_DATE_RE = re.compile(r"(?<!\d)(20\d{10}(?:\d{2})?)(?!\d)")`,取第一个匹配项作为数据日期。
|
||||
复用项目已有的正则 `_ZIP_DATE_RE = re.compile(r"(?<!\d)(20\d{10}(?:\d{2})?)(?!\d)")`,优先解析文件覆盖的自然日范围。
|
||||
|
||||
```python
|
||||
def extract_file_date(filename: str) -> date | None:
|
||||
"""从文件名提取数据日期(取第一个匹配的时间戳)"""
|
||||
match = _ZIP_DATE_RE.search(filename)
|
||||
if not match:
|
||||
return None
|
||||
timestamp = match.group(1) # 12位: YYYYMMDDHHMM 或 14位: YYYYMMDDHHMMSS
|
||||
fmt = "%Y%m%d%H%M%S" if len(timestamp) == 14 else "%Y%m%d%H%M"
|
||||
try:
|
||||
return datetime.strptime(timestamp, fmt).date()
|
||||
except ValueError:
|
||||
def parse_file_date_range(filename: str) -> FileDateRange | None:
|
||||
"""从文件名提取数据覆盖范围。"""
|
||||
values = _ZIP_DATE_RE.findall(filename)
|
||||
if not values:
|
||||
return None
|
||||
start = parse_timestamp(values[0])
|
||||
end = parse_timestamp(values[1]) if len(values) > 1 else start + timedelta(days=1)
|
||||
return FileDateRange(start=start.date(), end_exclusive=normalize_end(end))
|
||||
```
|
||||
|
||||
---
|
||||
@@ -130,10 +127,12 @@ def get_target_week_range(week_offset: int = 0) -> tuple[date, date]:
|
||||
|
||||
**关键**:
|
||||
1. 不依赖系统日期,而是从文件名中提取日期
|
||||
2. 文件名只取**第一个**时间戳作为数据日期
|
||||
3. 例如文件 `CapacityReportData2.6_202605120000_202605130000.zip` → 数据日期为 2026-05-12
|
||||
2. 文件名带两个时间戳时按覆盖范围判断;只有一个时间戳时视为单日文件
|
||||
3. 例如文件 `CapacityReportData2.6_202605120000_202605130000.zip` → 覆盖 2026-05-12
|
||||
4. 如果某个日期没有对应的 ZIP 文件,该目录判定为未就绪
|
||||
|
||||
RJ 目录会额外按最新文件自动判断粒度:最新文件为单日时要求 7 个目标日都齐全;最新文件为多日/周文件时要求存在一个 ZIP 覆盖完整目标自然周。
|
||||
|
||||
### 3.4 标识文件
|
||||
|
||||
- **位置**:`cache/auto_scheduler/ready.flag`
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
# 项目上下文记录
|
||||
|
||||
## 2026-06-01:完善 RJ 自动调度日/周粒度识别
|
||||
|
||||
- `app/utils/file_dates.py` 新增文件日期范围解析:`XXX_YYYYMMDDHHMM` 视为单日文件,`XXX_YYYYMMDDHHMM_YYYYMMDDHHMM` 按起止时间展开自然日,结束时间为零点时按右开区间处理。
|
||||
- `app/services/auto_scheduler.py` 的 RJ 检查改为按目录最新 ZIP 自动识别 `daily` 或 `weekly`:日粒度目录要求目标自然周 7 天都存在,周粒度目录要求有一个 ZIP 覆盖目标自然周;空 RJ 目录继续视为停推并跳过。
|
||||
- 自动调度普通 4G/5G 目录扫描会排除已配置的 RJ 目录,避免 `expected_directories=[]` 时 RJ 周目录被普通 7 天规则误判阻塞。
|
||||
- `app/services/remote_download.py` 的调度下载筛选改为使用日期覆盖范围:单日文件只要覆盖目标日即下载,多日/周文件必须覆盖完整目标周才下载,避免 ready 后漏下或误下 RJ 周文件。
|
||||
- `Configure.json` 将 `RJ/700M/700RJGD`、`RJ/700M/700RJYD` 加入 RJ 数据目录,并补充 `700MRJGD`、`700MRJYD` 字段映射;`processor.py` 避免多个源字段别名映射到同一目标字段时生成重复列。
|
||||
- 配置上传接口现在会导入/保存 `RJData`,前端类型补充 `rj_data` 和调度状态中的 `granularity` 字段。
|
||||
- 已验证:后端 AST 语法检查、`Configure.json` JSON 解析、`npm run build`、真实 SFTP 清单识别、MySQL 临时导入 700RJYD 样本并清理测试表均通过;前端构建仅保留既有大 chunk 警告。
|
||||
|
||||
## 2026-05-29:新增 RJ 周数据处理功能
|
||||
|
||||
- 新增 `RJData` 配置块到 `app/config.py`,支持 `enabled`、`weekly_directories` 和 `table_field_mappings` 配置项,用于管理 RJ 周数据目录和字段映射。
|
||||
|
||||
Reference in New Issue
Block a user