diff --git a/README.md b/README.md index 0fe715c817574cd5f3ad1bb5820bbd011230cbee..35d5ebc84a651b62859ca4555d554b76fc4aa542 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@

logo

-

Dash-FastAPI-Admin v1.4.0

+

Dash-FastAPI-Admin v1.4.1

基于Dash+FastAPI前后端分离的纯Python快速开发框架

- + @@ -17,6 +17,7 @@ + ## 平台简介 Dash-FastAPI-Admin是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。 diff --git a/dash-fastapi-backend/.env.dev b/dash-fastapi-backend/.env.dev index 4923d01a8a9ecd3ba046e66a177cbaad27b773ed..27b925ec8cfa176e41ff5525bf3960cf33c05af4 100644 --- a/dash-fastapi-backend/.env.dev +++ b/dash-fastapi-backend/.env.dev @@ -10,7 +10,7 @@ APP_HOST = '0.0.0.0' # 应用端口 APP_PORT = 9099 # 应用版本 -APP_VERSION= '1.4.0' +APP_VERSION= '1.4.1' # 应用是否开启热重载 APP_RELOAD = true # 应用是否开启IP归属区域查询 @@ -42,6 +42,14 @@ DB_PASSWORD = 'mysqlroot' DB_DATABASE = 'dash-fastapi' # 是否开启sqlalchemy日志 DB_ECHO = true +# 允许溢出连接池大小的最大连接数 +DB_MAX_OVERFLOW = 10 +# 连接池大小,0表示连接数无限制 +DB_POOL_SIZE = 50 +# 连接回收时间(单位:秒) +DB_POOL_RECYCLE = 3600 +# 连接池中没有线程可用时,最多等待的时间(单位:秒) +DB_POOL_TIMEOUT = 30 # -------- Redis配置 -------- # Redis主机 diff --git a/dash-fastapi-backend/.env.prod b/dash-fastapi-backend/.env.prod index 1e06e0d8c8d8d85ea92560461683426c1bbdfd96..f73763cdd1523a51b3111f84821ef28819f83b31 100644 --- a/dash-fastapi-backend/.env.prod +++ b/dash-fastapi-backend/.env.prod @@ -10,7 +10,7 @@ APP_HOST = '0.0.0.0' # 应用端口 APP_PORT = 9099 # 应用版本 -APP_VERSION= '1.4.0' +APP_VERSION= '1.4.1' # 应用是否开启热重载 APP_RELOAD = false # 应用是否开启IP归属区域查询 @@ -42,6 +42,14 @@ DB_PASSWORD = 'mysqlroot' DB_DATABASE = 'dash-fastapi' # 是否开启sqlalchemy日志 DB_ECHO = true +# 允许溢出连接池大小的最大连接数 +DB_MAX_OVERFLOW = 10 +# 连接池大小,0表示连接数无限制 +DB_POOL_SIZE = 50 +# 连接回收时间(单位:秒) +DB_POOL_RECYCLE = 3600 +# 连接池中没有线程可用时,最多等待的时间(单位:秒) +DB_POOL_TIMEOUT = 30 # -------- Redis配置 -------- # Redis主机 diff --git a/dash-fastapi-backend/config/database.py b/dash-fastapi-backend/config/database.py index 4f00f8b73d941698ad19824c8eed134ba2afc1d9..cb871ecb816a3ad308b6ca2758209f92da6d21e4 100644 --- a/dash-fastapi-backend/config/database.py +++ b/dash-fastapi-backend/config/database.py @@ -8,7 +8,12 @@ SQLALCHEMY_DATABASE_URL = f"mysql+pymysql://{DataBaseConfig.db_username}:{quote_ f"{DataBaseConfig.db_host}:{DataBaseConfig.db_port}/{DataBaseConfig.db_database}" engine = create_engine( - SQLALCHEMY_DATABASE_URL, echo=DataBaseConfig.db_echo + SQLALCHEMY_DATABASE_URL, + echo=DataBaseConfig.db_echo, + max_overflow=DataBaseConfig.db_max_overflow, + pool_size=DataBaseConfig.db_pool_size, + pool_recycle=DataBaseConfig.db_pool_recycle, + pool_timeout=DataBaseConfig.db_pool_timeout ) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) Base = declarative_base() diff --git a/dash-fastapi-backend/config/env.py b/dash-fastapi-backend/config/env.py index f257c1f6e61138ec6ab14604208b051a9fac4579..863719a7862e0446eff87a6e91a9cea67f2348f5 100644 --- a/dash-fastapi-backend/config/env.py +++ b/dash-fastapi-backend/config/env.py @@ -41,6 +41,10 @@ class DataBaseSettings(BaseSettings): db_password: str = 'mysqlroot' db_database: str = 'dash-fastapi' db_echo: bool = True + db_max_overflow: int = 10 + db_pool_size: int = 50 + db_pool_recycle: int = 3600 + db_pool_timeout: int = 30 class RedisSettings(BaseSettings): diff --git a/dash-fastapi-backend/module_admin/annotation/log_annotation.py b/dash-fastapi-backend/module_admin/annotation/log_annotation.py index 2e12462d2fea76901f60ddaf7b93c9cc3a3118f4..7c1f162699bde2aa2802ce48dacb20330e9bca19 100644 --- a/dash-fastapi-backend/module_admin/annotation/log_annotation.py +++ b/dash-fastapi-backend/module_admin/annotation/log_annotation.py @@ -1,4 +1,4 @@ -from functools import wraps +from functools import wraps, lru_cache from fastapi import Request from fastapi.responses import JSONResponse, ORJSONResponse, UJSONResponse import inspect @@ -52,21 +52,7 @@ def log_decorator(title: str, business_type: int, log_type: Optional[str] = 'ope oper_ip = request.headers.get('remote_addr') if request.headers.get('is_browser') == 'no' else request.headers.get('X-Forwarded-For') oper_location = '内网IP' if AppConfig.app_ip_location_query: - try: - if oper_ip != '127.0.0.1' and oper_ip != 'localhost': - ip_result = requests.get(f'https://qifu-api.baidubce.com/ip/geo/v1/district?ip={oper_ip}') - if ip_result.status_code == 200: - prov = ip_result.json().get('data').get('prov') - city = ip_result.json().get('data').get('city') - if prov or city: - oper_location = f'{prov}-{city}' - else: - oper_location = '未知' - else: - oper_location = '未知' - except Exception as e: - oper_location = '未知' - print(e) + oper_location = get_ip_location(oper_ip) # 根据不同的请求类型使用不同的方法获取请求参数 content_type = request.headers.get("Content-Type") if content_type and ("multipart/form-data" in content_type or 'application/x-www-form-urlencoded' in content_type): @@ -167,3 +153,26 @@ def log_decorator(title: str, business_type: int, log_type: Optional[str] = 'ope return wrapper return decorator + + +@lru_cache() +def get_ip_location(oper_ip: str): + """ + 查询ip归属区域 + :param oper_ip: 需要查询的ip + :return: ip归属区域 + """ + oper_location = '内网IP' + try: + if oper_ip != '127.0.0.1' and oper_ip != 'localhost': + oper_location = '未知' + ip_result = requests.get(f'https://qifu-api.baidubce.com/ip/geo/v1/district?ip={oper_ip}') + if ip_result.status_code == 200: + prov = ip_result.json().get('data').get('prov') + city = ip_result.json().get('data').get('city') + if prov or city: + oper_location = f'{prov}-{city}' + except Exception as e: + oper_location = '未知' + print(e) + return oper_location diff --git a/dash-fastapi-backend/module_admin/dao/role_dao.py b/dash-fastapi-backend/module_admin/dao/role_dao.py index 8ed51b4f4e3e6cf713ec95a2e217b64e65cf3ddb..7e2624f328c85ed8df3c0a3f929c8f6451ee869b 100644 --- a/dash-fastapi-backend/module_admin/dao/role_dao.py +++ b/dash-fastapi-backend/module_admin/dao/role_dao.py @@ -73,12 +73,12 @@ class RoleDao: query_role_menu_info = db.query(SysMenu).select_from(SysRole) \ .filter(SysRole.del_flag == 0, SysRole.role_id == role_id) \ .outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \ - .outerjoin(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, SysMenu.status == 0)) \ + .join(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, SysMenu.status == 0)) \ .distinct().all() query_role_dept_info = db.query(SysDept).select_from(SysRole) \ .filter(SysRole.del_flag == 0, SysRole.role_id == role_id) \ .outerjoin(SysRoleDept, SysRole.role_id == SysRoleDept.role_id) \ - .outerjoin(SysDept, and_(SysRoleDept.dept_id == SysDept.dept_id, SysDept.status == 0, SysDept.del_flag == 0)) \ + .join(SysDept, and_(SysRoleDept.dept_id == SysDept.dept_id, SysDept.status == 0, SysDept.del_flag == 0)) \ .distinct().all() results = dict( role=object_format_datetime(query_role_basic_info),