123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 |
- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-
- """
- 导航配置验证工具
- 版本: 1.0
- 描述: 验证导航架构配置文档的完整性和正确性
- """
- import os
- import sys
- import json
- import re
- from pathlib import Path
- # 添加项目根目录到Python路径
- project_root = Path(__file__).parent.parent.parent
- sys.path.append(str(project_root))
- class Colors:
- """终端颜色定义"""
- RED = '\033[91m'
- GREEN = '\033[92m'
- YELLOW = '\033[93m'
- BLUE = '\033[94m'
- MAGENTA = '\033[95m'
- CYAN = '\033[96m'
- WHITE = '\033[97m'
- BOLD = '\033[1m'
- UNDERLINE = '\033[4m'
- RESET = '\033[0m'
- def print_message(color, message):
- """打印带颜色的消息"""
- print(f"{color}{message}{Colors.RESET}")
- def print_success(message):
- print_message(Colors.GREEN, f"✓ {message}")
- def print_info(message):
- print_message(Colors.BLUE, f"ℹ {message}")
- def print_warning(message):
- print_message(Colors.YELLOW, f"⚠ {message}")
- def print_error(message):
- print_message(Colors.RED, f"✗ {message}")
- class NavigationConfigValidator:
- """导航配置验证器"""
-
- def __init__(self):
- self.project_root = project_root
- self.config_file = self.project_root / "process_docs" / "导航架构配置.md"
- self.page_list_file = self.project_root / "process_docs" / "页面清单.md"
- self.issues = []
-
- def validate_all(self):
- """执行所有验证检查"""
- print_message(Colors.BOLD + Colors.CYAN, "🔍 导航配置验证工具")
- print_message(Colors.CYAN, "=" * 60)
-
- # 检查配置文件是否存在
- if not self.config_file.exists():
- print_error(f"导航配置文件不存在: {self.config_file}")
- return False
-
- # 读取配置文件
- try:
- with open(self.config_file, 'r', encoding='utf-8') as f:
- self.config_content = f.read()
- except Exception as e:
- print_error(f"读取导航配置文件失败: {e}")
- return False
-
- # 读取页面清单文件
- if self.page_list_file.exists():
- try:
- with open(self.page_list_file, 'r', encoding='utf-8') as f:
- self.page_list_content = f.read()
- except Exception as e:
- print_warning(f"读取页面清单文件失败: {e}")
- self.page_list_content = ""
- else:
- print_warning("页面清单文件不存在,将跳过相关验证")
- self.page_list_content = ""
-
- # 执行各项验证
- all_passed = True
- all_passed &= self.validate_config_structure()
- all_passed &= self.validate_navigation_json()
- all_passed &= self.validate_route_mapping()
- all_passed &= self.validate_component_templates()
- all_passed &= self.validate_css_javascript_specs()
- all_passed &= self.validate_page_consistency()
-
- # 输出验证结果
- self.print_summary(all_passed)
- return all_passed
-
- def validate_config_structure(self):
- """验证配置文档结构"""
- print_info("验证导航配置文档结构...")
-
- required_sections = [
- "系统导航架构配置",
- "主导航结构",
- "侧边栏导航结构",
- "面包屑导航配置",
- "页面路由映射表",
- "导航状态管理规范",
- "导航HTML组件模板"
- ]
-
- missing_sections = []
- for section in required_sections:
- if section not in self.config_content:
- missing_sections.append(section)
-
- if missing_sections:
- for section in missing_sections:
- print_error(f" 缺少必需章节: {section}")
- return False
- else:
- print_success("配置文档结构完整")
- return True
-
- def validate_navigation_json(self):
- """验证导航JSON配置"""
- print_info("验证导航JSON配置...")
-
- # 查找JSON配置块
- json_pattern = r'```json\s*(\{.*?\})\s*```'
- json_matches = re.findall(json_pattern, self.config_content, re.DOTALL)
-
- if not json_matches:
- print_error("未找到导航JSON配置")
- return False
-
- valid_json_count = 0
- for i, json_str in enumerate(json_matches):
- try:
- config = json.loads(json_str)
-
- # 验证主导航配置
- if 'header' in config:
- if self.validate_header_config(config['header']):
- valid_json_count += 1
-
- # 验证侧边栏配置
- if 'sidebar' in config:
- if self.validate_sidebar_config(config['sidebar']):
- valid_json_count += 1
-
- # 验证面包屑配置
- if 'breadcrumbs' in config:
- if self.validate_breadcrumb_config(config['breadcrumbs']):
- valid_json_count += 1
-
- except json.JSONDecodeError as e:
- print_error(f" JSON配置 {i+1} 格式错误: {e}")
-
- if valid_json_count > 0:
- print_success(f"找到 {valid_json_count} 个有效的JSON配置")
- return True
- else:
- print_error("未找到有效的JSON配置")
- return False
-
- def validate_header_config(self, header_config):
- """验证头部导航配置"""
- required_fields = ['logo', 'mainMenu', 'userMenu']
-
- for field in required_fields:
- if field not in header_config:
- print_error(f" 头部配置缺少字段: {field}")
- return False
-
- # 验证主菜单结构
- if 'mainMenu' in header_config and isinstance(header_config['mainMenu'], list):
- for menu_item in header_config['mainMenu']:
- if not all(key in menu_item for key in ['id', 'label', 'route']):
- print_error(" 主菜单项缺少必需字段 (id, label, route)")
- return False
-
- return True
-
- def validate_sidebar_config(self, sidebar_config):
- """验证侧边栏配置"""
- required_fields = ['collapsible', 'sections']
-
- for field in required_fields:
- if field not in sidebar_config:
- print_error(f" 侧边栏配置缺少字段: {field}")
- return False
-
- # 验证菜单项结构
- if 'sections' in sidebar_config and isinstance(sidebar_config['sections'], list):
- for section in sidebar_config['sections']:
- if 'items' in section and isinstance(section['items'], list):
- for item in section['items']:
- if not all(key in item for key in ['id', 'label', 'route']):
- print_error(" 侧边栏菜单项缺少必需字段 (id, label, route)")
- return False
-
- return True
-
- def validate_breadcrumb_config(self, breadcrumb_config):
- """验证面包屑配置"""
- if not isinstance(breadcrumb_config, dict):
- print_error(" 面包屑配置格式错误")
- return False
-
- # 检查是否有路径映射
- if not breadcrumb_config:
- print_warning(" 面包屑配置为空")
- return True
-
- # 验证路径映射格式
- for path, breadcrumb in breadcrumb_config.items():
- if not isinstance(breadcrumb, list):
- print_error(f" 面包屑路径 {path} 配置格式错误")
- return False
-
- for item in breadcrumb:
- if not all(key in item for key in ['label', 'route']):
- print_error(f" 面包屑项 {path} 缺少必需字段 (label, route)")
- return False
-
- return True
-
- def validate_route_mapping(self):
- """验证路由映射表"""
- print_info("验证页面路由映射表...")
-
- # 查找路由映射表
- table_pattern = r'\|[^|]*页面名称[^|]*\|[^|]*路由路径[^|]*\|.*?\n(\|.*?\n)+'
- table_match = re.search(table_pattern, self.config_content)
-
- if not table_match:
- print_error("未找到页面路由映射表")
- return False
-
- # 解析表格内容
- table_content = table_match.group(0)
- rows = [row.strip() for row in table_content.split('\n') if row.strip().startswith('|')]
-
- if len(rows) < 3: # 至少要有表头、分隔符、一行数据
- print_error("路由映射表内容不足")
- return False
-
- print_success(f"找到路由映射表,包含 {len(rows)-2} 个页面路由")
- return True
-
- def validate_component_templates(self):
- """验证组件模板"""
- print_info("验证导航组件模板...")
-
- required_templates = [
- "Header组件模板",
- "Sidebar组件模板",
- "Breadcrumb组件模板"
- ]
-
- missing_templates = []
- for template in required_templates:
- if template not in self.config_content:
- missing_templates.append(template)
-
- # 查找HTML代码块
- html_pattern = r'```html\s*(.*?)\s*```'
- html_matches = re.findall(html_pattern, self.config_content, re.DOTALL)
-
- if not html_matches:
- print_error("未找到HTML组件模板")
- return False
-
- valid_templates = 0
- for html_code in html_matches:
- if any(tag in html_code.lower() for tag in ['header', 'aside', 'nav']):
- valid_templates += 1
-
- if missing_templates:
- for template in missing_templates:
- print_warning(f" 缺少模板: {template}")
-
- if valid_templates > 0:
- print_success(f"找到 {valid_templates} 个HTML组件模板")
- return True
- else:
- print_error("未找到有效的HTML组件模板")
- return False
-
- def validate_css_javascript_specs(self):
- """验证CSS和JavaScript规范"""
- print_info("验证CSS和JavaScript规范...")
-
- # 查找CSS类名规范
- css_pattern = r'CSS类名|class|className'
- css_found = re.search(css_pattern, self.config_content, re.IGNORECASE)
-
- # 查找JavaScript规范
- js_pattern = r'JavaScript|javascript|js|Navigation.*Controller'
- js_found = re.search(js_pattern, self.config_content, re.IGNORECASE)
-
- issues = []
- if not css_found:
- issues.append("缺少CSS类名规范说明")
-
- if not js_found:
- issues.append("缺少JavaScript交互规范说明")
-
- if issues:
- for issue in issues:
- print_warning(f" {issue}")
- return True # 这些是警告,不是错误
- else:
- print_success("CSS和JavaScript规范说明完整")
- return True
-
- def validate_page_consistency(self):
- """验证与页面清单的一致性"""
- print_info("验证与页面清单的一致性...")
-
- if not self.page_list_content:
- print_warning("无法验证页面一致性:页面清单文件不存在")
- return True
-
- # 从页面清单中提取页面名称
- page_pattern = r'(?:#+\s*)?(\d+\.\s*)?([^#\n]+?)(?:页面|页|Page)'
- page_matches = re.findall(page_pattern, self.page_list_content)
-
- if not page_matches:
- print_warning("未能从页面清单中识别页面名称")
- return True
-
- page_names = [match[1].strip() for match in page_matches if match[1].strip()]
-
- # 检查导航配置中是否包含这些页面
- missing_pages = []
- for page_name in page_names:
- if page_name not in self.config_content:
- missing_pages.append(page_name)
-
- if missing_pages:
- for page in missing_pages:
- print_warning(f" 导航配置中可能缺少页面: {page}")
- return True # 这是警告,不是错误
- else:
- print_success(f"导航配置与页面清单一致 (检查了 {len(page_names)} 个页面)")
- return True
-
- def print_summary(self, all_passed):
- """打印验证结果摘要"""
- print_message(Colors.CYAN, "=" * 60)
-
- if all_passed:
- print_success("🎉 导航配置验证通过!")
- print_info("导航架构配置完整,可以开始页面代码生成")
- else:
- print_error("❌ 发现导航配置问题")
- print_warning("请修复上述问题后再进行页面代码生成")
- print_info("建议:")
- print(" 1. 补充缺少的配置章节")
- print(" 2. 修复JSON配置格式错误")
- print(" 3. 完善组件模板定义")
- print(" 4. 确保路由映射表完整")
-
- print_message(Colors.CYAN, "=" * 60)
- def main():
- """主函数"""
- try:
- validator = NavigationConfigValidator()
- success = validator.validate_all()
-
- # 返回适当的退出码
- sys.exit(0 if success else 1)
-
- except Exception as e:
- print_error(f"验证过程中发生错误: {e}")
- import traceback
- traceback.print_exc()
- sys.exit(1)
- if __name__ == "__main__":
- main()
|