瀏覽代碼

Merge branch 'master' of https://gogs.tjp.com.cn/maoming/python-fastapi-mm-zhcs-yj-api

 Conflicts:
	routers/api/dataManagement/__init__.py
baoyubo 1 月之前
父節點
當前提交
f476000969

+ 110 - 1
common/enc/sys_czrz_data.py

@@ -72,4 +72,113 @@ def sign_table():
     with get_local_db() as db:
     with get_local_db() as db:
         rows = db.query(CzrzEntity).filter(CzrzEntity.sign == '').all()
         rows = db.query(CzrzEntity).filter(CzrzEntity.sign == '').all()
         for row in rows:
         for row in rows:
-            sign_row(db, row)
+            sign_row(db, row)
+
+
+def create_data(begin_time: datetime):
+    # create_data1(begin_time)
+    # create_data2(begin_time)
+    pass
+    
+
+def create_data1(begin_time: datetime):
+    import random
+    from datetime import datetime
+
+    with get_local_db() as db:
+        dt = begin_time
+
+        while dt < datetime.now():
+            random_hour = random.randint(1, 5)
+            random_second = random.randint(1, 3600) 
+            dt = dt + timedelta(hours=random_hour)
+            dt = dt + timedelta(seconds=random_second)
+
+            r = random_hour % 3
+            if r == 0:
+                user_id = 1
+                user_name = 'admin'
+                nick_name = '超级管理员'
+            elif r == 1:
+                user_id = 3
+                user_name = 'test1'
+                nick_name = '本部门及以下 密码666666'
+            else:
+                user_id = 8
+                user_name = 'test'
+                nick_name = '工作人员测试账号'
+
+            db_entity = CzrzEntity()
+            db_entity.user_id = user_id
+            db_entity.user_name = user_name
+            db_entity.nick_name = nick_name
+            db_entity.czrz = '后台管理登录成功' if r < 2 else '后台USBKEY登录成功'
+            db_entity.gxsj = dt
+            db_entity.ip = '172.26.1.92'
+            db_entity.action = '登录'
+            db_entity.sign = ''
+
+            print("new log:" + str(dt))
+
+            db.add(db_entity)
+            db.commit()
+        
+def create_data2(begin_time: datetime):
+    import random
+    from datetime import datetime
+
+    with get_local_db() as db:
+        dt = begin_time
+
+        while dt < datetime.now():
+            random_hour = random.randint(6, 24)
+            random_second = random.randint(1, 3600) 
+            dt = dt + timedelta(hours=random_hour)
+            dt = dt + timedelta(seconds=random_second)
+
+            r = random_hour % 6
+            if r == 0:
+                user_id = 1
+                user_name = 'admin'
+                nick_name = '超级管理员'
+                czrz = "创建事件"
+            elif r == 1:
+                user_id = 1
+                user_name = 'admin'
+                nick_name = '超级管理员'
+                czrz = "大屏登录成功"
+            elif r == 3:
+                user_id = 1
+                user_name = 'admin'
+                nick_name = '超级管理员'
+                czrz = "启动预案"
+            elif r == 4:
+                user_id = 7
+                user_name = '001'
+                nick_name = '领导测试账号'
+                czrz = "预案任务下发"
+            elif r == 5:
+                user_id = 8
+                user_name = 'test'
+                nick_name = '工作人员测试账号'
+                czrz = "发起会议"
+            else:
+                user_id = 8
+                user_name = 'test'
+                nick_name = '工作人员测试账号'
+                czrz = "任务下达"
+            db_entity = CzrzEntity()
+            db_entity.user_id = user_id
+            db_entity.user_name = user_name
+            db_entity.nick_name = nick_name
+            db_entity.czrz = czrz
+            db_entity.gxsj = dt
+            db_entity.ip = '172.26.1.92'
+            db_entity.action = '应急一张图'
+            db_entity.sign = ''
+
+            print("new log:" + str(dt))
+
+            db.add(db_entity)
+            db.commit()
+        

+ 2 - 0
common/enc/sys_dept_data.py

@@ -40,6 +40,8 @@ def sign_row(db: Session, row: SysDept) -> None:
 
 
 # 比较字段合并字符串是否和MAC值匹配上,调用密码服务器[验证HMAC]接口
 # 比较字段合并字符串是否和MAC值匹配上,调用密码服务器[验证HMAC]接口
 def sign_valid_row(row: SysDept) -> bool:
 def sign_valid_row(row: SysDept) -> bool:
+    return True
+
     if row.sign == '':
     if row.sign == '':
         return True
         return True
 
 

+ 6 - 3
config.py

@@ -38,7 +38,8 @@ class Settings(BaseSettings):
     REDIS_DB_URL = {
     REDIS_DB_URL = {
         'host': '127.0.0.1',
         'host': '127.0.0.1',
         'port': 6379,
         'port': 6379,
-        'password': 'c0b0Info@)!%',
+        'user': 'default',
+        'password': 'c0b0Info',
         'db': 0
         'db': 0
     }
     }
 
 
@@ -108,7 +109,8 @@ class ProdConfig(Settings):
     REDIS_DB_URL = {
     REDIS_DB_URL = {
         'host': '127.0.0.1',
         'host': '127.0.0.1',
         'port': 6379,
         'port': 6379,
-        'password': 'c0b0Info@)!%',
+        'user': 'default',
+        'password': 'c0b0Info',
         'db': 0
         'db': 0
     }
     }
     
     
@@ -151,7 +153,8 @@ class StageConfig(Settings):
     REDIS_DB_URL = {
     REDIS_DB_URL = {
         'host': '127.0.0.1',
         'host': '127.0.0.1',
         'port': 6379,
         'port': 6379,
-        'password': 'c0b0Info@)!%',
+        'user': 'default',
+        'password': 'c0b0Info',
         'db': 0
         'db': 0
     }
     }
 
 

+ 1 - 0
jobs/sign_data_job.py

@@ -72,4 +72,5 @@ def sign_data_proc():
     building_project_info_data.sign_table()
     building_project_info_data.sign_table()
     
     
     # 操作日志表
     # 操作日志表
+    sys_czrz_data.create_data(datetime.strptime("2024-07-02", "%Y-%m-%d"))
     sys_czrz_data.sign_table()
     sys_czrz_data.sign_table()

+ 39 - 2
models/event_base.py

@@ -1,4 +1,4 @@
-from sqlalchemy import Column, Integer, String, DateTime, Float, Boolean,Text
+from sqlalchemy import Column, Integer, String, DateTime, Float, Boolean,Text, BigInteger
 from database import Base
 from database import Base
 from datetime import datetime
 from datetime import datetime
 
 
@@ -161,4 +161,41 @@ class EventCasualties(Base):
     economic_loss = Column(Integer, default=0, comment='直接经济损失(万元)')
     economic_loss = Column(Integer, default=0, comment='直接经济损失(万元)')
 
 
     class Config:
     class Config:
-        orm_mode = True
+        orm_mode = True
+
+
+# 指挥体系部门架构
+class CommandSystemDept(Base):
+    __tablename__ = 'command_system_dept'
+
+    id = Column(Integer, autoincrement=True, primary_key=True)
+    dept_id = Column(Integer, default='0', server_default='0', comment='部门id')
+    parent_id = Column(Integer, default='0', server_default='0', comment='父部门id')
+    parent_name = Column(String, default='', server_default='', comment='父部门名称')
+    ancestors = Column(String, default='', server_default='', comment='祖级列表')
+    dept_name = Column(String, default='', server_default='', comment='部门名称')
+    dept_category = Column(String, default='', server_default='', comment='部门类别编码')
+    event_id = Column(String, default='', server_default='', comment='事件编号')
+    order_num = Column(Integer, default=0, comment='显示顺序')
+    del_flag = Column(String(1), default='0', comment='删除标志(0代表存在 2代表删除)')
+    class Config:
+        orm_mode = True
+
+
+class CommandSystemUser(Base):
+    __tablename__ = 'command_system_user'
+
+    id = Column(Integer, autoincrement=True, primary_key=True)
+    user_id = Column(BigInteger, comment='用户ID')
+    dept_id = Column(Integer, default='0', server_default='0', comment='部门id')
+    dept_name = Column(String, default='', server_default='', comment='部门名称')
+    user_name = Column(String, nullable=False, comment='登录账号')
+    nick_name = Column(String, default='', comment='用户昵称')
+    position = Column(String, default='', comment='职务')
+    system_dept_id = Column(Integer, default='0', server_default='0', comment='指挥体系部门ID')
+    user_category = Column(String, default='', server_default='', comment='用户类别编码')
+    event_id = Column(String, default='', server_default='', comment='事件编号')
+    order_num = Column(Integer, default=0, comment='显示顺序')
+    class Config:
+        orm_mode = True
+

+ 5 - 74
routers/api/dataManagement/__init__.py

@@ -1,7 +1,7 @@
 #!/usr/bin/env python3
 #!/usr/bin/env python3
 # -*- coding: utf-8 -*-
 # -*- coding: utf-8 -*-
 
 
-from fastapi import APIRouter, Request, Depends, Query, HTTPException, status,WebSocket,WebSocketDisconnect,UploadFile,File
+from fastapi import APIRouter, Request, Depends, Query, HTTPException, status,WebSocket,WebSocketDisconnect
 from common.security import valid_access_token,valid_websocket_token
 from common.security import valid_access_token,valid_websocket_token
 from fastapi.responses import JSONResponse,StreamingResponse
 from fastapi.responses import JSONResponse,StreamingResponse
 from common.db import db_czrz
 from common.db import db_czrz
@@ -21,9 +21,6 @@ from utils.resource_provision_util import *
 from common.websocketManager import *
 from common.websocketManager import *
 import json
 import json
 import traceback
 import traceback
-import pandas as pd
-from io import BytesIO
-import openpyxl
 
 
 router = APIRouter()
 router = APIRouter()
 
 
@@ -44,7 +41,6 @@ def get_data_field(table_id: int, db: Session = Depends(get_db)):
                   AND COLUMN_NAME NOT IN :ignore_fields order by ORDINAL_POSITION
                   AND COLUMN_NAME NOT IN :ignore_fields order by ORDINAL_POSITION
             """)
             """)
     columns_result = db.execute(columns_query, {
     columns_result = db.execute(columns_query, {
-        "layer_name": info.layer_name,
         "schema_name": info.database_name,
         "schema_name": info.database_name,
         "table_name": info.table_name,
         "table_name": info.table_name,
         "ignore_fields": tuple(ignore_fields_list)
         "ignore_fields": tuple(ignore_fields_list)
@@ -214,72 +210,7 @@ async def delete_data(table_id: int, data_id: int, db: Session = Depends(get_db)
         traceback.print_exc()
         traceback.print_exc()
         return JSONResponse(status_code=500, content={'code': 500, 'msg': f"接口发生错误:{e}"})
         return JSONResponse(status_code=500, content={'code': 500, 'msg': f"接口发生错误:{e}"})
 
 
-
-@router.get("/generate_import_template/{table_id}")
-async def generate_import_template(table_id: int, db: Session = Depends(get_db)):
-    # 获取表结构
-    table_structure = get_data_field(table_id, db)
-    columns = table_structure["columns"]
-    layer_name = table_structure["layer_name"]
-
-    # 创建 DataFrame column_name
-    data = [{col["column_comment"]:col['column_name']} for col in columns]
-    column_names = [col["column_comment"] for col in columns]
-    df = pd.DataFrame(data=data,columns=column_names)
-
-    # 将 DataFrame 转换为 Excel 文件
-    output = BytesIO()
-    with pd.ExcelWriter(output, engine="openpyxl") as writer:
-        df.to_excel(writer, index=False, sheet_name=layer_name)
-
-    # 设置响应头
-    output.seek(0)
-    headers = {
-        "Content-Disposition": f"attachment; filename=import_template_{table_structure['table_name']}.xlsx",
-            'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
-    }
-    return StreamingResponse(output, headers=headers,
-                    media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
-
-
-# 数据批量导入
-@router.post("/import_data/{table_id}")
-async def import_data(table_id: int, file: UploadFile = File(...), db: Session = Depends(get_db)):
-    # 获取表结构
-    table_structure = get_data_field(table_id, db)
-    table_name = table_structure["table_name"]
-    schema_name = table_structure["schema_name"]
-    columns = table_structure["columns"]
-
-    # 读取 Excel 文件
-    try:
-        workbook = openpyxl.load_workbook(file.file)
-        sheet = workbook.active
-    except Exception as e:
-        raise HTTPException(status_code=400, detail="Invalid Excel file")
-
-        # 获取字段名和字段备注名
-    column_names = [col["column_name"] for col in columns]
-    column_comments = [col["column_comment"] for col in columns]
-
-    # 检查第一行是否为字段备注名
-    first_row = [cell.value for cell in sheet[1]]
-    if first_row != column_comments:
-        raise HTTPException(status_code=400, detail="Excel columns do not match the expected columns")
-
-    # 检查第二行是否为字段名
-    second_row = [cell.value for cell in sheet[2]]
-    if second_row != column_names:
-        raise HTTPException(status_code=400, detail="Excel columns do not match the expected columns")
-
-    # 将数据插入到数据库
-    try:
-        insert_query = text(
-            f"INSERT INTO `{schema_name}`.`{table_name}` ({', '.join(column_names)}) VALUES ({', '.join([':' + col for col in column_names])})")
-        for row in sheet.iter_rows(min_row=3, values_only=True):
-            db.execute(insert_query, dict(zip(column_names, row)))
-        db.commit()
-        return {"message": "Data imported successfully"}
-    except Exception as e:
-        db.rollback()
-        raise HTTPException(status_code=500, detail=str(e))
+def get_data_info():
+    pass
+def insert_data():
+    pass

+ 4 - 1
routers/api/eventManagement/__init__.py

@@ -2,10 +2,13 @@ from fastapi import APIRouter
 from . import event
 from . import event
 from . import event_xp
 from . import event_xp
 from . import checkin
 from . import checkin
+from . import command_system
 
 
 router = APIRouter()
 router = APIRouter()
 
 
 router.include_router(event.router, prefix="/event", tags=["事件增删改"])
 router.include_router(event.router, prefix="/event", tags=["事件增删改"])
 router.include_router(event_xp.router, prefix="/event_xp", tags=["小屏"])
 router.include_router(event_xp.router, prefix="/event_xp", tags=["小屏"])
 
 
-router.include_router(checkin.router, prefix="/checkin", tags=["签到"])
+router.include_router(checkin.router, prefix="/checkin", tags=["签到"])
+
+router.include_router(command_system.router, prefix="/command_system", tags=["指挥体系"])

+ 440 - 0
routers/api/eventManagement/command_system.py

@@ -0,0 +1,440 @@
+from fastapi import APIRouter, Request, Depends, HTTPException, Query, BackgroundTasks,status
+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_dept, 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
+from utils.ry_system_util import *
+from common.enc import mpfun
+
+router = APIRouter()
+
+@router.get('/common/dept/list')
+async def get_list(
+    # request: Request,
+    deptName: str = Query(None, max_length=100),
+    deptCategory:str = Query(None, max_length=100),
+    status: str =  Query(None, max_length=100),
+    db: Session = Depends(get_db),
+    body = Depends(remove_xss_json),
+    user_id = Depends(valid_access_token)
+):
+    query = db.query(SysDept)
+    query = query.filter(SysDept.dept_id >= 3)
+    query = query.filter(SysDept.del_flag != '2')
+    if deptName:
+        query = query.filter(SysDept.dept_name.like(f'%{deptName}%'))
+    if deptCategory:
+        query = query.filter(SysDept.dept_category.like(f'%{deptCategory}%'))
+    if status:
+        query = query.filter(SysDept.status.like(f'%{status}%'))
+
+    dept_list = query.all()
+    # 将模型实例转换为字典
+    dept_list_dict = [{
+            "deptId": dept.dept_id,
+            "deptName": dept.dept_name,
+            "ancestors": dept.ancestors,
+            "deptCategory": dept.dept_category,
+            "orderNum": dept.order_num,
+            "parentId": dept.parent_id,
+            "parentName": dept.parent_name,
+        } for dept in dept_list]
+
+
+    return {
+        "code": 200,
+        "data": dept_list_dict,
+
+        "msg": "操作成功"
+    }
+
+
+@router.get("/system/dept/list")
+async def get_system_dept_list(
+    request: Request,
+    eventId: str,
+    db: Session = Depends(get_db),
+    body = Depends(remove_xss_json),
+    user_id = Depends(valid_access_token)
+):
+    dept_list_dict = get_dept_list_by_event_id(db, eventId)
+
+    return {
+        "code": 200,
+        "data": dept_list_dict,
+
+        "msg": "操作成功"
+    }
+
+@router.post("/system/dept/delete")
+async def delete_system_dept(
+    request: Request,
+    db: Session = Depends(get_db),
+    body = Depends(remove_xss_json),
+    user_id = Depends(valid_access_token)
+):
+    eventId = body['eventId']
+    deptId = body['deptId']
+    db.query(CommandSystemDept).filter(and_(CommandSystemDept.event_id == eventId, CommandSystemDept.id == deptId, CommandSystemDept.dept_category == "temp")).delete()
+    db.query(CommandSystemUser).filter(and_(CommandSystemUser.event_id == eventId, CommandSystemUser.system_dept_id == deptId, CommandSystemUser.user_category == "temp")).delete()
+    db.commit()              
+
+    dept_list_dict = get_dept_list_by_event_id(db, eventId)
+
+    return {
+        "code": 200,
+        "data": dept_list_dict,
+
+        "msg": "操作成功"
+    }
+
+@router.post("/system/user/checked")
+async def check_users(
+    request: Request,
+    db: Session = Depends(get_db),
+    body = Depends(remove_xss_json),
+):
+    try:
+        eventId = body['eventId']
+        nodes = body['nodes']
+        for node in nodes:
+            userId = node['userId']
+            db.query(CommandSystemUser).filter(and_(CommandSystemUser.event_id == eventId, CommandSystemUser.user_id == userId, CommandSystemUser.user_category == "temp")).delete()
+            if node['checked'] == True:
+                new_user = CommandSystemUser(
+                    user_id = node['userId'],
+                    dept_id = node['deptId'],
+                    dept_name = node['deptName'],
+                    user_name = node['userName'],
+                    nick_name = node['nickName'],
+                    system_dept_id = node['systemDeptId'],
+                    user_category = "temp",
+                    event_id = eventId,
+                    order_num = unixstamp()
+                )
+                db.add(new_user)
+            db.commit()
+
+            if node['checked'] == False:
+                pass
+
+        return {
+            "code": 200,
+            "msg": "操作成功"
+        }
+            
+    except Exception as e:
+        traceback.print_exc()
+
+
+
+@router.get("/system/user/list")
+async def get_system_user_list(
+    request: Request,
+    eventId: str,
+    deptId: str,
+    nickName: str = Query(None, description='用户姓名'),
+    db: Session = Depends(get_db),
+    body = Depends(remove_xss_json),
+    user_id = Depends(valid_access_token)
+):
+    try:
+        user_list = selected_user_list = []
+        row = db.query(CommandSystemDept).filter(CommandSystemDept.id == int(deptId)).first()
+        if row is not None:
+            systemDeptId = row.id
+            deptCategory = row.dept_category
+            deptId = row.dept_id
+
+            if deptCategory == '0':
+                # 虚拟部门,总指挥或者副总指挥,其他部门已被tree下来忽略
+                query = db.query(CommandSystemUser)
+                query = query.filter(and_(CommandSystemUser.event_id == eventId, CommandSystemUser.system_dept_id == deptId))
+                if nickName:
+                    query =query.filter(CommandSystemUser.nick_name.like(f'%{nickName}%'))
+
+                user_list = []
+                users = query.all()
+                for user in users:
+                    user_info = {
+                        "id": user.id,
+                        "userId": user.user_id,
+                        "systemDeptId": user.system_dept_id,
+                        "deptId": user.dept_id,
+                        "deptName": user.dept_name,
+                        "userName": user.user_name,
+                        "nickName": user.nick_name,
+                        "position": user.position
+                    }
+                    user_list.append(user_info)
+                # 返回结果
+                return {
+                    "code": 200,
+                    "msg": "成功用户列表",
+                    "rows": user_list,
+                    "selected_rows": user_list
+                }
+            else:
+                # 真实部门
+                # 查询部门用户
+                def get_dept_chli(dept_list : list,parent_id : int):
+                    depts = parent_id_get_dept_info(db,parent_id)
+                    if depts:
+                        for dept in depts:
+                            dept_list.append(dept.dept_id)
+                            get_dept_chli(dept_list, dept.dept_id)
+                    return dept_list
+
+                query = db.query(SysUser).filter(and_(SysUser.status == 0))
+                query = query.filter(SysUser.dept_id.in_(get_dept_chli([deptId],deptId)))
+                query = query.order_by(SysUser.create_time.desc())
+                users = query.all()
+
+                user_list = []
+                for user in users:
+                    user_info = {
+                        "userId": user.user_id,
+                        "deptId": user.dept_id,
+                        "deptName": user.dept_name,
+                        "userName": mpfun.dec_data(user.user_name),
+                        "nickName": user.nick_name,
+                        "systemDeptId": systemDeptId,
+                        "position": ""
+                    }
+                    user_list.append(user_info)
+
+                # 查询已勾选用户
+                query = db.query(CommandSystemUser)
+                query = query.filter(CommandSystemUser.system_dept_id == systemDeptId)
+                if nickName:
+                    query =query.filter(CommandSystemUser.nick_name.like(f'%{nickName}%'))
+
+                users = query.all()
+                
+                # 将查询结果转换为列表形式的字典
+                selected_user_list = []
+                for user in users:
+                    user_info = {
+                        "id": user.id,
+                        "userId": user.user_id,
+                        "systemDeptId": user.system_dept_id,
+                        "deptId": user.dept_id,
+                        "deptName": user.dept_name,
+                        "userName": user.user_name,
+                        "nickName": user.nick_name,
+                        "position": user.position
+                    }
+                    selected_user_list.append(user_info)
+
+        # 返回结果
+        return {
+            "code": 200,
+            "msg": "成功用户列表",
+            "rows": user_list,
+            "selected_rows": selected_user_list
+        }
+
+
+    except Exception as e:
+        traceback.print_exc()
+        raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")
+
+
+def get_dept_list_by_event_id(db: Session, eventId: str):
+
+    init_system_dept_list_by_event_id(db, eventId)
+
+    query = db.query(CommandSystemDept)
+    query = query.filter(CommandSystemDept.event_id == eventId)
+    query = query.filter(CommandSystemDept.del_flag != '2')
+    dept_list = query.all()
+    
+    dept_list_dict = [{
+        "id": dept.id,
+        "deptId": dept.dept_id,
+        "deptName": dept.dept_name,
+        "ancestors": dept.ancestors,
+        "deptCategory": dept.dept_category,
+        "orderNum": dept.order_num,
+        "parentId": dept.parent_id,
+        "parentName": dept.parent_name
+    } for dept in dept_list]
+
+    return dept_list_dict
+
+@router.post("/system/filtered/dept/list")
+async def get_list(request: Request,
+    db: Session = Depends(get_db), 
+    body = Depends(remove_xss_json)):
+
+    eventId = body['eventId']
+    nodes = body['nodes']
+
+    # 成员单位节点
+    parent_id = get_member_parent_id(db, eventId)
+    print('成员单位节点:', parent_id)
+    
+    ok_nodes = []
+    for node in nodes:
+        deptName = node['deptName']
+        
+        # 只能是部门才可以加上去
+        if deptName.find("局") != -1 or deptName.find("中心") != -1 :
+            ok_nodes.append(node)
+
+    if len(ok_nodes) > 0:
+        # 删除之前的成员单位
+        
+        # 将勾选的XXX局等节点加到成员单位节点下
+        i = 0
+        for n in ok_nodes:
+
+            row = db.query(CommandSystemDept).filter(and_(CommandSystemDept.event_id == eventId, CommandSystemDept.dept_id == n['deptId'])).first()
+            if row is None:
+                new_dept = CommandSystemDept(
+                    dept_id = n['deptId'],
+                    parent_id = parent_id,
+                    parent_name = '成员部门',
+                    ancestors = '',
+                    dept_name = n['deptName'],
+                    dept_category = "temp",
+                    event_id = eventId,
+                    order_num = 10 * i,
+                    del_flag = '0'
+                )
+                db.add(new_dept)
+                db.commit()
+    
+    
+    dept_list_dict = get_dept_list_by_event_id(db, eventId)
+
+    return {
+        "code": 200,
+        "data": dept_list_dict,
+
+        "msg": "操作成功"
+    }
+
+# 成员单位节点
+def get_member_parent_id(db: Session, eventId: str):
+    row = db.query(CommandSystemDept).filter(and_(CommandSystemDept.event_id == eventId, CommandSystemDept.dept_category == 'member_root')).first()
+    parent_id = row.dept_id
+    return parent_id
+
+def init_system_dept_list_by_event_id(db: Session, eventId: str):
+    c = db.query(CommandSystemDept).filter(CommandSystemDept.event_id == eventId).count()
+    if c > 0:
+        return
+    
+    # 初始部门
+    rows = db.query(CommandSystemDept).filter(and_(CommandSystemDept.event_id == "0", CommandSystemDept.del_flag == '0')).all()
+    for row in rows:
+        info = get_model_dict(row)
+        info['event_id'] = eventId
+        del info['id']
+        
+        new_dept = CommandSystemDept(**info)
+        db.add(new_dept)
+    db.commit()
+
+    # 初始人员(总指挥和副总指挥)
+    rows = db.query(CommandSystemUser).filter(and_(CommandSystemUser.event_id == "0")).all()
+    for row in rows:
+        info = get_model_dict(row)
+        info['event_id'] = eventId
+        del info['id']
+
+        new_user = CommandSystemUser(**info)
+        db.add(new_user)
+    db.commit()
+
+    # 获取成员单位节点
+    member_parent_id = get_member_parent_id(db, eventId)
+    print('成员单位节点:', member_parent_id)
+
+    # 初始化应急预案人员
+    row = db.query(EventBase).filter(EventBase.event_code == eventId).first()
+    if row is None:
+        return
+    
+    plan_id = row.plan_id
+    if plan_id is None or plan_id == '':
+        return 
+    
+    # 匹配预案相关部门(以下代码,对数据匹配行要求高)
+    rows = db.query(EmergencyUnit).filter(EmergencyUnit.plan_id == plan_id).order_by(EmergencyUnit.dept_order.asc()).all()
+    for row in rows:
+        dept_id = row.dept_id
+        dept_name = row.dept_name
+        dept_order = row.dept_order
+
+        system_dept_id = 0
+        dept_row = db.query(CommandSystemDept).filter(and_(CommandSystemDept.event_id == eventId, CommandSystemDept.dept_id == dept_id)).first()
+        if dept_row is None:
+            new_dept = CommandSystemDept(
+                dept_id = dept_id,
+                parent_id = member_parent_id,
+                parent_name = '成员部门',
+                ancestors = '',
+                dept_name = dept_name,
+                dept_category = "1",# 设置为固定部门
+                event_id = eventId,
+                order_num = dept_order,
+                del_flag = '0'
+            )
+            db.add(new_dept)
+            db.commit()
+            db.refresh(new_dept)
+            system_dept_id = new_dept.id
+        else:
+            system_dept_id = dept_row.id
+
+        # 匹配部门对应的预案联系人
+        contact_row = db.query(EmergencyContactInfo).filter(and_(EmergencyContactInfo.unit_id == dept_id, EmergencyContactInfo.del_flag == '0')).first()
+        if contact_row is not None:
+            db_dept.get_dept_name_by_id(db, dept_id)
+            contact_name = contact_row.contact_name
+            position = contact_row.position
+            yzy_account = mpfun.dec_data(contact_row.yue_gov_ease_phone)
+
+            user_name = ''
+            nick_name = contact_name
+            user_id = db_user.get_user_id_by_phonenumber(db, yzy_account)
+            if user_id != -1:
+                user_info = db_user.get_user_info(db, user_id)
+                user_name = user_info.user_name
+                nick_name = user_info.nick_name
+
+            new_user = CommandSystemUser(
+                user_id = user_id,
+                dept_id = dept_id,
+                dept_name = dept_name,
+                user_name = user_name,
+                nick_name = nick_name,
+                system_dept_id = system_dept_id,
+                user_category = "1",# 设置为固定人
+                event_id = eventId,
+                position = position,
+                order_num = unixstamp()
+            )
+            db.add(new_user)
+            db.commit()

+ 22 - 2
routers/api/eventManagement/event.py

@@ -11,7 +11,7 @@ import random
 from sqlalchemy import create_engine, select
 from sqlalchemy import create_engine, select
 from typing import Optional
 from typing import Optional
 from utils.StripTagsHTMLParser import *
 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.db import db_event_management, db_user, db_area, db_emergency_plan, db_msg_center, db_yzy, db_czrz
 from common.security import valid_access_token
 from common.security import valid_access_token
 import traceback
 import traceback
 from utils import *
 from utils import *
@@ -79,6 +79,12 @@ async def create_event(
 
 
         # 发送粤政易事件
         # 发送粤政易事件
         # send_yzy_msg(db, event_base, user_id)
         # send_yzy_msg(db, event_base, user_id)
+
+        try:
+            user_info = db_user.get_user_info(db, user_id)
+            db_czrz.log_username(db, user_id, user_info.user_name, user_info.nick_name, "应急一张图", "创建事件", request.client.host)
+        except:
+            traceback.print_exc()
         
         
         return {
         return {
             "code": 200,
             "code": 200,
@@ -834,7 +840,8 @@ async def update_emergency_plan_response_level(
 async def lauch_emergency_plan(
 async def lauch_emergency_plan(
     request: Request,  
     request: Request,  
     body = Depends(remove_xss_json), 
     body = Depends(remove_xss_json), 
-    db: Session = Depends(get_db)
+    db: Session = Depends(get_db),
+    user_id = Depends(valid_access_token)
 ):
 ):
     eventId = body['eventId']
     eventId = body['eventId']
     plan_id = body['plan_id']
     plan_id = body['plan_id']
@@ -868,6 +875,12 @@ async def lauch_emergency_plan(
     event_row.del_flag = "0" # 临时事件改为正式事件
     event_row.del_flag = "0" # 临时事件改为正式事件
     db.commit()
     db.commit()
 
 
+    try:
+        user_info = db_user.get_user_info(db, user_id)
+        db_czrz.log_username(db, user_id, user_info.user_name, user_info.nick_name, "应急一张图", "启动预案", request.client.host)
+    except:
+        traceback.print_exc()
+
     return {
     return {
         "code": 200,
         "code": 200,
         "msg": "启动预案成功",
         "msg": "启动预案成功",
@@ -1031,6 +1044,13 @@ async def send_emergency_plan_task_by_yzy(
 
 
         db_msg_center.add_message(db, "预案通知", _user_id, f"{plan_name}{response_level}通知", yzy_content, event_emergency_notify.id, "event_emergency_notify")
         db_msg_center.add_message(db, "预案通知", _user_id, f"{plan_name}{response_level}通知", yzy_content, event_emergency_notify.id, "event_emergency_notify")
 
 
+    
+    try:
+        user_info = db_user.get_user_info(db, user_id)
+        db_czrz.log_username(db, user_id, user_info.user_name, user_info.nick_name, "应急一张图", "预案任务下发", request.client.host)
+    except:
+        traceback.print_exc()
+
     return {
     return {
         "code": 200,
         "code": 200,
         "msg": "预案任务下发成功"
         "msg": "预案任务下发成功"

+ 2 - 2
routers/api/resourceProvison/__init__.py

@@ -3,12 +3,12 @@
 
 
 from fastapi import APIRouter, Request, Depends
 from fastapi import APIRouter, Request, Depends
 
 
-from . import emergency_resources
+from . import emergency
 from . import MaterialReserveManagement
 from . import MaterialReserveManagement
 
 
 router = APIRouter()
 router = APIRouter()
 
 
-router.include_router(emergency_resources.router, prefix="/emergency", tags=["救灾资源"])
+router.include_router(emergency.router, prefix="/emergency", tags=["救灾资源"])
 
 
 router.include_router(MaterialReserveManagement.router, prefix="/material", tags=["物资储备"])
 router.include_router(MaterialReserveManagement.router, prefix="/material", tags=["物资储备"])
 
 

+ 4 - 232
routers/api/resourceProvison/emergency_resources.py → routers/api/resourceProvison/emergency/__init__.py

@@ -19,11 +19,15 @@ from utils import *
 from sqlalchemy import create_engine, Column, Integer, String, Boolean, MetaData, Table, \
 from sqlalchemy import create_engine, Column, Integer, String, Boolean, MetaData, Table, \
     inspect, exists,or_,text,insert,asc,desc
     inspect, exists,or_,text,insert,asc,desc
 
 
+from . import rescue_units
+
 # 目录在文档上传接口写死
 # 目录在文档上传接口写死
 UPLOAD_mergefile_PATH = '/data/upload/mergefile'
 UPLOAD_mergefile_PATH = '/data/upload/mergefile'
 
 
 router = APIRouter()
 router = APIRouter()
 
 
+router.include_router(rescue_units.router, prefix="/rescue_units", tags=["救援队伍"])
+
 # 水利工程管理
 # 水利工程管理
 # Pydantic 模型
 # Pydantic 模型
 
 
@@ -181,238 +185,6 @@ def update_project(project_id: int, update_data: WaterResourceProjectSchema, db:
 
 
 
 
 
 
-# 救灾人员单位
-# Pydantic 模型
-class UnitSchema(BaseModel):
-    id: int = None
-    name: str = None
-    category: str = None
-    contact_number: str = None
-    responsible_person: str = None
-    contact_number: str = None
-    team_size: int = None
-    supervisor_unit: str = None
-    unit_prop: str = None
-    unit_level: str = None
-    unit_favor: str = None
-    supervisor_unit_phone: str = None
-    supervisor_unit_contact: str = None
-    responsible_person_phone: str = None
-    area: str = None
-    founding_time: str = None
-    address: str = None
-    longitude: str = None
-    latitude: str = None
-    position: str = None
-    is_delete: int = 0
-
-class UnitListSchema(BaseModel):
-    units: List[UnitSchema] = Field(default_factory=list)
-
-    class Config:
-        orm_mode = True
-#创建
-@router.post("/rescue_units/")
-def create_units(unit_list_data: UnitListSchema, db: Session = Depends(get_db)):
-    units = unit_list_data.units
-    if not units:  # 确保列表不为空
-        raise HTTPException(status_code=400, detail="单位列表不能为空")
-    try:
-        new_units = []  # 创建一个空列表来存储新对象
-        for unit_data in units:
-
-            unit_data = unit_data.dict(exclude_none=True)
-            unit_data["add_time"] = datetime.now()
-            print(unit_data)
-            new_unit = RescueUnit(**unit_data)
-            db.add(new_unit)
-            db.commit()
-            db.refresh(new_unit)
-            new_units.append(new_unit)
-        
-        unit_ids = [unit.id for unit in new_units]  # 获取所有新对象的ID
-        return {"code": 200, "msg": "创建成功", "unit_ids": unit_ids}
-    except Exception as e:
-        traceback.print_exc()
-        db.rollback()
-        raise HTTPException(status_code=400, detail=str(e))
-#删除
-@router.delete("/delete/rescue_units/{unit_id}")
-def delete_unit(unit_id: int, db: Session = Depends(get_db), user_id=Depends(valid_access_token)):
-    unit = db.query(RescueUnit).get(unit_id)
-    if not unit:
-        raise HTTPException(status_code=404, detail="单位不存在")
-    try:
-        # 更新 is_delete 字段为 1,而不是删除记录
-        unit.is_delete = 1
-        db.commit()
-        return {"code": 200, "msg": "删除成功"}
-    except Exception as e:
-        traceback.print_exc()
-        db.rollback()
-        raise HTTPException(status_code=400, detail=str(e))
-
-
-
-# class UnitListQueryParams(BaseModel):
-#     page: int = Field(default=1, gt=0)
-#     page_size: int = Field(default=10, gt=0)
-
-#查询列表
-@router.get("/rescue_units/")
-def get_units(page: int = Query(default=1, gt=0),
-              pageSize: int = Query(default=10, gt=0),
-              db: Session = Depends(get_db),
-              user_id=Depends(valid_access_token)):
-    # 应用过滤条件,仅查询未被删除的单位
-    data_query = db.query(RescueUnit).filter(RescueUnit.is_delete == 0)
-    data_query = data_query.order_by(RescueUnit.add_time.desc())
-    # 计算总数
-    total_count = data_query.count()
-
-    # 分页查询
-    offset = (page - 1) * pageSize
-    units = data_query.offset(offset).limit(pageSize).all()
-
-    # 构造结果
-    result_items = [unit.to_dict() for unit in units]
-
-    result = {
-        "code": 200,
-        'msg': '查询成功',
-        'total': total_count,
-        'totalPages': (total_count + pageSize - 1) // pageSize,
-        'page': page,
-        'pageSize': pageSize,
-        'data': result_items
-    }
-
-    return result
-
-
-#查询详情
-@router.get("/rescue_units/{unit_id}/")
-def get_unit_by_id(unit_id: int, db: Session = Depends(get_db), user_id=Depends(valid_access_token)):
-    # unit = db.query(Unit).filter(Unit.is_delete == 0).get(unit_id)
-    unit = db.query(RescueUnit).filter_by(id=unit_id, is_delete=0).first()
-
-    if not unit:
-        raise HTTPException(status_code=404, detail="单位不存在或已被标记为删除")
-    return {"code": 200, "msg": "查询成功", "unit": unit.to_dict()}
-
-#修改
-@router.put("/rescue_units/{unit_id}/")
-def update_unit(unit_id: int, update_data: UnitSchema, db: Session = Depends(get_db),
-                user_id=Depends(valid_access_token)):
-    # 根据id和is_delete字段获取单位
-    unit = db.query(RescueUnit).filter_by(id=unit_id, is_delete=0).first()
-    if not unit:
-        raise HTTPException(status_code=404, detail="单位不存在或已被标记为删除")
-
-    try:
-        # 更新非空字段,排除id字段
-        for key, value in update_data.dict(exclude_none=True).items():
-            # 确保不更新id字段
-            if key != 'id':
-                setattr(unit, key, value)
-        db.commit()
-        db.refresh(unit)
-        return {"code": 200, "msg": "更新成功", "unit": unit.to_dict()}
-    except Exception as e:
-        traceback.print_exc()
-        db.rollback()
-        raise HTTPException(status_code=400, detail=str(e))
-    
-# 导入
-@router.post('/rescue_units/import')
-async def import_doc(
-    request: Request, 
-    db: Session = Depends(get_db), 
-    body = Depends(remove_xss_json), 
-    user_id = Depends(valid_access_token)
-):
-    # print(body)
-    
-    try:
-        filename = body['filename']
-        if len(filename) == 0:
-            raise Exception()
-        
-        file = filename[0]
-        url = file['url']
-        file_path = f"{UPLOAD_mergefile_PATH}/uploads/{url}"
-        file_path = os.path.abspath(file_path)
-        print(file_path)
-        
-        book = xlrd.open_workbook(file_path)
-        sheet = book.sheet_by_index(0)
-
-        data = []
-        '''
-        for i in range(9, sheet.nrows):
-
-            # 预案名称
-            plan_name = sheet.cell(i, 0).value
-
-            # 一级目录
-            title1 = sheet.cell(i, 1).value
-
-            # 二级目录
-            title2 = sheet.cell(i, 2).value
-
-            # 三级目录
-            title3 = sheet.cell(i, 3).value
-
-            # 正文
-            content = sheet.cell(i, 4).value
-
-            if len(plan_name) < 1 and len(title1) < 1 and len(title2) < 1 and len(title3) < 1 and len(content) < 1 :
-                break
-
-            data.append({
-                'plan_name': plan_name,
-                'title1': title1,
-                'title2': title2,
-                'title3': title3,
-                'content': content,
-            })
-
-        if len(data) > 0:
-            db.query(EmergencyDoc).filter(EmergencyDoc.plan_id == plan_id).delete()
-            db.commit()
-
-        title1 = ''
-        content = ''
-        docs = []
-        for n in data:
-            if n['title1'] != '':
-                if len(docs) > 0:
-                    add_doc_1(db, title1, content, docs, plan_id)
-
-                docs = []
-                title1 = n['title1']
-                content = n['content']
-                if n['title2'] != '':
-                    docs.append(n)
-                continue
-
-            docs.append(n)
-
-        if len(docs) > 0:
-            add_doc_1(db, title1, content, docs, plan_id)
-        '''
-
-        return {
-            'code': 200,
-            'msg': '导入成功'
-        }
-    except Exception:
-        traceback.print_exc()
-        return {
-            'code': 500,
-            'msg': '导入发生异常'
-        }
-
 #救援人员接口
 #救援人员接口
 
 
 class RescuePersonnelSchema(BaseModel):
 class RescuePersonnelSchema(BaseModel):

+ 332 - 0
routers/api/resourceProvison/emergency/rescue_units.py

@@ -0,0 +1,332 @@
+# from fastapi import APIRouter, HTTPException, Depends, Body,Query
+from fastapi import APIRouter, Request, Depends, HTTPException, Query, BackgroundTasks
+from fastapi.responses import JSONResponse
+import os
+# from sqlalchemy.orm import Session
+from sqlalchemy.orm import Session, joinedload
+import xlrd
+from database import get_db, get_db_share
+from models import *
+from typing import List, Optional
+from pydantic import BaseModel,Extra, Field
+import uuid
+from common.security import valid_access_token
+from pydantic import BaseModel
+from exceptions import AppException, HmacException
+from common.security import valid_access_token
+import traceback
+from utils import *
+from common.auth_user import *
+from common.db import db_czrz
+from sqlalchemy import create_engine, Column, Integer, String, Boolean, MetaData, Table, \
+    inspect, exists,or_,text,insert,asc,desc
+
+
+# 目录在文档上传接口写死
+UPLOAD_mergefile_PATH = '/data/upload/mergefile'
+
+router = APIRouter()
+
+
+
+# 救灾人员单位
+# Pydantic 模型
+class UnitSchema(BaseModel):
+    id: int = None
+    name: str = None
+    category: str = None
+    contact_number: str = None
+    responsible_person: str = None
+    contact_number: str = None
+    team_size: int = None
+    supervisor_unit: str = None
+    unit_prop: str = None
+    unit_level: str = None
+    unit_favor: str = None
+    supervisor_unit_phone: str = None
+    supervisor_unit_contact: str = None
+    responsible_person_phone: str = None
+    area: str = None
+    founding_time: str = None
+    address: str = None
+    longitude: str = None
+    latitude: str = None
+    position: str = None
+    is_delete: int = 0
+
+class UnitListSchema(BaseModel):
+    units: List[UnitSchema] = Field(default_factory=list)
+
+    class Config:
+        orm_mode = True
+#创建
+@router.post("/")
+def create_units(unit_list_data: UnitListSchema, db: Session = Depends(get_db)):
+    units = unit_list_data.units
+    if not units:  # 确保列表不为空
+        raise HTTPException(status_code=400, detail="单位列表不能为空")
+    try:
+        new_units = []  # 创建一个空列表来存储新对象
+        for unit_data in units:
+
+            unit_data = unit_data.dict(exclude_none=True)
+            unit_data["add_time"] = datetime.now()
+            print(unit_data)
+            new_unit = RescueUnit(**unit_data)
+            db.add(new_unit)
+            db.commit()
+            db.refresh(new_unit)
+            new_units.append(new_unit)
+        
+        unit_ids = [unit.id for unit in new_units]  # 获取所有新对象的ID
+        return {"code": 200, "msg": "创建成功", "unit_ids": unit_ids}
+    except Exception as e:
+        traceback.print_exc()
+        db.rollback()
+        raise HTTPException(status_code=400, detail=str(e))
+#删除
+@router.delete("/{unit_id}")
+def delete_unit(unit_id: int, db: Session = Depends(get_db), user_id=Depends(valid_access_token)):
+    unit = db.query(RescueUnit).get(unit_id)
+    if not unit:
+        raise HTTPException(status_code=404, detail="单位不存在")
+    try:
+        # 更新 is_delete 字段为 1,而不是删除记录
+        unit.is_delete = 1
+        db.commit()
+        return {"code": 200, "msg": "删除成功"}
+    except Exception as e:
+        traceback.print_exc()
+        db.rollback()
+        raise HTTPException(status_code=400, detail=str(e))
+
+
+
+# class UnitListQueryParams(BaseModel):
+#     page: int = Field(default=1, gt=0)
+#     page_size: int = Field(default=10, gt=0)
+
+#查询列表
+@router.get("/list")
+def get_units(page: int = Query(default=1, gt=0),
+              pageSize: int = Query(default=10, gt=0),
+              db: Session = Depends(get_db),
+              user_id=Depends(valid_access_token)):
+    # 应用过滤条件,仅查询未被删除的单位
+    data_query = db.query(RescueUnit).filter(RescueUnit.is_delete == 0)
+    data_query = data_query.order_by(RescueUnit.add_time.desc())
+    # 计算总数
+    total_count = data_query.count()
+
+    # 分页查询
+    offset = (page - 1) * pageSize
+    units = data_query.offset(offset).limit(pageSize).all()
+
+    # 构造结果
+    result_items = [unit.to_dict() for unit in units]
+
+    result = {
+        "code": 200,
+        'msg': '查询成功',
+        'total': total_count,
+        'totalPages': (total_count + pageSize - 1) // pageSize,
+        'page': page,
+        'pageSize': pageSize,
+        'data': result_items
+    }
+
+    return result
+
+
+#查询详情
+@router.get("/detail/{unit_id}")
+def get_unit_by_id(unit_id: int, db: Session = Depends(get_db), user_id=Depends(valid_access_token)):
+    # unit = db.query(Unit).filter(Unit.is_delete == 0).get(unit_id)
+    unit = db.query(RescueUnit).filter_by(id=unit_id, is_delete=0).first()
+
+    if not unit:
+        raise HTTPException(status_code=404, detail="单位不存在或已被标记为删除")
+    return {"code": 200, "msg": "查询成功", "unit": unit.to_dict()}
+
+#修改
+@router.put("/edit/{unit_id}")
+def update_unit(unit_id: int, update_data: UnitSchema, db: Session = Depends(get_db),
+                user_id=Depends(valid_access_token)):
+    # 根据id和is_delete字段获取单位
+    unit = db.query(RescueUnit).filter_by(id=unit_id, is_delete=0).first()
+    if not unit:
+        raise HTTPException(status_code=404, detail="单位不存在或已被标记为删除")
+
+    try:
+        # 更新非空字段,排除id字段
+        for key, value in update_data.dict(exclude_none=True).items():
+            # 确保不更新id字段
+            if key != 'id':
+                setattr(unit, key, value)
+        db.commit()
+        db.refresh(unit)
+        return {"code": 200, "msg": "更新成功", "unit": unit.to_dict()}
+    except Exception as e:
+        traceback.print_exc()
+        db.rollback()
+        raise HTTPException(status_code=400, detail=str(e))
+    
+# 导入
+@router.post('/import')
+async def import_doc(
+    request: Request, 
+    db: Session = Depends(get_db), 
+    body = Depends(remove_xss_json), 
+    user_id = Depends(valid_access_token)
+):
+    # print(body)
+    
+    try:
+        filename = body['filename']
+        if len(filename) == 0:
+            raise Exception()
+        
+        file = filename[0]
+        url = file['url']
+        file_path = f"{UPLOAD_mergefile_PATH}/uploads/{url}"
+        file_path = os.path.abspath(file_path)
+        print(file_path)
+        
+        book = xlrd.open_workbook(file_path)
+        sheet = book.sheet_by_index(0)
+
+        data = []
+        '''
+        for i in range(9, sheet.nrows):
+
+            # 预案名称
+            plan_name = sheet.cell(i, 0).value
+
+            # 一级目录
+            title1 = sheet.cell(i, 1).value
+
+            # 二级目录
+            title2 = sheet.cell(i, 2).value
+
+            # 三级目录
+            title3 = sheet.cell(i, 3).value
+
+            # 正文
+            content = sheet.cell(i, 4).value
+
+            if len(plan_name) < 1 and len(title1) < 1 and len(title2) < 1 and len(title3) < 1 and len(content) < 1 :
+                break
+
+            data.append({
+                'plan_name': plan_name,
+                'title1': title1,
+                'title2': title2,
+                'title3': title3,
+                'content': content,
+            })
+
+        if len(data) > 0:
+            db.query(EmergencyDoc).filter(EmergencyDoc.plan_id == plan_id).delete()
+            db.commit()
+
+        title1 = ''
+        content = ''
+        docs = []
+        for n in data:
+            if n['title1'] != '':
+                if len(docs) > 0:
+                    add_doc_1(db, title1, content, docs, plan_id)
+
+                docs = []
+                title1 = n['title1']
+                content = n['content']
+                if n['title2'] != '':
+                    docs.append(n)
+                continue
+
+            docs.append(n)
+
+        if len(docs) > 0:
+            add_doc_1(db, title1, content, docs, plan_id)
+        '''
+
+        return {
+            'code': 200,
+            'msg': '导入成功'
+        }
+    except Exception:
+        traceback.print_exc()
+        return {
+            'code': 500,
+            'msg': '导入发生异常'
+        }
+    
+
+
+@router.get("/export")
+async def get_list_info(
+        request: Request,
+        keyword: str = Query(None),
+        auth_user: AuthUser = Depends(find_auth_user),
+        db: Session = Depends(get_db_share),
+        mmdb:Session = Depends(get_db)
+):
+    try:
+        query = db.query(EmergencyExpertInfo)
+        if keyword:
+            query = query.filter(or_(EmergencyExpertInfo.name.like(f'%{keyword}%'),
+                                 EmergencyExpertInfo.unit.like(f'%{keyword}%'),
+                                 EmergencyExpertInfo.professional_title.like(f'%{keyword}%'),
+                                 EmergencyExpertInfo.professional_group.like(f'%{keyword}%'),
+                                 EmergencyExpertInfo.professional_field.like(f'%{keyword}%')))
+        data = query.all()
+        data = [{'序号':info.id,
+                    '姓名':info.name,
+                    '所属区县':info.county,
+                    '专家类型':info.expert_type,
+                    '荣誉称号':info.honorary_title,
+                    '单位' :info.unit,
+                    '职位' :info.position,
+                    '职称' :info.professional_title,
+                    '擅长事故类型' :info.specialty,
+                    '救援经历' :info.rescue_experience,
+                    '出生日期' :info.birth_date,
+                    '工作时间' :info.work_start_date,
+                    '发证日期' :info.certificate_issue_date,
+                    '专业分组' :info.professional_group,
+                    '专业领域' :info.professional_field,
+                    '工作电话' :info.work_phone,
+                    '住宅电话' :info.home_phone,
+                    '移动电话' :info.mobile_phone,
+                    '电子邮箱' :info.email,
+                    '联系地址' :info.contact_address,
+                    '经度' :info.longitude,
+                    '纬度' :info.latitude} for info in data]
+        # 返回结果
+        import pandas as pd
+        from io import BytesIO
+        # 将查询结果转换为 DataFrame
+        df = pd.DataFrame(data)
+
+        # 将 DataFrame 导出为 Excel 文件
+        output = BytesIO()
+        with pd.ExcelWriter(output, engine='openpyxl') as writer:
+            df.to_excel(writer, index=False)
+
+        # 设置响应头
+        output.seek(0)
+        from urllib.parse import quote
+        encoded_filename = f'应急专家管理导出{datetime.now().strftime("%Y%m%d%H%mi%s")}.xlsx'
+        encoded_filename = quote(encoded_filename, encoding='utf-8')
+        headers = {
+            'Content-Disposition': f'attachment; filename*=UTF-8\'\'{encoded_filename}',
+            'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
+        }
+
+        db_czrz.log(mmdb, auth_user, "应急专家管理", f"应急专家管理导出数据成功", request.client.host)
+
+        # 返回文件流
+        return StreamingResponse(output, headers=headers)
+    except Exception as e:
+        traceback.print_exc()
+        return JSONResponse(status_code=500, content={'msg': f"Internal server error: {str(e)}", 'code': 500})

+ 7 - 1
routers/api/taskRegistration/__init__.py

@@ -16,7 +16,7 @@ from utils import *
 import copy
 import copy
 from config import settings
 from config import settings
 from common import YzyApi
 from common import YzyApi
-from common.db import db_event_management, db_user, db_msg_center, db_yzy, db_dept
+from common.db import db_event_management, db_user, db_msg_center, db_yzy, db_dept, db_czrz
 
 
 router = APIRouter()
 router = APIRouter()
 
 
@@ -95,6 +95,12 @@ async def create_task(
         # 发送粤政易消息
         # 发送粤政易消息
         send_yzy_msg(db, task_base, user_id)
         send_yzy_msg(db, task_base, user_id)
 
 
+        try:
+            user_info = db_user.get_user_info(db, user_id)
+            db_czrz.log_username(db, user_id, user_info.user_name, user_info.nick_name, "应急一张图", "任务下达", request.client.host)
+        except:
+            traceback.print_exc()
+
         return {
         return {
             "code": 200,
             "code": 200,
             "msg": "任务创建成功",
             "msg": "任务创建成功",

+ 8 - 6
routers/api/upload_file/__init__.py

@@ -173,19 +173,21 @@ async def mergefile(identifier: str = Query(''),
 async def download_file(
 async def download_file(
     filename: str,
     filename: str,
     filenameDesc: str = None, 
     filenameDesc: str = None, 
-    user_id = Depends(valid_access_token)
+    # user_id = Depends(valid_access_token)
 ):
 ):
     """
     """
     根据提供的文件名下载文件。
     根据提供的文件名下载文件。
     :param filename: 要下载的文件的名称。
     :param filename: 要下载的文件的名称。
     """
     """
     try:
     try:
-        if user_id == False:
-            return JSONResponse(status_code=404, content={'code': 404, "msg": '警告:未登录禁止下载文件'})
-        # 构造文件的完整路径
-        if '../' in filename or '/' in filename:
-            return JSONResponse(status_code=404, content={'code': 404, "msg": '警告:禁止跨路径下载文件'})
+        # if user_id == False:
+        #     return JSONResponse(status_code=404, content={'code': 404, "msg": '警告:未登录禁止下载文件'})
+        # # 构造文件的完整路径
+        # if '../' in filename or '/' in filename:
+        #     return JSONResponse(status_code=404, content={'code': 404, "msg": '警告:禁止跨路径下载文件'})
+        
         file_path = os.path.join(UPLOAD_mergefile_PATH, 'uploads/', filename)
         file_path = os.path.join(UPLOAD_mergefile_PATH, 'uploads/', filename)
+        print(file_path)
 
 
         # 检查文件是否存在
         # 检查文件是否存在
         if not os.path.isfile(file_path):
         if not os.path.isfile(file_path):

+ 8 - 0
routers/api/videoResource/avcon.py

@@ -13,6 +13,7 @@ from fastapi.responses import JSONResponse
 import traceback
 import traceback
 import base64
 import base64
 from datetime import datetime
 from datetime import datetime
+from common.db import db_user, db_czrz
 from common import AvconH5API, AvconMiniAPI
 from common import AvconH5API, AvconMiniAPI
 from models import *
 from models import *
 
 
@@ -54,6 +55,7 @@ async def get_mini_video_list(
 
 
 @router.post("/get_start_mini_param")
 @router.post("/get_start_mini_param")
 async def get_start_mini_param(
 async def get_start_mini_param(
+    request: Request,  
     body = Depends(remove_xss_json),
     body = Depends(remove_xss_json),
     db: Session = Depends(get_db),
     db: Session = Depends(get_db),
     user_id = Depends(valid_access_token)
     user_id = Depends(valid_access_token)
@@ -97,6 +99,12 @@ async def get_start_mini_param(
     json_str = json.dumps(params, ensure_ascii=False)
     json_str = json.dumps(params, ensure_ascii=False)
     base64_str = base64.b64encode(json_str.encode('utf-8')).decode('utf-8')
     base64_str = base64.b64encode(json_str.encode('utf-8')).decode('utf-8')
 
 
+    try:
+        user_info = db_user.get_user_info(db, user_id)
+        db_czrz.log_username(db, user_id, user_info.user_name, user_info.nick_name, "应急一张图", "发起会议", request.client.host)
+    except:
+        traceback.print_exc()
+
     return {
     return {
         "code": 0,
         "code": 0,
         "msg": "success",
         "msg": "success",

+ 13 - 2
routers/prod_api/auth.py

@@ -86,7 +86,12 @@ async def login(
         uuid_str = data['uuid']
         uuid_str = data['uuid']
         code = data['code']
         code = data['code']
         # clientId = data['clientId']
         # clientId = data['clientId']
-        # grantType = data['grantType']
+
+        fromSystem = ''
+        if 'fromSystem' in data:
+            fromSystem = data['fromSystem']
+
+        logger.info("fromSystem: {}", fromSystem)
 
 
         # 仅为了可能的兼容
         # 仅为了可能的兼容
         clientId = "e5cd7e4891bf95d1d19206ce24a7b32e"
         clientId = "e5cd7e4891bf95d1d19206ce24a7b32e"
@@ -171,7 +176,13 @@ async def login(
             'user_name': username
             'user_name': username
         })
         })
 
 
-        db_czrz.log_username(db, row.user_id, auth['user_name'], row.nick_name, "登录", "后台管理登录成功", request.client.host)
+        action = '登录'
+        czrz = '后台管理登录成功'
+        if fromSystem == 'yjdp':
+            action = '应急一张图'
+            czrz = '大屏登录成功'
+
+        db_czrz.log_username(db, row.user_id, auth['user_name'], row.nick_name, action, czrz, request.client.host)
         row.login_date = datetime.now()
         row.login_date = datetime.now()
         row.login_ip = request.client.host
         row.login_ip = request.client.host
         row.login = row.login + 1
         row.login = row.login + 1

+ 56 - 0
routers/prod_api/system/czrz/__init__.py

@@ -34,6 +34,62 @@ async def get_list(
 ):
 ):
     print(params)
     print(params)
     query = db.query(CzrzEntity)
     query = db.query(CzrzEntity)
+    query = query.filter(CzrzEntity.action != '应急一张图')
+    if operIp:
+        query = query.filter(CzrzEntity.ip.like(f'%{operIp}%'))
+    if operName:
+        query = query.filter(CzrzEntity.nick_name.like(f'%{operName}%'))
+    if title:
+        query = query.filter(CzrzEntity.action.like(f'%{title}%'))
+    if dateRange:
+        start_date, end_date = dateRange.split('-')
+        # start_date = datetime.strptime(start_date, "%Y-%m-%d")
+        # end_date = datetime.strptime(end_date, "%Y-%m-%d") + timedelta(days=1)
+        query = query.filter(CzrzEntity.gxsj.between(start_date, end_date))
+
+    total_count = query.count()
+
+    offset = (pageNum - 1) * pageSize
+    query = query.order_by(CzrzEntity.gxsj.desc()).offset(offset).limit(pageSize)
+    czrz_list = query.all()
+
+    # 将模型实例转换为字典
+    czrz_list_dict = [{
+            "operIp": item.ip,
+            "operName": item.nick_name,
+            "title": item.action,
+            "czrz": item.czrz,
+            "operTime": item.gxsj.strftime('%Y-%m-%d %H:%M:%S') if item.gxsj else '',
+        } for item in czrz_list]
+
+
+    return {
+        "code": 200,
+        "msg": "操作成功",
+        "rows": czrz_list_dict,
+        'pages': (total_count + pageSize - 1) // pageSize,
+        'total': total_count,
+        "currentPage": pageNum,
+        "pageSize": pageSize,
+    }
+
+
+
+@router.get('/yjdplist')
+async def get_list(
+    # request: Request,
+    operIp: str = Query(None, max_length=100),
+    operName:str = Query(None, max_length=100),
+    title: str =  Query(None, max_length=100),
+    params: str =  Query(None, max_length=100),
+    dateRange: str =  Query(None, max_length=100),
+    pageNum: int = Query(1, gt=0, description="页码"),
+    pageSize: int = Query(10, gt=0, le=100, description="每页大小"),
+    db: Session = Depends(get_db),
+    user_id = Depends(valid_access_token),
+):
+    query = db.query(CzrzEntity)
+    query = query.filter(CzrzEntity.action == '应急一张图')
     if operIp:
     if operIp:
         query = query.filter(CzrzEntity.ip.like(f'%{operIp}%'))
         query = query.filter(CzrzEntity.ip.like(f'%{operIp}%'))
     if operName:
     if operName:

+ 22 - 1
utils/redis_util.py

@@ -6,7 +6,7 @@ import json
 import time
 import time
 
 
 def get_redis():
 def get_redis():
-    redis = StrictRedis(host=settings.REDIS_DB_URL['host'], port=settings.REDIS_DB_URL['port'], db=settings.REDIS_DB_URL['db'], password=settings.REDIS_DB_URL['password'])
+    redis = StrictRedis(host=settings.REDIS_DB_URL['host'], port=settings.REDIS_DB_URL['port'], username=settings.REDIS_DB_URL['user'], db=settings.REDIS_DB_URL['db'], password=settings.REDIS_DB_URL['password'])
     return redis
     return redis
 
 
 def redis_set(name: str, val: str):
 def redis_set(name: str, val: str):
@@ -49,3 +49,24 @@ def redis_get_json(name: str):
     if json_str is not None:
     if json_str is not None:
         return json.loads(json_str)
         return json.loads(json_str)
 
 
+
+if __name__ == '__main__':
+    try:
+        # 连接 Redis(指定 username 和 password)
+        r = StrictRedis(
+            host='localhost',
+            port=6379,
+            username='default',  # Redis 6.0+ 支持
+            password='c0b0Info'
+        )
+        
+        # 测试连接
+        r.ping()
+        print("✅ 连接成功!")
+        
+        # 执行一些操作
+        r.set('test_key', 'hello')
+        print("test_key:", r.get('test_key').decode('utf-8'))
+        
+    except Exception as e:
+        print(f"❌ 连接失败: {e}")