merge_all_simple.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """
  4. 全部源代码软著申请专用拼接脚本 (Python版本)
  5. 功能:一键执行前端、后端、数据库所有代码的拼接,并生成完整的申请材料包
  6. 特点:
  7. - 一键执行所有合并脚本
  8. - 生成完整的申请材料清单
  9. - 跨平台兼容(Windows/Linux/macOS)
  10. - 智能错误处理和恢复
  11. """
  12. import os
  13. import sys
  14. import json
  15. import subprocess
  16. from pathlib import Path
  17. from datetime import datetime
  18. from typing import List, Dict, Optional
  19. # 颜色输出类
  20. class Colors:
  21. RED = '\033[0;31m'
  22. GREEN = '\033[0;32m'
  23. YELLOW = '\033[1;33m'
  24. BLUE = '\033[0;34m'
  25. PURPLE = '\033[0;35m'
  26. CYAN = '\033[0;36m'
  27. NC = '\033[0m' # No Color
  28. def print_success(message: str):
  29. print(f"{Colors.GREEN}✓ {message}{Colors.NC}")
  30. def print_info(message: str):
  31. print(f"{Colors.BLUE}ℹ {message}{Colors.NC}")
  32. def print_warning(message: str):
  33. print(f"{Colors.YELLOW}⚠ {message}{Colors.NC}")
  34. def print_error(message: str):
  35. print(f"{Colors.RED}✗ {message}{Colors.NC}")
  36. def print_header(message: str):
  37. print(f"{Colors.PURPLE}{'=' * 80}{Colors.NC}")
  38. print(f"{Colors.PURPLE}{message.center(80)}{Colors.NC}")
  39. print(f"{Colors.PURPLE}{'=' * 80}{Colors.NC}")
  40. def get_project_config() -> Optional[dict]:
  41. """读取项目配置文件"""
  42. config_file = Path("ai-copyright-config.json")
  43. if not config_file.exists():
  44. print_error("配置文件不存在: ai-copyright-config.json")
  45. return None
  46. try:
  47. with open(config_file, 'r', encoding='utf-8') as f:
  48. return json.load(f)
  49. except json.JSONDecodeError as e:
  50. print_error(f"配置文件JSON格式错误: {e}")
  51. return None
  52. except Exception as e:
  53. print_error(f"读取配置文件失败: {e}")
  54. return None
  55. def run_merge_script(script_name: str, script_path: Path) -> Dict[str, any]:
  56. """运行单个合并脚本"""
  57. result = {
  58. 'script': script_name,
  59. 'success': False,
  60. 'output': '',
  61. 'error': '',
  62. 'execution_time': 0
  63. }
  64. try:
  65. print_info(f"执行脚本: {script_name}")
  66. start_time = datetime.now()
  67. # 运行Python脚本
  68. process = subprocess.run(
  69. [sys.executable, str(script_path)],
  70. capture_output=True,
  71. text=True,
  72. cwd=Path.cwd(),
  73. timeout=300 # 5分钟超时
  74. )
  75. end_time = datetime.now()
  76. result['execution_time'] = (end_time - start_time).total_seconds()
  77. result['output'] = process.stdout
  78. result['error'] = process.stderr
  79. result['success'] = process.returncode == 0
  80. if result['success']:
  81. print_success(f"{script_name} 执行成功 (用时: {result['execution_time']:.1f}秒)")
  82. else:
  83. print_error(f"{script_name} 执行失败")
  84. if result['error']:
  85. print_error(f"错误信息: {result['error']}")
  86. except subprocess.TimeoutExpired:
  87. print_error(f"{script_name} 执行超时")
  88. result['error'] = "执行超时"
  89. except Exception as e:
  90. print_error(f"{script_name} 执行异常: {e}")
  91. result['error'] = str(e)
  92. return result
  93. def check_generated_files() -> Dict[str, Dict[str, any]]:
  94. """检查生成的文件"""
  95. output_dir = Path("output_docs")
  96. expected_files = {
  97. "前端源代码.txt": "前端页面源代码文档",
  98. "后端源代码.txt": "后端业务逻辑源代码文档",
  99. "数据库源代码.txt": "数据库设计和建表语句文档"
  100. }
  101. file_status = {}
  102. for filename, description in expected_files.items():
  103. file_path = output_dir / filename
  104. status = {
  105. 'exists': file_path.exists(),
  106. 'size': 0,
  107. 'size_mb': 0,
  108. 'description': description,
  109. 'path': str(file_path)
  110. }
  111. if status['exists']:
  112. try:
  113. status['size'] = file_path.stat().st_size
  114. status['size_mb'] = status['size'] / (1024 * 1024)
  115. except:
  116. status['size'] = 0
  117. file_status[filename] = status
  118. return file_status
  119. def generate_application_summary(config: dict, file_status: Dict, execution_results: List[Dict]) -> str:
  120. """生成申请材料总结报告"""
  121. current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
  122. summary = f"""
  123. {'-' * 80}
  124. 软件著作权申请材料生成总结报告
  125. {'-' * 80}
  126. 项目信息:
  127. - 软件名称: {config.get('title', '未设置')}
  128. - 软件简称: {config.get('short_title', config.get('title', '未设置'))}
  129. - 前端技术: {config.get('front', '未设置')}
  130. - 后端技术: {config.get('backend', '未设置')}
  131. - UI设计风格: {config.get('ui_design_style', '未设置')}
  132. - 生成模式: {config.get('generation_mode', '未设置')}
  133. 生成时间: {current_time}
  134. {'-' * 80}
  135. 申请材料文档清单
  136. {'-' * 80}
  137. """
  138. total_size = 0
  139. total_files = 0
  140. for filename, status in file_status.items():
  141. if status['exists']:
  142. summary += f"✓ {filename}\n"
  143. summary += f" 描述: {status['description']}\n"
  144. summary += f" 大小: {status['size']:,} 字节 ({status['size_mb']:.2f} MB)\n"
  145. summary += f" 路径: {status['path']}\n\n"
  146. total_size += status['size']
  147. total_files += 1
  148. else:
  149. summary += f"✗ {filename} (文件不存在)\n"
  150. summary += f" 描述: {status['description']}\n\n"
  151. summary += f"总计: {total_files} 个文件,{total_size:,} 字节 ({total_size / (1024 * 1024):.2f} MB)\n\n"
  152. # 执行结果统计
  153. summary += f"{'-' * 80}\n执行结果统计\n{'-' * 80}\n\n"
  154. success_count = sum(1 for r in execution_results if r['success'])
  155. total_time = sum(r['execution_time'] for r in execution_results)
  156. summary += f"执行脚本数量: {len(execution_results)}\n"
  157. summary += f"成功执行: {success_count}\n"
  158. summary += f"失败执行: {len(execution_results) - success_count}\n"
  159. summary += f"总执行时间: {total_time:.1f} 秒\n\n"
  160. for result in execution_results:
  161. status_symbol = "✓" if result['success'] else "✗"
  162. summary += f"{status_symbol} {result['script']} (用时: {result['execution_time']:.1f}秒)\n"
  163. if not result['success'] and result['error']:
  164. summary += f" 错误: {result['error']}\n"
  165. # 申请建议
  166. summary += f"\n{'-' * 80}\n申请材料使用建议\n{'-' * 80}\n\n"
  167. if total_files == 3:
  168. summary += "✅ 所有必需的源代码文档已生成完成\n\n"
  169. summary += "下一步操作:\n"
  170. summary += "1. 检查各文档内容的完整性和准确性\n"
  171. summary += "2. 根据需要生成用户手册和软件著作权登记信息表\n"
  172. summary += "3. 准备其他申请材料(申请表、身份证明等)\n"
  173. summary += "4. 提交至软件著作权登记机构\n\n"
  174. if total_size > 1024 * 1024: # 大于1MB
  175. summary += "📊 文档规模良好,内容充实,有利于申请通过\n"
  176. else:
  177. summary += "⚠️ 文档规模较小,建议检查内容是否完整\n"
  178. else:
  179. summary += "❌ 部分源代码文档生成失败,请检查并重新生成\n\n"
  180. summary += "故障排除建议:\n"
  181. summary += "1. 确认 output_sourcecode/ 目录下已生成相应的代码文件\n"
  182. summary += "2. 检查Python环境和脚本权限\n"
  183. summary += "3. 查看详细错误信息进行针对性修复\n"
  184. summary += f"\n{'-' * 80}\n报告生成时间: {current_time}\n{'-' * 80}\n"
  185. return summary
  186. def merge_all_sources():
  187. """执行所有源代码合并"""
  188. print_header("开始执行完整软著申请材料生成")
  189. # 1. 读取项目配置
  190. config = get_project_config()
  191. if not config:
  192. print_warning("无法读取项目配置,使用默认配置")
  193. config = {
  194. 'title': '软件系统',
  195. 'short_title': '软件系统',
  196. 'front': 'JavaScript',
  197. 'backend': 'Java',
  198. 'ui_design_style': 'corporate',
  199. 'generation_mode': 'fast'
  200. }
  201. print_info(f"项目: {config.get('title', '未设置')}")
  202. print_info(f"技术栈: {config.get('front', '未设置')} + {config.get('backend', '未设置')}")
  203. print_info(f"生成模式: {config.get('generation_mode', '未设置')}")
  204. print()
  205. # 2. 定义合并脚本
  206. script_dir = Path(__file__).parent
  207. merge_scripts = [
  208. ("前端代码合并", script_dir / "merge_frontend_simple.py"),
  209. ("后端代码合并", script_dir / "merge_backend_simple.py"),
  210. ("数据库代码合并", script_dir / "merge_database_simple.py")
  211. ]
  212. # 3. 检查脚本存在性
  213. available_scripts = []
  214. for name, script_path in merge_scripts:
  215. if script_path.exists():
  216. available_scripts.append((name, script_path))
  217. print_success(f"脚本就绪: {name}")
  218. else:
  219. print_warning(f"脚本不存在: {name} ({script_path})")
  220. if not available_scripts:
  221. print_error("未发现任何合并脚本")
  222. return False
  223. print()
  224. # 4. 逐个执行合并脚本
  225. execution_results = []
  226. for i, (name, script_path) in enumerate(available_scripts, 1):
  227. print_header(f"第 {i}/{len(available_scripts)} 步: {name}")
  228. result = run_merge_script(name, script_path)
  229. execution_results.append(result)
  230. print()
  231. # 5. 检查生成的文件
  232. print_header("检查生成的申请材料文档")
  233. file_status = check_generated_files()
  234. for filename, status in file_status.items():
  235. if status['exists']:
  236. print_success(f"{filename} - {status['size_mb']:.2f} MB")
  237. else:
  238. print_error(f"{filename} - 文件不存在")
  239. print()
  240. # 6. 生成总结报告
  241. print_info("生成申请材料总结报告...")
  242. output_dir = Path("output_docs")
  243. output_dir.mkdir(parents=True, exist_ok=True)
  244. summary = generate_application_summary(config, file_status, execution_results)
  245. # 保存总结报告
  246. summary_file = output_dir / "软著申请材料总结报告.txt"
  247. try:
  248. with open(summary_file, 'w', encoding='utf-8') as f:
  249. f.write(summary)
  250. print_success(f"总结报告已保存: {summary_file}")
  251. except Exception as e:
  252. print_error(f"保存总结报告失败: {e}")
  253. # 7. 输出最终结果
  254. success_count = sum(1 for r in execution_results if r['success'])
  255. total_scripts = len(execution_results)
  256. existing_files = sum(1 for s in file_status.values() if s['exists'])
  257. print_header("申请材料生成完成")
  258. if success_count == total_scripts and existing_files == len(file_status):
  259. print_success("🎉 所有申请材料已成功生成!")
  260. print_info("📋 请查看 output_docs/ 目录下的所有文档")
  261. print_info("📄 详细信息请参考: 软著申请材料总结报告.txt")
  262. return True
  263. else:
  264. print_warning(f"⚠️ 部分材料生成失败 ({success_count}/{total_scripts} 脚本成功, {existing_files}/{len(file_status)} 文件存在)")
  265. print_info("🔧 请检查错误信息并重新生成失败的部分")
  266. return False
  267. def main():
  268. """主函数"""
  269. if len(sys.argv) > 1 and sys.argv[1] in ['-h', '--help']:
  270. print("全部源代码拼接脚本 (Python版本)")
  271. print("\n用法:")
  272. print(" python3 merge_all_simple.py")
  273. print("\n功能:")
  274. print(" 一键执行前端、后端、数据库所有代码的拼接")
  275. print(" 生成完整的软著申请材料包")
  276. print("\n输出文件:")
  277. print(" output_docs/前端源代码.txt")
  278. print(" output_docs/后端源代码.txt")
  279. print(" output_docs/数据库源代码.txt")
  280. print(" output_docs/软著申请材料总结报告.txt")
  281. print(" output_docs/*拼接报告.txt")
  282. print("\n注意:")
  283. print(" 请确保已生成前端、后端、数据库代码文件")
  284. print(" 运行前请检查 output_sourcecode/ 目录内容")
  285. return
  286. success = merge_all_sources()
  287. sys.exit(0 if success else 1)
  288. if __name__ == "__main__":
  289. main()