|
@@ -0,0 +1,397 @@
|
|
|
+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)
|