From 929d16943139e152e3c4492614a7d4fc4b613f8d Mon Sep 17 00:00:00 2001 From: Shuming Liu Date: Wed, 22 Apr 2026 07:59:53 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=A8=8B=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/association_detail.py | 53 ++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/server/association_detail.py b/server/association_detail.py index 6e5343e..9fcccb9 100644 --- a/server/association_detail.py +++ b/server/association_detail.py @@ -458,6 +458,16 @@ def extract_zip_recursive(zip_path: Path, extract_dir: Path, clear_dir: bool = T return extracted_files +def has_audio_video_files(files_list: List[Dict[str, Union[str, float]]]) -> bool: + """检查文件列表中是否包含音视频文件""" + audio_video_exts = {'.mp3', '.mp4', '.avi', '.mkv', '.wav', '.flac', '.aac', '.ogg', '.wma', '.mov', '.wmv'} + for file_entry in files_list: + name = file_entry.get('name', '') + if any(name.lower().endswith(ext) for ext in audio_video_exts): + return True + return False + + def build_file_associations( word_content: List[str], twole_folder: Path, @@ -482,12 +492,16 @@ def build_file_associations( # 辅助函数:处理文件路径,如果是 zip 则递归解压 def process_file(file_path: Path) -> List[Dict[str, Union[str, float]]]: + def format_datetime(mtime: float) -> str: + """将时间戳格式化为可读的日期时间字符串""" + return datetime.fromtimestamp(mtime).strftime("%Y-%m-%d %H:%M:%S") + files = [] # 检查是否是压缩文件 if file_path.suffix.lower() in ('.zip', '.rar', '.7z'): # 先添加压缩文件本身 mtime = file_path.stat().st_mtime - files.append({"name": file_path.name, "mtime": mtime}) + files.append({"name": file_path.name, "mtime": mtime, "datetime": format_datetime(mtime)}) tmp_dir = Path(__file__).parent / "tmp" tmp_dir.mkdir(exist_ok=True) @@ -510,10 +524,10 @@ def build_file_associations( for f in extracted: if f.is_file(): mtime = f.stat().st_mtime - files.append({"name": f.name, "mtime": mtime}) + files.append({"name": f.name, "mtime": mtime, "datetime": format_datetime(mtime)}) else: mtime = file_path.stat().st_mtime - files.append({"name": file_path.name, "mtime": mtime}) + files.append({"name": file_path.name, "mtime": mtime, "datetime": format_datetime(mtime)}) return files def get_latest_extracted_mtime(file_entries: List[Dict[str, Union[str, float]]], archive_name: str) -> Optional[float]: @@ -522,10 +536,28 @@ def build_file_associations( for entry in file_entries if entry.get("name") != archive_name and "mtime" in entry ] - return max(extracted_times) if extracted_times else None + if not extracted_times: + return None + + # 找出压缩文件本身的时间 + archive_mtime = None + for entry in file_entries: + if entry.get("name") == archive_name and "mtime" in entry: + archive_mtime = entry["mtime"] + break + + latest_extracted = max(extracted_times) + + # 如果压缩文件时间和解压文件最晚时间差小于 30 秒,返回 None + if archive_mtime is not None and abs(latest_extracted - archive_mtime) < 300: + return None + + return latest_extracted # 初始化条目 entry = {} + group1_files = [] + group2_files = [] group1_latest = None group2_latest = None @@ -593,8 +625,16 @@ def build_file_associations( if file_path.suffix.lower() in ('.zip', '.rar', '.7z'): group2_latest = get_latest_extracted_mtime(group2_files, file_path.name) - # 如果 group1 和 group2 都是压缩文件,并且 group1 的解压文件最新时间早于 group2,则记录到问题列表 - if group1_latest is not None and group2_latest is not None and group1_latest < group2_latest: + # 如果 group1 和 group2 都是压缩文件,并且 group1 的解压文件最新时间早于 group2(时间差超过阈值),则记录到问题列表 + # 或者如果解压出来的文件中包含音视频文件,也记录到问题列表 + TIME_DIFF_THRESHOLD = 30 # 时间差阈值(秒),避免将 zip 文件和解压文件时间相近的误判为问题组 + time_diff_condition = ( + group1_latest is not None + and group2_latest is not None + and group1_latest < group2_latest + and (group2_latest - group1_latest) > TIME_DIFF_THRESHOLD + ) + if time_diff_condition: problematic_groups.append({ "row_index": i, "group1_latest_extracted_mtime": group1_latest, @@ -750,6 +790,7 @@ def main(): print(f"\n===== 批量处理完成 =====") print(f"成功:{success_count}, 失败:{fail_count}") print(f"问题组报告已保存到:{report_file}") + print(len(all_problem_groups)) return if __name__ == "__main__":