1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135 |
- from fastapi import APIRouter, Request, Depends, HTTPException, Query, BackgroundTasks
- 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, db_msg_center, db_yzy
- from common.security import valid_access_token
- import traceback
- from utils import *
- from datetime import datetime, timedelta
- from common import YzyApi
- from common.db import db_dict
- from urllib.parse import quote
- import base64
- from config import settings
- from extensions import logger
- import os
- 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' or body['casualties'] == '':
- body['deaths'] = None
- body['injuries'] = None
- body['missing'] = None
- body['casualties'] == '0'
- 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,
- create_time = datetime.now()
- )
- 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()
- # 发送粤政易事件
- # send_yzy_msg(db, event_base, user_id)
-
- 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)}")
- # 发送粤政易消息
- def send_yzy_msg(db: Session, event_base: EventBase, user_id: int) -> None:
- to_user_id = event_base.recorded_by
- user_info = db_user.get_user_info(db, to_user_id)
- yzy_account = user_info.yzy_account
- yzy_userid = db_yzy.get_userid_by_account(db, yzy_account)
- create_time = get_datetime_str(event_base.event_time)
- detail_url = "{}{}{}".format(settings.YZY_WEB_ROOT, "/yjxp/#/event/detail?event_id=", event_base.event_code)
- description = "事件名称: " + event_base.event_title + "\n事件等级:" + create_time + "\n事发地点: " + event_base.address
- data = {
- "yzy_userid": yzy_userid,
- "mobile": yzy_account,
- "content": description,
- "recorded_by": user_id,
- "detail_url": detail_url,
- "foreign_key": event_base.id,
- "from_scenario": "event_base",
- "title": "事件接报"
- }
- YzyApi.add_to_msg_queue(db, data)
- # db_msg_center.add_message(db, "事件接报", recv_userid, "事件接报提醒", description, event_base.event_code, 'event_base')
- @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),
- "create_time": get_datetime_str(row.create_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,
- "create_time": get_datetime_str(row.create_time),
-
- # 关联预案
- "plan_id": row.plan_id,
- "plan_name": db_emergency_plan.get_plan_name_by_id(db, row.plan_id),
- "plan_files": db_emergency_plan.get_plan_file_list(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),
- # 预案通知下发
- "emergency_notify_count": db_event_management.get_emergency_notify_count(db, row.event_code)
- }
- }
- 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()
- if event_base is None:
- return {
- "code": 500,
- "msg": '事件不存在'
- }
-
- if event_base.event_status != "3":
- event_base.event_status = "3"
- event_base.del_flag = "0" # 临时事件页改为正式事件
- 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()
- if 'fileName' in body:
- event_files = [
- EventFile(
- event_id=event_base.id,
- file_name=fileName["name"], # 使用 fileName["name"] 作为文件名
- file_path=f'/data/upload/mergefile/uploads/{fileName["url"]}',
- storage_file_name=fileName["url"],
- foreign_key=event_base.event_code,
- from_scenario="event_summary_file",
- update_time=datetime.now(),
- create_time=datetime.now(),
- del_flag='0'
- )
- for fileName in body['fileNames'] # body['fileNames'] 现在是一个包含对象的数组,每个对象都有 'name' 和 'url' 属性
- ]
- db.add_all(event_files)
- 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)
- # 小屏通知栏显示的最新时间
- @router.get("/notice_bar")
- async def notice_bar(
- request: Request,
- db: Session = Depends(get_db)
- ):
- try:
- row = db.query(EventBase).filter(and_(EventBase.del_flag == '0', EventBase.event_title != '', EventBase.event_status.in_([0, 1]))).order_by(EventBase.event_time.desc()).first()
- if row is not None:
- return {
- 'code': 200,
- 'msg': '查询成功',
- 'data': {
- 'event_id': row.event_code,
- 'event_title': row.event_title
- }
- }
- else:
- return {
- 'code': 500,
- 'msg': '查询失败'
- }
- except Exception as e:
- traceback.print_exc()
- # 处理异常
- raise HTTPException(status_code=500, detail=str(e))
-
- # 列出已登记(未开始指挥)的事件列表
- @router.post("/list_registered")
- async def list_registered(
- request: Request,
- db: Session = Depends(get_db)
- ):
- where = and_(EventBase.del_flag == '0', EventBase.event_status == '0')
- rows = db.query(EventBase).filter(where).order_by(EventBase.event_time.asc()).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),
- "create_time": get_datetime_str(row.create_time)
- }
- for row in rows
- ]
- # 返回结果
- return {
- "code": 200,
- "msg": "查询成功",
- "data": data
- }
- # 列出有个不分页的查询 不是临时事件、未结束、未关闭的事件列表接口
- @router.post("/list_active")
- async def list_active(
- request: Request,
- db: Session = Depends(get_db)
- ):
- where = and_(EventBase.del_flag == '0', EventBase.event_title != '', EventBase.event_status.in_(['0', '1']))
- rows = db.query(EventBase).filter(where).order_by(EventBase.event_time.desc()).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),
- "create_time": get_datetime_str(row.create_time)
- }
- for row in rows
- ]
- # 返回结果
- return {
- "code": 200,
- "msg": "查询成功",
- "data": data
- }
- # 将临时事件绑定成正式事件
- @router.post("/update_event_id")
- async def update_event_id(
- request: Request,
- body = Depends(remove_xss_json),
- db: Session = Depends(get_db)
- ):
- temp_event_id = body['temp_event_id'] # 临时事件ID
- event_id = body['event_id'] # 正式(未开始指挥)事件ID
- row = db.query(EventBase).filter(EventBase.event_code == event_id, EventBase.event_status == "0").first()
- if row is not None:
- info = get_model_dict(row)
- row = db.query(EventBase).filter(and_(EventBase.event_code == temp_event_id)).first()
- if row is not None:
- # 目前只是改变名称和事发地址
- row.event_title = info['event_title']
- row.del_flag = '0' # 正式事件
- if row.address == "":
- row.address = info['address']
- row.longitude = info['longitude']
- row.latitude = info['latitude']
- db.commit()
- # 把之前的事件ID改为已删除
- db.query(EventBase).filter(EventBase.event_code == event_id).update({"del_flag": "2"})
- db.commit()
- # 返回当前事件信息
- row = db.query(EventBase).filter(EventBase.event_code == temp_event_id).first()
- 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),
- "create_time": get_datetime_str(row.create_time)
- }
- return {
- "code": 200,
- "msg": "绑定成功",
- "data": data
- }
-
- return {
- "code": 500,
- "msg": "查询错误,事件不存在"
- }
-
- # 登记事发地点
- @router.post("/save_address")
- async def list_registered(
- request: Request,
- body = Depends(remove_xss_json),
- db: Session = Depends(get_db)
- ):
- eventId = body['eventId']
- row = db.query(EventBase).filter(EventBase.event_code == eventId).first()
- if row is None:
- return {
- "code": 500,
- "msg": "事件编号不存在"
- }
- row.address = body['address']
- row.longitude = body['longitude']
- row.latitude = body['latitude']
- db.commit()
- return {
- "code": 200,
- "msg": "登记事发地点成功"
- }
- # 匹配预案
- @router.post("/march_emergency_plan")
- async def martch_emergency_plan(
- request: Request,
- body = Depends(remove_xss_json),
- db: Session = Depends(get_db)
- ):
- eventId = body['eventId']
- row = db.query(EventBase).filter(EventBase.event_code == eventId).first()
- if row is None or row.event_type == '':
- return {
- "code": 500,
- "msg": "事件编号不正确或事件类型为空"
- }
- event_type = row.event_type
- plan_id = row.plan_id
- response_level = row.response_level
- # 如果已事件已匹配预案,直接返回
- if plan_id != '' and response_level != '':
- row = db.query(EmergencyPlan).filter(EmergencyPlan.plan_number == plan_id).filter(EmergencyPlan.del_flag == "0").first()
- if row is not None:
- plan_name = row.plan_name
- return {
- "code": 200,
- "msg": "匹配预案成功",
- "data": {
- "eventId": eventId,
- "plan_id": plan_id,
- "plan_name": plan_name,
- "response_level": response_level
- }
- }
- '''
- 匹配到事件类型
- '''
- row = db.query(EmergencyPlan).filter(EmergencyPlan.event_type == event_type).filter(EmergencyPlan.del_flag == "0").first()
- if row is None:
- event_type_text = db_dict.get_dict_label(db, "mm_event_type", event_type)
- return {
- "code": 500,
- "msg": f"无法匹配事件类型{event_type_text}到相应的预案"
- }
-
- plan_id = row.plan_number
- plan_name = row.plan_name
- response_level = row.response_level
-
- return {
- "code": 200,
- "msg": "匹配预案成功",
- "data": {
- "eventId": eventId,
- "plan_id": plan_id,
- "plan_name": plan_name,
- "response_level": response_level
- }
- }
- # 取消预案
- @router.post("/cancel_emergency_plan")
- async def cancel_emergency_plan(
- request: Request,
- body = Depends(remove_xss_json),
- db: Session = Depends(get_db)
- ):
- eventId = body['eventId']
- event_row = db.query(EventBase).filter(EventBase.event_code == eventId).first()
- if event_row is None:
- return {
- "code": 500,
- "msg": "事件编号不存在"
- }
-
- plan_id = event_row.plan_id
- if plan_id != "":
- # 清空之前的下发内容
- db.query(EventEmergencyNotify).filter(and_(EventEmergencyNotify.plan_id == plan_id, EventEmergencyNotify.event_id == eventId)).delete()
- db.commit()
- event_row.plan_id = ""
- event_row.response_level = ""
- db.commit()
-
- return {
- "code": 200,
- "msg": "取消响应成功"
- }
- #变更响应登记
- @router.post("/update_emergency_plan_response_level")
- async def update_emergency_plan_response_level(
- request: Request,
- body = Depends(remove_xss_json),
- db: Session = Depends(get_db)
- ):
- eventId = body['eventId']
- plan_id = body['plan_id']
- response_level = body['response_level']
- event_row = db.query(EventBase).filter(EventBase.event_code == eventId).first()
- if event_row is None:
- return {
- "code": 500,
- "msg": "事件编号不存在"
- }
-
- plan_row = db.query(EmergencyPlan).filter(EmergencyPlan.plan_number == plan_id).first()
- if plan_row is None:
- return {
- "code": 500,
- "msg": "预案不存在"
- }
-
- # 绑定预案ID和响应等级
- event_row.plan_id = plan_row.plan_number
- event_row.response_level = response_level
- event_row.event_type = plan_row.event_type
- event_row.del_flag = "0" # 临时事件改为正式事件
- db.commit()
- # 清空之前的下发内容
- # db.query(EventEmergencyNotify).filter(and_(EventEmergencyNotify.plan_id == plan_id, EventEmergencyNotify.event_id == eventId)).delete()
- # db.commit()
- return {
- "code": 200,
- "msg": "变更响应登记成功"
- }
-
- # 启动预案
- @router.post("/lauch_emergency_plan")
- async def lauch_emergency_plan(
- request: Request,
- body = Depends(remove_xss_json),
- db: Session = Depends(get_db)
- ):
- eventId = body['eventId']
- plan_id = body['plan_id']
- response_level = body['response_level']
- event_row = db.query(EventBase).filter(EventBase.event_code == eventId).first()
- if event_row is None:
- return {
- "code": 500,
- "msg": "事件编号不存在"
- }
-
- '''
- if event_row.plan_id != '' and event_row.response_level != '':
- return {
- "code": 500,
- "msg": "预案已启动"
- }
- '''
-
- plan_row = db.query(EmergencyPlan).filter(EmergencyPlan.plan_number == plan_id).first()
- if plan_row is None:
- return {
- "code": 500,
- "msg": "预案不存在"
- }
-
- # 绑定预案ID和响应等级
- event_row.plan_id = plan_row.plan_number
- event_row.response_level = response_level
- event_row.event_type = plan_row.event_type
- event_row.del_flag = "0" # 临时事件改为正式事件
- db.commit()
- return {
- "code": 200,
- "msg": "启动预案成功"
- }
- # 预案任务下发
- @router.post("/send_emergency_plan_task_by_yzy")
- async def send_emergency_plan_task_by_yzy(
- request: Request,
- background_tasks: BackgroundTasks,
- body = Depends(remove_xss_json),
- db: Session = Depends(get_db),
- user_id = Depends(valid_access_token)
- ):
- time.sleep(1.0)
-
- eventId = body['eventId']
- tasks = body['tasks']
-
- event_row = db.query(EventBase).filter(EventBase.event_code == eventId).first()
- if event_row is None:
- return {
- "code": 500,
- "msg": "事件编号不存在"
- }
-
- '''
- c1 = db.query(EventEmergencyNotify).filter(EventEmergencyNotify.event_id == eventId).count()
- if c1 > 0:
- return {
- "code": 500,
- "msg": "预案任务已下发"
- }
- '''
-
- event_info = get_model_dict(event_row)
- plan_id = event_info['plan_id']
- response_level = db_dict.get_dict_label(db, "response_level", event_info['response_level'])
- if plan_id is None or plan_id == '':
- return {
- "code": 500,
- "msg": "请先启动预案"
- }
-
- row = db.query(EmergencyPlan).filter(EmergencyPlan.plan_number == plan_id).first()
- if row is None:
- return {
- "code": 500,
- "msg": "没有匹配的预案"
- }
-
- plan_info = get_model_dict(row)
- plan_name = plan_info['plan_name']
- rows = db.query(EmergencyUnit).filter(EmergencyUnit.plan_id == plan_id).order_by(EmergencyUnit.dept_order.asc()).all()
- if len(rows) == 0:
- return {
- "code": 500,
- "msg": "该预案没有相关通知部门"
- }
-
- # 清空之前的下发内容
- db.query(EventEmergencyNotify).filter(and_(EventEmergencyNotify.plan_id == plan_id, EventEmergencyNotify.event_id == eventId)).delete()
- db.commit()
- for row in rows:
- dept_id = row.dept_id
- dept_name = row.dept_name
-
- leader_content = ""
- if str(dept_id) in tasks:
- leader_content = tasks[str(dept_id)]
- # 已下发的过滤掉,避免重发
- '''
- row_exists = db.query(EventEmergencyNotify).filter(and_(EventEmergencyNotify.plan_id == plan_id, EventEmergencyNotify.event_id == eventId, EventEmergencyNotify.dept_id == dept_id)).first()
- if row_exists is not None:
- continue
- '''
- if leader_content != "":
- # 领导批示
- new_instruction = TaskLeaderInstructions(
- event_code = eventId,
- dept_id = dept_id,
- dept_name = dept_name,
- content = leader_content,
- create_time = datetime.now(),
- recorded_by = user_id
- )
- db.add(new_instruction)
- db.commit()
-
- # 通过预案人员管理匹配负责人
- _user_id = 0
- user_name = ''
- contact_row = db.query(EmergencyContactInfo).filter(and_(EmergencyContactInfo.del_flag == "0", EmergencyContactInfo.unit_id == dept_id)).first()
- yzy_account = contact_row.yue_gov_ease_phone
- nick_name = contact_row.contact_name
-
- yzy_user_row = db.query(YzyOrgUserEntity).filter(YzyOrgUserEntity.account == yzy_account).first()
- if yzy_user_row is None:
- logger.info("粤政易人员ID不存在", yzy_account)
- yzy_user_id = ""
- else:
- yzy_user_id = yzy_user_row.userid
- # 通过通讯录匹配相关负责人
- # user_row = db.query(SysUser).filter(SysUser.user_id == 1).first()
- # user_id = user_row.user_id
- # user_name = user_row.user_name
- # nick_name = user_row.nick_name
- # yzy_user_id = "eb4kehgy6wj4qn0jhx1dk6" # 暂时写死梦梅的账号
- yzy_content = "{},您好!《{}》现已全面启动,特此通知您单位迅速响应,全力做好预案工作要点:{}".format(row.dept_name, plan_info['plan_name'], row.content)
- event_emergency_notify = EventEmergencyNotify(
- event_id = eventId,
- plan_id = plan_id,
- dept_id = dept_id,
- dept_name = dept_name,
- user_id = _user_id,
- user_name = user_name,
- nick_name = nick_name,
- yzy_user_id = yzy_user_id,
- yzy_content = yzy_content,
- sent_time = datetime.now(),
- sent_status = 0,
- comment = leader_content # 领导批示
- )
- db.add(event_emergency_notify)
- db.commit()
- db.refresh(event_emergency_notify)
- # 发送粤政易消息
- detail_url = "{}{}{}".format(settings.YZY_WEB_ROOT, "/yjxp/#/event/detail?event_id=", eventId)
- description = "预案名称: " + plan_name + "\n响应级别:" + response_level + "\n消息内容: "+yzy_content
- data = {
- "yzy_userid": yzy_user_id,
- "mobile": yzy_account,
- "content": description,
- "recorded_by": user_id,
- "detail_url": detail_url,
- "foreign_key": event_emergency_notify.id,
- "from_scenario": "event_emergency_notify",
- "title": "预案通知"
- }
- YzyApi.add_to_msg_queue(db, data)
- db_msg_center.add_message(db, "预案通知", _user_id, f"{plan_name}{response_level}通知", yzy_content, event_emergency_notify.id, "event_emergency_notify")
- return {
- "code": 200,
- "msg": "预案任务下发成功"
- }
- '''
- def async_send_yzy_msg(db: Session, queue: dict):
- for item in queue:
- event_emergency_notify = db.query(EventEmergencyNotify).filter(EventEmergencyNotify.id == item['id']).first()
- if event_emergency_notify is not None and event_emergency_notify.sent_status == 0:
- yzy_user_id = item['yzy_user_id']
- if yzy_user_id == "":
- event_emergency_notify.sent_status = 9 # 发送失败
- db.commit()
- else:
- description = item['description']
- detail_url = item['detail_url']
- try:
- resp = YzyApi.send_textcard_message([yzy_user_id], "预案响应消息", description, detail_url)
- if resp['errcode'] == 0:
- event_emergency_notify.sent_status = 1 # 发送成功
- else:
- event_emergency_notify.sent_status = 9 # 发送失败
- db.commit()
- except Exception:
- pass
- '''
- # 获取预案通知
- @router.post("/emergency_plan_task_list")
- async def emergency_plan_task_list(
- request: Request,
- body = Depends(remove_xss_json),
- db: Session = Depends(get_db)
- ):
- eventId = body['eventId']
-
- event_row = db.query(EventBase).filter(EventBase.event_code == eventId).first()
- if event_row is None:
- return {
- "code": 500,
- "msg": "事件编号不存在"
- }
-
- event_info = get_model_dict(event_row)
- plan_id = event_info['plan_id']
- if plan_id is None or plan_id == '':
- return {
- "code": 200,
- "msg": "未关联预案",
- "data": []
- }
-
- where = and_(and_(EventEmergencyNotify.plan_id == plan_id, EventEmergencyNotify.event_id == eventId))
- rows = db.query(EventEmergencyNotify).filter(where).order_by(EventEmergencyNotify.id.asc()).all()
- data = [
- {
- "dept_name": row.dept_name,
- "sent_time": get_datetime_str(row.sent_time),
- "sent_status": row.sent_status,
- "sent_status_text": get_sent_status_text(row.sent_status),
- "yzy_content": row.yzy_content,
- "nick_name": row.nick_name,
- "comment": row.comment,
- "leaders": get_event_leaders(db, eventId, row.dept_id)
- }
- for row in rows
- ]
- # 返回结果
- return {
- "code": 200,
- "msg": "查询成功",
- "data": data
- }
- def get_event_leaders(db: Session, event_id: str, dept_id: int) -> dict:
- rows = db.query(EventLeaderUser).filter(and_(EventLeaderUser.del_flag == '0', EventLeaderUser.event_id == event_id, EventLeaderUser.unit_id == dept_id)).order_by(EventLeaderUser.create_time.asc()).all()
- return [
- {
- "user_type": row.user_type,
- "user_name": row.user_name,
- "mobile": row.mobile
- }
- for row in rows
- ]
- def get_sent_status_text(sent_status) -> str:
- if sent_status == 0:
- return '暂未发送'
- elif sent_status == 1:
- return '发送成功'
- elif sent_status == 0:
- return '发送失败'
- else:
- return str(sent_status)
-
- # 上报伤亡情况
- @router.post("/upload_casualties")
- async def upload_casualties(
- request: Request,
- body = Depends(remove_xss_json),
- db: Session = Depends(get_db)
- ):
- fileNames = []
- eventId = body['event_id']
- if 'fileNames' in body:
- fileNames = body['fileNames']
- del body['fileNames']
-
- del body['event_id']
- # 标记已上传
- body['casualties'] = '1'
- db.query(EventBase).filter(EventBase.event_code == eventId).update(body)
- db.commit()
- if len(fileNames) > 0:
- event_base = db.query(EventBase).filter(EventBase.event_code == eventId).first()
-
- # 删除之前的总结报告,保留当前这一份
- db.query(EventFile).filter(and_(EventFile.from_scenario == 'event_summary_file', EventFile.foreign_key == event_base.event_code)).update({"del_flag": "2"})
- db.commit()
- event_files = [
- EventFile(
- event_id=event_base.id,
- file_name=fileName["name"], # 使用 fileName["name"] 作为文件名
- file_path=f'/data/upload/mergefile/uploads/{fileName["url"]}',
- file_size=os.path.getsize(f'/data/upload/mergefile/uploads/{fileName["url"]}'),
- storage_file_name=fileName["url"],
- foreign_key=event_base.event_code,
- from_scenario="event_summary_file",
- update_time=datetime.now(),
- create_time=datetime.now(),
- del_flag='0'
- )
- for fileName in fileNames # body['fileNames'] 现在是一个包含对象的数组,每个对象都有 'name' 和 'url' 属性
- ]
- db.add_all(event_files)
- db.commit()
- return {
- "code": 200,
- "msg": "保存事件伤亡情况成功"
- }
|