from fastapi import APIRouter, Request, Depends, HTTPException, Query from sqlalchemy.exc import IntegrityError from fastapi.responses import HTMLResponse, FileResponse from fastapi.responses import JSONResponse from database import get_db from sqlalchemy import text, exists, and_, or_, not_ from sqlalchemy.orm import Session from models import * import json import random from sqlalchemy import create_engine, select from typing import Optional from utils.StripTagsHTMLParser import * from common.db import db_event_management, db_user, db_area, db_emergency_plan from common.security import valid_access_token import traceback from utils import * from datetime import datetime, timedelta router = APIRouter() @router.post('/create') async def create_event( request: Request, db: Session = Depends(get_db), body = Depends(remove_xss_json), user_id = Depends(valid_access_token)): try: # 验证必需的字段 required_fields = ['event_title', 'event_type', 'event_level', 'event_status', 'event_time', 'report_time', 'deaths', 'injuries', "missing", "event_source", "longitude", "latitude", "event_description", "address"] missing_fields = [field for field in required_fields if field not in body] if missing_fields: raise HTTPException(status_code=401, detail=f"Missing required fields: {', '.join(missing_fields)}") eventId = db_event_management.get_next_event_id(db) # 未上报时清空伤亡人数 if body['casualties'] == '0': body['deaths'] = None body['injuries'] = None body['missing'] = None region_code = db_area.get_region_code_by_gps(db, body['longitude'], body['latitude']) event_base = EventBase( **body, event_code = eventId, recorded_by = user_id, region_code = region_code ) db.add(event_base) db.commit() db.refresh(event_base) # 事件跟踪表 event_tracking = EventTracking() event_tracking.event_id = event_base.id event_tracking.event_status = event_base.event_status event_tracking.event_level = event_base.event_level event_tracking.tracking_time = datetime.now() event_tracking.recorded_by = user_id event_tracking.del_flag = "0" db.add(event_tracking) db.commit() return { "code": 200, "msg": "新建事件成功", "data": eventId } except Exception as e: db.rollback() traceback.print_exc() raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}") @router.get('/list') async def get_event_list( event_type: str = Query('', description='事件类型的字典键值'), event_level: str = Query('', description='事件等级的字典键值'), event_status: str = Query('', description='事件状态的字典键值'), event_time: str = Query('', description='事发时间'), region_code: str = Query('', description='行政区划代码'), keyword: str = Query('', description='根据事件标题或描述中的关键字进行模糊搜索'), sort_by: str = Query('', description='排序字段'), sort_order: str = Query("asc", description='排序方式'), page: int = Query(1, gt=0, description='页码'), page_size: int = Query(10, gt=0, description='pageSize'), db: Session = Depends(get_db) ): try: # 应用查询条件 where = and_(EventBase.del_flag == '0') if event_type != '': where = and_(where, EventBase.event_type == event_type) if event_level != '': where = and_(where, EventBase.event_level == event_level) if event_status != '': where = and_(where, EventBase.event_status == event_status) if event_time != '': event_time = datetime.strptime(event_time, "%Y-%m-%d") event_time = event_time + timedelta(days=1) where = and_(where, EventBase.event_time.between(event_time, event_time + timedelta(days=1))) if region_code != '': where = and_(where, EventBase.region_code.like('{}%'.format(region_code))) if keyword != '': where = and_(where, or_(EventBase.event_title.like('%{}%'.format(keyword)), EventBase.address.like('%{}%'.format(keyword)))) print(where) # 计算总条目数 q = db.query(func.count(EventBase.id)) q = q.filter(where) total = q.scalar() # 执行分页查询 q = db.query(EventBase) q = q.filter(where) rows = q.order_by(EventBase.id.desc()).offset((page - 1) * page_size).limit(page_size).all() data = [ { "event_id": row.event_code, "event_title": row.event_title, "event_type": row.event_type, "event_level": row.event_level, "event_status": row.event_status, "latitude": row.latitude, "longitude": row.longitude, "address": row.address, "event_time": get_datetime_str(row.event_time) } for row in rows ] # 返回结果 return { "code": 200, "msg": "查询成功", "data": data, "total": total } except Exception as e: # 处理异常 traceback.print_exc() raise HTTPException(status_code=500, detail=str(e)) @router.get('/edit') async def get_edit_event( request: Request, event_id: str = Query(None, description='事件编号'), db: Session = Depends(get_db)): row = db.query(EventBase).filter(EventBase.event_code == event_id).first() data = get_model_dict(row) data['eventId'] = data['event_code'] data['event_time'] = get_datetime_str(data['event_time']) data['report_time'] = get_datetime_str(data['report_time']) return { "code": 200, "msg": "查询成功", "data": data } @router.post('/edit') async def post_edit_event( request: Request, body = Depends(remove_xss_json), db: Session = Depends(get_db), user_id = Depends(valid_access_token)): eventId = body['eventId'] del body['eventId'] body['recorded_by'] = user_id # 未上报时清空伤亡人数 if body['casualties'] == '0': body['deaths'] = None body['injuries'] = None body['missing'] = None db.query(EventBase).filter(EventBase.event_code == eventId).update(body) db.commit() return { "code": 200, "msg": "保存事件成功" } @router.post("/uploadEventCasualties") async def uploadEventCasualties( request: Request, body = Depends(remove_xss_json), db: Session = Depends(get_db) ): eventId = body['eventId'] del body['eventId'] body['casualties'] = '1' db.query(EventBase).filter(EventBase.event_code == eventId).update(body) db.commit() return { "code": 200, "msg": "上报伤亡情况成功" } @router.get('/detail') async def get_event_detail( request: Request, event_id: str = Query(None, description='事件编号'), db: Session = Depends(get_db)): print('event_id:',event_id) try: # 构建查询 query = db.query(EventBase) query = query.filter(EventBase.event_code == event_id) # 执行查询 row = query.first() if row is not None: return { "code": 200, "msg": "查询成功", "data": { "id": row.id, "event_id": row.event_code, "event_title": row.event_title, "event_type": row.event_type, "event_level": row.event_level, "event_status": row.event_status, "event_source": row.event_source, "event_time": get_datetime_str(row.event_time), "report_time": get_datetime_str(row.report_time), "casualties": row.casualties, "deaths": row.deaths, "injuries": row.injuries, "missing": row.missing, "reported_by": db_user.get_nick_name_by_id(db, row.recorded_by), "contact": row.contact, "event_description": row.event_description, "latitude": row.latitude, "longitude": row.longitude, "address": row.address, "plan_name": db_emergency_plan.get_plan_name_by_id(db, row.plan_id), "del_flag": row.del_flag, "summary_file": db_event_management.get_summary_file_list(db, row.id), # 事件跟踪 "event_status_tracks": db_event_management.get_event_status_track(db, row.id), # 事件等级 "event_level_tracks": db_event_management.get_event_level_track(db, row.id) } } else: return { "code": 500, "msg": "查询失败" } except Exception as e: # 处理异常 traceback.print_exc() raise HTTPException(status_code=500, detail=str(e)) @router.post('/start') async def start_event( request: Request, db: Session = Depends(get_db), body = Depends(remove_xss_json), user_id = Depends(valid_access_token)): try: event_base = db.query(EventBase).filter(EventBase.event_code == body['eventId']).first() if event_base is not None: event_base.event_status = "1" # 开始指挥 event_base.event_level= body['event_level'] event_tracking = EventTracking() event_tracking.event_id = event_base.id event_tracking.event_status = event_base.event_status event_tracking.event_level = body['event_level'] event_tracking.tracking_time = datetime.now() event_tracking.recorded_by = user_id event_tracking.del_flag = "0" db.add(event_tracking) db.commit() return { "code": 200, "msg": "开始指挥成功" } except Exception as e: # 处理异常 db.rollback() traceback.print_exc() raise HTTPException(status_code=500, detail=str(e)) @router.post('/close') async def close_event( request: Request, db: Session = Depends(get_db), body = Depends(remove_xss_json), user_id = Depends(valid_access_token)): try: # 验证必需的字段 required_fields = ['eventId', 'deaths', 'injuries', 'missing', 'fileNames'] missing_fields = [field for field in required_fields if field not in body] print('missing_fields', missing_fields) if missing_fields: raise HTTPException(status_code=401, detail=f"Missing required fields: {', '.join(missing_fields)}") eventId = body['eventId'] # 标记关闭状态 event_base = db.query(EventBase).filter(EventBase.event_code == eventId).first() event_base.event_status = "3" db.commit() event_tracking = EventTracking() event_tracking.event_id = event_base.id event_tracking.event_status = event_base.event_status event_tracking.event_level = event_base.event_level event_tracking.tracking_time = datetime.now() event_tracking.recorded_by = user_id event_tracking.del_flag = "0" db.add(event_tracking) db.commit() return { "code": 200, "msg": '关闭事件成功' } except Exception as e: # 处理异常 traceback.print_exc() raise HTTPException(status_code=500, detail=str(e)) @router.post('/stop') async def stop_event( request: Request, db: Session = Depends(get_db), body = Depends(remove_xss_json)): try: eventId = body['eventId'] db.query(EventBase).filter(EventBase.event_code == eventId).update({"event_status": "2"}) db.commit() return { "code": 200, "msg": '结束指挥成功' } except Exception as e: traceback.print_exc() # 处理异常 raise HTTPException(status_code=500, detail=str(e)) @router.post('/delete') async def delete_event( request: Request, db: Session = Depends(get_db), body = Depends(remove_xss_json)): try: eventId = body['eventId'] db.query(EventBase).filter(EventBase.event_code == eventId).update({"del_flag": "2"}) db.commit() return { "code": 200, "msg": '删除事件成功' } except Exception as e: traceback.print_exc() # 处理异常 raise HTTPException(status_code=500, detail=str(e)) @router.get("/download_file", response_class=FileResponse, summary="下载总结报告") async def download_file( request: Request, file_id: int, event_id: int, db: Session = Depends(get_db) ): row = db.query(EventFile).filter(and_(EventFile.del_flag == '0', EventFile.id == file_id, EventFile.event_id == event_id)).first() if row is not None: return FileResponse(row.file_path)