主要功能: - 修改RequirementModal支持12个订单班选择 - 添加OrderClassIconMap图标映射组件 - Store中添加selectedOrderClass状态管理 - WorkflowPage支持传递orderClass参数 - web_result添加URL参数切换功能 - 创建order-class-handler.js动态处理页面主题 技术改进: - 创建软链接关联订单班数据目录 - 生成wenlu.json和food.json数据结构 - 删除重复的web_result目录 - 添加测试页面test-order-class.html 影响范围: - 展会策划系统现支持12个订单班 - 结果展示页面自动适配不同订单班主题 - 用户可选择不同行业生成对应方案 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
370 lines
13 KiB
Python
370 lines
13 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
订单班图片整理主程序 v2.0
|
||
支持针对不同订单班单独执行或检查
|
||
"""
|
||
|
||
import os
|
||
import sys
|
||
import shutil
|
||
from pathlib import Path
|
||
from datetime import datetime
|
||
from typing import List, Optional
|
||
|
||
# 设置路径
|
||
BASE_PATH = Path("/Users/xiaoqi/Documents/Dev/Project/2025-09-08_n8nDEMO演示")
|
||
DATA_PATH = BASE_PATH / "data/订单班文档资料"
|
||
SCRIPT_PATH = BASE_PATH / "scripts"
|
||
|
||
# 预定义所有订单班
|
||
ALL_ORDER_CLASSES = [
|
||
"食品", "环保", "财经商贸", "视觉设计", "能源",
|
||
"交通物流", "智能制造", "文旅", "化工", "大健康",
|
||
"智能开发", "土木"
|
||
]
|
||
|
||
def print_banner():
|
||
"""打印标题"""
|
||
print("=" * 60)
|
||
print(" 订单班图片资源整理工具 v2.0")
|
||
print("=" * 60)
|
||
print()
|
||
|
||
def list_order_classes() -> List[str]:
|
||
"""列出所有可用的订单班"""
|
||
available = []
|
||
for order_dir in DATA_PATH.iterdir():
|
||
if order_dir.is_dir() and order_dir.name in ALL_ORDER_CLASSES:
|
||
available.append(order_dir.name)
|
||
return sorted(available)
|
||
|
||
def select_order_classes() -> List[str]:
|
||
"""选择要处理的订单班"""
|
||
available = list_order_classes()
|
||
|
||
print("\n可用的订单班:")
|
||
for i, name in enumerate(available, 1):
|
||
print(f" {i:2d}. {name}")
|
||
print(f" {len(available)+1:2d}. 全部选择")
|
||
print()
|
||
|
||
selection = input("请选择订单班(可输入多个编号,用逗号分隔,如: 1,3,5): ").strip()
|
||
|
||
if selection == str(len(available) + 1):
|
||
return available
|
||
|
||
try:
|
||
indices = [int(x.strip()) - 1 for x in selection.split(',')]
|
||
selected = [available[i] for i in indices if 0 <= i < len(available)]
|
||
return selected if selected else available
|
||
except:
|
||
print("输入无效,默认选择全部订单班")
|
||
return available
|
||
|
||
def backup_data(order_classes: Optional[List[str]] = None):
|
||
"""备份数据"""
|
||
print("\n创建备份...")
|
||
backup_dir = BASE_PATH / "backups" / f"backup_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
|
||
backup_dir.mkdir(parents=True, exist_ok=True)
|
||
|
||
# 复制指定的订单班目录
|
||
dirs_to_backup = order_classes if order_classes else ALL_ORDER_CLASSES
|
||
for dir_name in dirs_to_backup:
|
||
order_dir = DATA_PATH / dir_name
|
||
if order_dir.exists() and order_dir.is_dir():
|
||
target = backup_dir / dir_name
|
||
shutil.copytree(order_dir, target)
|
||
print(f" 备份: {dir_name}")
|
||
|
||
print(f"✅ 备份完成: {backup_dir}")
|
||
return backup_dir
|
||
|
||
def run_script_for_orders(script_name: str, description: str, order_classes: List[str]):
|
||
"""为指定的订单班运行脚本"""
|
||
script_path = SCRIPT_PATH / script_name
|
||
if not script_path.exists():
|
||
print(f"⚠️ 跳过 {description}:脚本不存在")
|
||
return False
|
||
|
||
print(f"\n{description}...")
|
||
|
||
# 这里可以根据需要修改脚本来支持特定订单班参数
|
||
# 暂时还是运行整体脚本,但只会影响选中的订单班
|
||
temp_script = create_temp_script_for_orders(script_name, order_classes)
|
||
if temp_script:
|
||
os.system(f'python3 "{temp_script}"')
|
||
os.remove(temp_script)
|
||
else:
|
||
os.system(f'python3 "{script_path}"')
|
||
return True
|
||
|
||
def create_temp_script_for_orders(script_name: str, order_classes: List[str]) -> Optional[Path]:
|
||
"""创建临时脚本,只处理指定的订单班"""
|
||
# 这是一个示例实现,根据实际脚本结构可能需要调整
|
||
return None
|
||
|
||
def validate_order_class(order_name: str):
|
||
"""验证单个订单班的图片"""
|
||
print(f"\n检查 {order_name} ...")
|
||
order_dir = DATA_PATH / order_name
|
||
|
||
if not order_dir.exists():
|
||
print(f" ⚠️ 目录不存在")
|
||
return
|
||
|
||
# 检查图片目录
|
||
image_dir = order_dir / "notion文稿" / "image"
|
||
if not image_dir.exists():
|
||
print(f" ⚠️ 没有图片目录")
|
||
return
|
||
|
||
# 统计图片
|
||
jpg_files = list(image_dir.glob("*.jpg"))
|
||
png_files = list(image_dir.glob("*.png"))
|
||
jpeg_files = list(image_dir.glob("*.jpeg"))
|
||
|
||
total = len(jpg_files) + len(png_files) + len(jpeg_files)
|
||
print(f" 图片统计: {len(jpg_files)} JPG, {len(png_files)} PNG, {len(jpeg_files)} JPEG")
|
||
print(f" 总计: {total} 张图片")
|
||
|
||
# 检查命名规范
|
||
non_standard = []
|
||
for img in jpg_files:
|
||
if not (img.name.startswith("图片_") or
|
||
img.name.startswith("设计图_") or
|
||
img.name.startswith("场景图_") or
|
||
img.name.startswith("展示图_")):
|
||
non_standard.append(img.name)
|
||
|
||
if non_standard:
|
||
print(f" ⚠️ 非标准命名: {len(non_standard)} 个")
|
||
for name in non_standard[:5]: # 只显示前5个
|
||
print(f" - {name}")
|
||
if len(non_standard) > 5:
|
||
print(f" ... 还有 {len(non_standard)-5} 个")
|
||
else:
|
||
print(f" ✅ 所有图片命名规范")
|
||
|
||
# 检查MD文件中的图片引用
|
||
md_files = list((order_dir / "notion文稿").glob("*.md"))
|
||
if md_files:
|
||
import re
|
||
broken_refs = []
|
||
for md_file in md_files:
|
||
content = md_file.read_text(encoding='utf-8')
|
||
# 查找图片引用
|
||
img_refs = re.findall(r'!\[.*?\]\((.*?)\)', content)
|
||
for ref in img_refs:
|
||
if ref.startswith('image/'):
|
||
img_path = order_dir / "notion文稿" / ref
|
||
if not img_path.exists():
|
||
broken_refs.append((md_file.name, ref))
|
||
|
||
if broken_refs:
|
||
print(f" ⚠️ 损坏的图片引用: {len(broken_refs)} 个")
|
||
for md_name, ref in broken_refs[:3]:
|
||
print(f" - {md_name}: {ref}")
|
||
else:
|
||
print(f" ✅ 所有图片引用有效")
|
||
|
||
def quick_validate(order_classes: List[str]):
|
||
"""快速验证指定订单班的结果"""
|
||
print("\n" + "=" * 60)
|
||
print("快速验证结果")
|
||
print("=" * 60)
|
||
|
||
# 统计图片数量
|
||
total_images = 0
|
||
for dir_name in order_classes:
|
||
order_dir = DATA_PATH / dir_name
|
||
if order_dir.exists() and order_dir.is_dir():
|
||
image_dir = order_dir / "notion文稿" / "image"
|
||
if image_dir.exists():
|
||
count = len(list(image_dir.glob("*.jpg")))
|
||
if count > 0:
|
||
print(f" {dir_name}: {count} 张图片")
|
||
total_images += count
|
||
|
||
print(f"\n总计: {total_images} 张图片")
|
||
|
||
# 检查URL编码(只在选定的目录中)
|
||
print("\n检查URL编码路径...")
|
||
import subprocess
|
||
url_paths_count = 0
|
||
for dir_name in order_classes:
|
||
order_dir = DATA_PATH / dir_name
|
||
if order_dir.exists():
|
||
result = subprocess.run(
|
||
['grep', '-r', '%[0-9A-F][0-9A-F]', str(order_dir)],
|
||
capture_output=True,
|
||
text=True
|
||
)
|
||
url_paths = [line for line in result.stdout.split('\n')
|
||
if any(ext in line for ext in ['.jpg', '.jpeg', '.png'])]
|
||
if url_paths:
|
||
url_paths_count += len(url_paths)
|
||
print(f" {dir_name}: {len(url_paths)} 个URL编码路径")
|
||
|
||
if url_paths_count == 0:
|
||
print("✅ 没有URL编码路径")
|
||
|
||
def process_single_order_class(order_name: str, action: str):
|
||
"""处理单个订单班"""
|
||
print(f"\n=== 处理 {order_name} ===")
|
||
|
||
order_dir = DATA_PATH / order_name
|
||
if not order_dir.exists():
|
||
print(f"⚠️ {order_name} 目录不存在")
|
||
return
|
||
|
||
if action == "validate":
|
||
validate_order_class(order_name)
|
||
elif action == "fix":
|
||
# 使用独立的修复脚本
|
||
print(f"修复 {order_name} 的图片...")
|
||
import sys
|
||
sys.path.insert(0, str(SCRIPT_PATH))
|
||
from fix_image_paths import fix_order_class_images
|
||
refs, files = fix_order_class_images(order_dir)
|
||
if refs > 0 or files > 0:
|
||
print(f" ✅ 完成修复: {refs} 个引用, {files} 个文件")
|
||
elif action == "backup":
|
||
backup_data([order_name])
|
||
|
||
def main():
|
||
"""主函数"""
|
||
print_banner()
|
||
|
||
print("请选择操作模式:")
|
||
print("1. 处理所有订单班")
|
||
print("2. 选择特定订单班")
|
||
print("3. 单独检查每个订单班")
|
||
print("4. 快速验证")
|
||
print("5. 退出")
|
||
print()
|
||
|
||
mode = input("请输入选项 (1-5): ").strip()
|
||
|
||
if mode == "1":
|
||
# 处理所有订单班(原有逻辑)
|
||
print("\n=== 处理所有订单班 ===")
|
||
|
||
print("\n请选择执行操作:")
|
||
print("1. 完整执行(推荐)")
|
||
print("2. 仅验证")
|
||
print("3. 仅修复路径")
|
||
print()
|
||
|
||
choice = input("请输入选项 (1-3): ").strip()
|
||
|
||
if choice == "1":
|
||
# 完整执行
|
||
print("\n=== 完整执行模式 ===\n")
|
||
|
||
# 询问是否备份
|
||
backup_choice = input("是否需要先备份?(y/n): ").strip().lower()
|
||
if backup_choice == 'y':
|
||
backup_data()
|
||
|
||
# 执行主要脚本
|
||
print("\n开始处理图片...")
|
||
|
||
# 1. 处理所有订单班图片
|
||
run_script_for_orders("fix_all_orders_images.py", "统一图片格式和重命名", ALL_ORDER_CLASSES)
|
||
|
||
# 2. 修复Markdown路径
|
||
run_script_for_orders("fix_all_markdown_paths.py", "修复Markdown路径", ALL_ORDER_CLASSES)
|
||
|
||
# 3. 完成最终修复
|
||
run_script_for_orders("complete_fix_paths.py", "修复特殊路径问题", ALL_ORDER_CLASSES)
|
||
|
||
# 4. 验证结果
|
||
run_script_for_orders("final_validation.py", "验证所有路径", ALL_ORDER_CLASSES)
|
||
|
||
elif choice == "2":
|
||
# 仅验证
|
||
print("\n=== 验证模式 ===")
|
||
run_script_for_orders("final_validation.py", "验证所有路径", ALL_ORDER_CLASSES)
|
||
quick_validate(ALL_ORDER_CLASSES)
|
||
|
||
elif choice == "3":
|
||
# 仅修复路径
|
||
print("\n=== 修复路径模式 ===")
|
||
run_script_for_orders("fix_all_markdown_paths.py", "修复Markdown路径", ALL_ORDER_CLASSES)
|
||
run_script_for_orders("complete_fix_paths.py", "修复特殊路径问题", ALL_ORDER_CLASSES)
|
||
run_script_for_orders("final_validation.py", "验证修复结果", ALL_ORDER_CLASSES)
|
||
|
||
elif mode == "2":
|
||
# 选择特定订单班
|
||
print("\n=== 选择特定订单班 ===")
|
||
selected = select_order_classes()
|
||
|
||
if not selected:
|
||
print("未选择任何订单班")
|
||
return
|
||
|
||
print(f"\n已选择: {', '.join(selected)}")
|
||
|
||
print("\n请选择操作:")
|
||
print("1. 验证")
|
||
print("2. 修复")
|
||
print("3. 备份")
|
||
print("4. 完整处理")
|
||
print()
|
||
|
||
action = input("请输入选项 (1-4): ").strip()
|
||
|
||
if action == "1":
|
||
for order_name in selected:
|
||
validate_order_class(order_name)
|
||
elif action == "2":
|
||
print("\n修复选定的订单班...")
|
||
# 可以在这里添加具体的修复逻辑
|
||
for order_name in selected:
|
||
process_single_order_class(order_name, "fix")
|
||
elif action == "3":
|
||
backup_data(selected)
|
||
elif action == "4":
|
||
backup_choice = input("是否需要先备份?(y/n): ").strip().lower()
|
||
if backup_choice == 'y':
|
||
backup_data(selected)
|
||
|
||
print("\n开始处理选定的订单班...")
|
||
run_script_for_orders("fix_all_orders_images.py", "统一图片格式和重命名", selected)
|
||
run_script_for_orders("fix_all_markdown_paths.py", "修复Markdown路径", selected)
|
||
run_script_for_orders("complete_fix_paths.py", "修复特殊路径问题", selected)
|
||
quick_validate(selected)
|
||
|
||
elif mode == "3":
|
||
# 单独检查每个订单班
|
||
print("\n=== 单独检查每个订单班 ===")
|
||
available = list_order_classes()
|
||
|
||
for order_name in available:
|
||
validate_order_class(order_name)
|
||
|
||
# 询问是否继续
|
||
if order_name != available[-1]: # 如果不是最后一个
|
||
cont = input("\n按Enter继续,输入q退出: ").strip()
|
||
if cont.lower() == 'q':
|
||
break
|
||
|
||
elif mode == "4":
|
||
# 快速验证
|
||
print("\n=== 快速验证模式 ===")
|
||
selected = select_order_classes()
|
||
quick_validate(selected)
|
||
|
||
elif mode == "5":
|
||
print("退出程序")
|
||
sys.exit(0)
|
||
else:
|
||
print("无效选项")
|
||
sys.exit(1)
|
||
|
||
print("\n" + "=" * 60)
|
||
print("✅ 执行完成!")
|
||
print("=" * 60)
|
||
|
||
if __name__ == "__main__":
|
||
main() |