123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113 |
- 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
- 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()
- 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),
- "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']
- send_queue = []
- 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)
- description = "预案名称: " + plan_name + "\n响应级别:" + response_level + "\n消息内容: "+yzy_content
- '''
- yzy_callback_url = quote("http://19.155.220.206/yjxp/#/yzy-callback")
- state_json = {
- "redirect_url": "http://19.155.220.206/yjxp/#/leader/index" # 业务页面
- }
- state_str = json.dumps(state_json)
- state = base64.b64encode(state_str).decode('utf-8')
- detail_url = "https://open.weixin.qq.com/connect/Oauth2/authorize?appid=wld341060039&redirect_uri={}&response_type=code&scope=snsapi_base&agentid=1004302&state={}#wechat_redirect".format(yzy_callback_url, state)
- '''
-
- # redirect_url = "http://19.155.220.206:8086/yjxp/#/leader/index" # 业务页面
- redirect_url = "{}/".format(settings.YJXP_WEB_ROOT_PATH) # 主页
- # detail_url = YzyApi.format_redirect_url(redirect_url, "eb4kehgy6wj4qn0jhx1dk6")
- detail_url = redirect_url
- send_queue.append({
- "id": event_emergency_notify.id,
- "yzy_user_id": yzy_user_id,
- "description": description,
- "detail_url": detail_url
- })
-
- background_tasks.add_task(async_send_yzy_msg, db, send_queue)
- 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": "保存事件伤亡情况成功"
- }
|