review_results.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. """
  2. 审查结果获取接口Mock实现
  3. 模拟风险统计、总结报告和问题条文返回
  4. """
  5. import random
  6. import os
  7. import json
  8. from datetime import datetime
  9. from fastapi import APIRouter, HTTPException, Query
  10. from pydantic import BaseModel
  11. from typing import Optional, Dict, Any
  12. from .schemas.error_schemas import ReviewResultsErrors
  13. # 导入文件上传模块的存储
  14. try:
  15. from .file_upload import uploaded_files
  16. except ImportError:
  17. from views.construction_review.file_upload import uploaded_files
  18. class ReviewResultsRequest(BaseModel):
  19. id: str = None
  20. user: str = None
  21. type: str = None # "summary" 或 "issues"
  22. class ReviewResultsResponse(BaseModel):
  23. code: int
  24. data: Dict[str, Any]
  25. review_results_router = APIRouter(prefix="/sgsc", tags=["前端接口"])
  26. def generate_risk_stats():
  27. """生成模拟风险统计"""
  28. return {
  29. "high": random.randint(1, 5),
  30. "medium": random.randint(3, 8),
  31. "low": random.randint(2, 6)
  32. }
  33. def generate_dimension_scores():
  34. """生成模拟四维评分"""
  35. return {
  36. "safety": random.randint(60, 95),
  37. "quality": random.randint(55, 90),
  38. "schedule": random.randint(70, 95),
  39. "cost": random.randint(65, 90)
  40. }
  41. def generate_summary_report(risk_stats):
  42. """生成模拟总结报告"""
  43. total_issues = sum(risk_stats.values())
  44. if risk_stats["high"] > 0:
  45. return f"该施工方案存在{risk_stats['high']}处高风险问题,需重点整改。建议在施工前完善相关技术细节,确保符合规范要求。"
  46. elif total_issues > 5:
  47. return f"该施工方案整体符合规范要求,但存在{total_issues}处中低风险问题,建议优化完善。"
  48. else:
  49. return "该施工方案整体符合规范要求,存在少量细节问题,可正常施工。"
  50. def generate_issues():
  51. """生成模拟问题条文"""
  52. issues = []
  53. # 高风险问题示例
  54. high_risk_issues = [
  55. {
  56. "page": 12,
  57. "chapter": "1.1 路面材料要求",
  58. "original_content": "采用沥青、混凝土作为路面施工材料,未明确标号及来源;施工段落仅标注主线段,未细化具体桩号范围"
  59. },
  60. {
  61. "page": 45,
  62. "chapter": "3.2 模板安装工艺",
  63. "original_content": "模板未按设计要求进行预压,直接浇筑混凝土;预压观测记录采用文字描述,未体现观测点布置及沉降数据"
  64. }
  65. ]
  66. # 中风险问题示例
  67. medium_risk_issues = [
  68. {
  69. "page": 28,
  70. "chapter": "2.3 施工机械配置",
  71. "original_content": "施工机械清单未包含备用设备,未制定设备故障应急预案"
  72. },
  73. {
  74. "page": 67,
  75. "chapter": "4.1 质量保证措施",
  76. "original_content": "质量检测频次未明确具体标准,检验方法描述不够详细"
  77. }
  78. ]
  79. # 生成高风险问题
  80. for i, issue_data in enumerate(high_risk_issues):
  81. issue_id = f"ISSUE-HL-{datetime.now().strftime('%Y%m%d')}-{i+1:03d}"
  82. reviews = [
  83. {
  84. "check_item": "强制性标准符合性检查",
  85. "check_result": "不符合",
  86. "risk_info": {"risk_level": "high"},
  87. "suggestion": {
  88. "suggestion_type": "professional",
  89. "suggestion_content": "按相关规范要求,明确材料规格和施工参数,确保符合技术标准要求",
  90. "verification_standard": "整改后需提供技术规格书,由项目总工签字确认"
  91. }
  92. },
  93. {
  94. "check_item": "条文完整性检查",
  95. "check_result": "不符合",
  96. "risk_info": {"risk_level": "low"},
  97. "suggestion": {
  98. "suggestion_type": "completeness",
  99. "suggestion_content": "补充详细的施工范围描述,与施工平面布置图桩号标注一致",
  100. "verification_standard": "参考施工方案编制导则相关条款"
  101. }
  102. }
  103. ]
  104. issues.append({
  105. "issue_id": issue_id,
  106. "metadata": issue_data,
  107. "risk_summary": {
  108. "max_risk_level": "high",
  109. "risk_count": {"high": 1, "medium": 1, "low": 1},
  110. "key_risk_reminder": "高风险点:技术参数缺失,需24小时内整改"
  111. },
  112. "review_lists": reviews
  113. })
  114. # 生成中风险问题
  115. for i, issue_data in enumerate(medium_risk_issues):
  116. issue_id = f"ISSUE-ML-{datetime.now().strftime('%Y%m%d')}-{i+1:03d}"
  117. reviews = [
  118. {
  119. "check_item": "规范性检查",
  120. "check_result": "不符合",
  121. "risk_info": {"risk_level": "medium"},
  122. "suggestion": {
  123. "suggestion_type": "normative",
  124. "suggestion_content": "完善应急预案制定,明确设备故障处理流程和备用资源配置",
  125. "verification_standard": "参考《施工组织设计规范》相关要求"
  126. }
  127. }
  128. ]
  129. issues.append({
  130. "issue_id": issue_id,
  131. "metadata": issue_data,
  132. "risk_summary": {
  133. "max_risk_level": "medium",
  134. "risk_count": {"high": 0, "medium": 1, "low": 0},
  135. "key_risk_reminder": "中风险点:管理措施不完善,需在施工前完善"
  136. },
  137. "review_lists": reviews
  138. })
  139. return issues
  140. @review_results_router.get("/review_results", response_model=ReviewResultsResponse)
  141. async def review_results(
  142. callback_task_id: str = Query(..., description="回调任务ID"),
  143. user: str = Query(..., description="用户ID")
  144. ):
  145. """
  146. 获取审查结果接口 - 从temp目录读取保存的结果文件
  147. """
  148. try:
  149. # 验证参数
  150. if not callback_task_id:
  151. raise HTTPException(status_code=400, detail="缺少callback_task_id参数")
  152. if not user:
  153. raise HTTPException(status_code=400, detail="缺少user参数")
  154. # 验证用户标识(应该是指定用户如user-001)
  155. valid_users = {"user-001", "user-002", "user-003"} # 可以配置化
  156. if user not in valid_users:
  157. raise HTTPException(status_code=403, detail="无效的用户ID")
  158. # 构建文件路径
  159. temp_dir = "temp"
  160. file_path = os.path.join(temp_dir, f"{callback_task_id}.json")
  161. # 检查文件是否存在
  162. if not os.path.exists(file_path):
  163. raise HTTPException(status_code=404, detail="审查结果文件不存在")
  164. # 读取文件内容
  165. try:
  166. with open(file_path, 'r', encoding='utf-8') as f:
  167. review_results = json.load(f)
  168. except json.JSONDecodeError:
  169. raise HTTPException(status_code=500, detail="审查结果文件格式错误")
  170. except Exception as e:
  171. raise HTTPException(status_code=500, detail=f"读取文件失败: {str(e)}")
  172. # 验证文件中的用户信息是否匹配
  173. if review_results.get("user_id") != user:
  174. raise HTTPException(status_code=403, detail="用户权限验证失败")
  175. return ReviewResultsResponse(
  176. code=200,
  177. data=review_results
  178. )
  179. except HTTPException:
  180. raise
  181. except Exception as e:
  182. raise HTTPException(status_code=500, detail=f"服务器内部错误: {str(e)}")