diff --git a/README.md b/README.md index 1771e4c47d33cf76698be62648e56b270cd8fa5e..b96177e2dce80fc346313c5ea90bd7dd2a3b9ed5 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,12 @@

logo

-

Dash-FastAPI-Admin v1.0.6

+

Dash-FastAPI-Admin v1.0.7

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

- + + @@ -75,7 +76,11 @@ Dash-FastAPI-Admin是一套全部开源的快速开发平台,毫无保留给 + + + + diff --git a/dash-fastapi-backend/app.py b/dash-fastapi-backend/app.py index da016c5c401aead81e7ce801c83b636509ddd426..93a8c2a6012bfb94aa3c7778bdc09a9ab53724d4 100644 --- a/dash-fastapi-backend/app.py +++ b/dash-fastapi-backend/app.py @@ -71,6 +71,12 @@ async def auth_exception_handler(request: Request, exc: AuthException): return response_401(data=exc.data, message=exc.message) +# 自定义权限检验异常 +@app.exception_handler(PermissionException) +async def permission_exception_handler(request: Request, exc: PermissionException): + return response_403(data=exc.data, message=exc.message) + + @app.exception_handler(HTTPException) async def http_exception_handler(request: Request, exc: HTTPException): return JSONResponse( @@ -97,4 +103,4 @@ app.include_router(cacheController, prefix="/monitor", tags=['系统监控-缓 app.include_router(commonController, prefix="/common", tags=['通用模块']) if __name__ == '__main__': - uvicorn.run(app='app:app', host="127.0.0.1", port=9099, reload=True) + uvicorn.run(app='app:app', host="0.0.0.0", port=9099, reload=True) diff --git a/dash-fastapi-backend/caches/avatar/admin/admin_avatar.jpeg b/dash-fastapi-backend/caches/avatar/admin/admin_avatar.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..6fda0548459e5a43be8be8dfa745bfaabbad6b0c Binary files /dev/null and b/dash-fastapi-backend/caches/avatar/admin/admin_avatar.jpeg differ diff --git a/dash-fastapi-backend/caches/avatar/admin_avatar.jpeg b/dash-fastapi-backend/caches/avatar/admin_avatar.jpeg deleted file mode 100644 index 58c3e92376f97cd5da3a16e1380210a365fc6c61..0000000000000000000000000000000000000000 Binary files a/dash-fastapi-backend/caches/avatar/admin_avatar.jpeg and /dev/null differ diff --git a/dash-fastapi-backend/caches/avatar/ry_avatar.jpeg b/dash-fastapi-backend/caches/avatar/ry/ry_avatar.jpeg similarity index 100% rename from dash-fastapi-backend/caches/avatar/ry_avatar.jpeg rename to dash-fastapi-backend/caches/avatar/ry/ry_avatar.jpeg diff --git a/dash-fastapi-backend/config/database.py b/dash-fastapi-backend/config/database.py index 707a3e6871d1665145f92258b82388e2daed5c9a..a9acc4c4f06f77155e6cbe2feaf82c7a0a7babc9 100644 --- a/dash-fastapi-backend/config/database.py +++ b/dash-fastapi-backend/config/database.py @@ -1,9 +1,10 @@ from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker +from urllib.parse import quote_plus from config.env import DataBaseConfig -SQLALCHEMY_DATABASE_URL = f"mysql+pymysql://{DataBaseConfig.USERNAME}:{DataBaseConfig.PASSWORD}@" \ +SQLALCHEMY_DATABASE_URL = f"mysql+pymysql://{DataBaseConfig.USERNAME}:{quote_plus(DataBaseConfig.PASSWORD)}@" \ f"{DataBaseConfig.HOST}:{DataBaseConfig.PORT}/{DataBaseConfig.DB}" engine = create_engine( diff --git a/dash-fastapi-backend/config/env.py b/dash-fastapi-backend/config/env.py index ab9ddc2dfc2aed73498b728dc93ac4bec11b652f..be50c118b8042fbe6d0327c60c639173d2d64964 100644 --- a/dash-fastapi-backend/config/env.py +++ b/dash-fastapi-backend/config/env.py @@ -39,3 +39,16 @@ class CachePathConfig: """ PATH = os.path.join(os.path.abspath(os.getcwd()), 'caches') PATHSTR = 'caches' + + +class RedisInitKeyConfig: + """ + 系统内置Redis键名 + """ + ACCESS_TOKEN = {'key': 'access_token', 'remark': '登录令牌信息'} + SYS_DICT = {'key': 'sys_dict', 'remark': '数据字典'} + SYS_CONFIG = {'key': 'sys_config', 'remark': '配置信息'} + CAPTCHA_CODES = {'key': 'captcha_codes', 'remark': '图片验证码'} + ACCOUNT_LOCK = {'key': 'account_lock', 'remark': '用户锁定'} + PASSWORD_ERROR_COUNT = {'key': 'password_error_count', 'remark': '密码错误次数'} + SMS_CODE = {'key': 'sms_code', 'remark': '短信验证码'} diff --git a/dash-fastapi-backend/module_admin/aspect/data_scope.py b/dash-fastapi-backend/module_admin/aspect/data_scope.py index 8afe1353e906fccdda401e74f0361307cf5629be..24f45258e6d410ae92a2f9ab8d94ceb00ec05e4b 100644 --- a/dash-fastapi-backend/module_admin/aspect/data_scope.py +++ b/dash-fastapi-backend/module_admin/aspect/data_scope.py @@ -8,9 +8,11 @@ class GetDataScope: """ 获取当前用户数据权限对应的查询sql语句 """ - def __init__(self, query_alias: Optional[str] = '', db_alias: Optional[str] = 'db'): + def __init__(self, query_alias: Optional[str] = '', db_alias: Optional[str] = 'db', user_alias: Optional[str] = 'user_id', dept_alias: Optional[str] = 'dept_id'): self.query_alias = query_alias self.db_alias = db_alias + self.user_alias = user_alias + self.dept_alias = dept_alias def __call__(self, current_user: CurrentUserInfoServiceResponse = Depends(get_current_user)): user_id = current_user.user.user_id @@ -22,13 +24,13 @@ class GetDataScope: if self.query_alias == '' or max_data_scope == 1 or user_id == 1: param_sql = '1 == 1' elif max_data_scope == 2: - param_sql = f'{self.query_alias}.dept_id.in_({self.db_alias}.query(SysRoleDept.dept_id).filter(SysRoleDept.role_id == {max_role_id}))' + param_sql = f"{self.query_alias}.{self.dept_alias}.in_({self.db_alias}.query(SysRoleDept.dept_id).filter(SysRoleDept.role_id == {max_role_id})) if hasattr({self.query_alias}, '{self.dept_alias}') else 1 == 1" elif max_data_scope == 3: - param_sql = f'{self.query_alias}.dept_id == {dept_id}' + param_sql = f"{self.query_alias}.{self.dept_alias} == {dept_id} if hasattr({self.query_alias}, '{self.dept_alias}') else 1 == 1" elif max_data_scope == 4: - param_sql = f'{self.query_alias}.dept_id.in_({self.db_alias}.query(SysDept.dept_id).filter(or_(SysDept.dept_id == {dept_id}, func.find_in_set({dept_id}, SysDept.ancestors))))' + param_sql = f"{self.query_alias}.{self.dept_alias}.in_({self.db_alias}.query(SysDept.dept_id).filter(or_(SysDept.dept_id == {dept_id}, func.find_in_set({dept_id}, SysDept.ancestors)))) if hasattr({self.query_alias}, '{self.dept_alias}') else 1 == 1" elif max_data_scope == 5: - param_sql = f'{self.query_alias}.user_id == {user_id}' + param_sql = f"{self.query_alias}.{self.user_alias} == {user_id} if hasattr({self.query_alias}, '{self.user_alias}') else 1 == 1" else: param_sql = '1 == 0' diff --git a/dash-fastapi-backend/module_admin/aspect/interface_auth.py b/dash-fastapi-backend/module_admin/aspect/interface_auth.py index ebaaf14e2766aedf9f52c8a46e5484666a1ff08c..a9d4f5eb1b8a368d191b0c1556ff331b0bec32e7 100644 --- a/dash-fastapi-backend/module_admin/aspect/interface_auth.py +++ b/dash-fastapi-backend/module_admin/aspect/interface_auth.py @@ -1,7 +1,7 @@ from fastapi import Depends from module_admin.entity.vo.user_vo import CurrentUserInfoServiceResponse from module_admin.service.login_service import get_current_user -from utils.response_util import AuthException +from utils.response_util import PermissionException class CheckUserInterfaceAuth: @@ -16,4 +16,4 @@ class CheckUserInterfaceAuth: user_auth_list.append('common') if self.perm_str in user_auth_list: return True - raise AuthException(data="", message="该用户无此接口权限") + raise PermissionException(data="", message="该用户无此接口权限") diff --git a/dash-fastapi-backend/module_admin/controller/cache_controller.py b/dash-fastapi-backend/module_admin/controller/cache_controller.py index e18696b2af8d4993671dcd0b132fd01350884b87..76426a58e1949c2877cdc4786ebc7ad1f51c1997 100644 --- a/dash-fastapi-backend/module_admin/controller/cache_controller.py +++ b/dash-fastapi-backend/module_admin/controller/cache_controller.py @@ -20,3 +20,75 @@ async def get_monitor_cache_info(request: Request): except Exception as e: logger.exception(e) return response_500(data="", message=str(e)) + + +@cacheController.post("/getNames", response_model=List[CacheInfoModel], dependencies=[Depends(CheckUserInterfaceAuth('monitor:cache:list'))]) +async def get_monitor_cache_name(request: Request): + try: + # 获取全量数据 + cache_name_list_result = CacheService.get_cache_monitor_cache_name_services() + logger.info('获取成功') + return response_200(data=cache_name_list_result, message="获取成功") + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@cacheController.post("/getKeys/{cache_name}", response_model=List[str], dependencies=[Depends(CheckUserInterfaceAuth('monitor:cache:list'))]) +async def get_monitor_cache_key(request: Request, cache_name: str): + try: + # 获取全量数据 + cache_key_list_result = await CacheService.get_cache_monitor_cache_key_services(request, cache_name) + logger.info('获取成功') + return response_200(data=cache_key_list_result, message="获取成功") + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@cacheController.post("/getValue/{cache_name}/{cache_key}", response_model=CacheInfoModel, dependencies=[Depends(CheckUserInterfaceAuth('monitor:cache:list'))]) +async def get_monitor_cache_value(request: Request, cache_name: str, cache_key: str): + try: + # 获取全量数据 + cache_value_list_result = await CacheService.get_cache_monitor_cache_value_services(request, cache_name, cache_key) + logger.info('获取成功') + return response_200(data=cache_value_list_result, message="获取成功") + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@cacheController.post("/clearCacheName/{cache_name}", response_model=CrudCacheResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:cache:list'))]) +async def clear_monitor_cache_name(request: Request, cache_name: str): + try: + clear_cache_name_result = await CacheService.clear_cache_monitor_cache_name_services(request, cache_name) + if clear_cache_name_result.is_success: + logger.info(clear_cache_name_result.message) + return response_200(data=clear_cache_name_result, message=clear_cache_name_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@cacheController.post("/clearCacheKey/{cache_name}/{cache_key}", response_model=CrudCacheResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:cache:list'))]) +async def clear_monitor_cache_key(request: Request, cache_name: str, cache_key: str): + try: + clear_cache_key_result = await CacheService.clear_cache_monitor_cache_key_services(request, cache_name, cache_key) + if clear_cache_key_result.is_success: + logger.info(clear_cache_key_result.message) + return response_200(data=clear_cache_key_result, message=clear_cache_key_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) + + +@cacheController.post("/clearCacheAll", response_model=CrudCacheResponse, dependencies=[Depends(CheckUserInterfaceAuth('monitor:cache:list'))]) +async def clear_monitor_cache_all(request: Request): + try: + clear_cache_all_result = await CacheService.clear_cache_monitor_all_services(request) + if clear_cache_all_result.is_success: + logger.info(clear_cache_all_result.message) + return response_200(data=clear_cache_all_result, message=clear_cache_all_result.message) + except Exception as e: + logger.exception(e) + return response_500(data="", message=str(e)) diff --git a/dash-fastapi-backend/module_admin/controller/captcha_controller.py b/dash-fastapi-backend/module_admin/controller/captcha_controller.py index d6a28840228cce907ebe43161b79f62bc1532a9e..22cbe06ecb15c8eebe09a5cbf62ec9796e60f09b 100644 --- a/dash-fastapi-backend/module_admin/controller/captcha_controller.py +++ b/dash-fastapi-backend/module_admin/controller/captcha_controller.py @@ -1,5 +1,6 @@ import uuid from fastapi import APIRouter, Request +from config.env import RedisInitKeyConfig from module_admin.service.captcha_service import * from utils.response_util import * from utils.log_util import * @@ -16,7 +17,7 @@ async def get_captcha_image(request: Request): captcha_result = CaptchaService.create_captcha_image_service() image = captcha_result[0] computed_result = captcha_result[1] - await request.app.state.redis.set(f'captcha_codes:{session_id}', computed_result, ex=timedelta(minutes=2)) + await request.app.state.redis.set(f"{RedisInitKeyConfig.CAPTCHA_CODES.get('key')}:{session_id}", computed_result, ex=timedelta(minutes=2)) logger.info(f'编号为{session_id}的会话获取图片验证码成功') return response_200(data={'image': image, 'session_id': session_id}, message='获取验证码成功') except Exception as e: diff --git a/dash-fastapi-backend/module_admin/controller/common_controller.py b/dash-fastapi-backend/module_admin/controller/common_controller.py index 7844e0c3a6edc3814f49f09fefcb1d84518fe147..adec809ddf7cd76c0d47de8f0ea098507a988cab 100644 --- a/dash-fastapi-backend/module_admin/controller/common_controller.py +++ b/dash-fastapi-backend/module_admin/controller/common_controller.py @@ -1,40 +1,43 @@ from fastapi import APIRouter, Request from fastapi import Depends, File, Form +from sqlalchemy.orm import Session from config.env import CachePathConfig +from config.get_db import get_db from module_admin.service.login_service import get_current_user from module_admin.service.common_service import * from module_admin.service.config_service import ConfigService from utils.response_util import * from utils.log_util import * from module_admin.aspect.interface_auth import CheckUserInterfaceAuth +from typing import Optional commonController = APIRouter() @commonController.post("/upload", dependencies=[Depends(get_current_user), Depends(CheckUserInterfaceAuth('common'))]) -async def common_upload(request: Request, uploadId: str = Form(), file: UploadFile = File(...)): +async def common_upload(request: Request, taskPath: str = Form(), uploadId: str = Form(), file: UploadFile = File(...)): try: try: - os.makedirs(os.path.join(CachePathConfig.PATH, uploadId)) + os.makedirs(os.path.join(CachePathConfig.PATH, taskPath, uploadId)) except FileExistsError: pass - CommonService.upload_service(CachePathConfig.PATH, uploadId, file) + CommonService.upload_service(CachePathConfig.PATH, taskPath, uploadId, file) logger.info('上传成功') - return response_200(data={'filename': file.filename}, message="上传成功") + return response_200(data={'filename': file.filename, 'path': f'/common/{CachePathConfig.PATHSTR}?taskPath={taskPath}&taskId={uploadId}&filename={file.filename}'}, message="上传成功") except Exception as e: logger.exception(e) return response_500(data="", message=str(e)) @commonController.post("/uploadForEditor", dependencies=[Depends(get_current_user), Depends(CheckUserInterfaceAuth('common'))]) -async def editor_upload(request: Request, uploadId: str = Form(), file: UploadFile = File(...)): +async def editor_upload(request: Request, baseUrl: str = Form(), uploadId: str = Form(), taskPath: str = Form(), file: UploadFile = File(...)): try: try: - os.makedirs(os.path.join(CachePathConfig.PATH, uploadId)) + os.makedirs(os.path.join(CachePathConfig.PATH, taskPath, uploadId)) except FileExistsError: pass - CommonService.upload_service(CachePathConfig.PATH, uploadId, file) + CommonService.upload_service(CachePathConfig.PATH, taskPath, uploadId, file) logger.info('上传成功') return JSONResponse( status_code=status.HTTP_200_OK, @@ -42,7 +45,7 @@ async def editor_upload(request: Request, uploadId: str = Form(), file: UploadFi { 'errno': 0, 'data': { - 'url': f'{request.base_url}common/{CachePathConfig.PATHSTR}?taskId={uploadId}&filename={file.filename}' + 'url': f'{baseUrl}/common/{CachePathConfig.PATHSTR}?taskPath={taskPath}&taskId={uploadId}&filename={file.filename}' }, } ) @@ -61,11 +64,16 @@ async def editor_upload(request: Request, uploadId: str = Form(), file: UploadFi @commonController.get(f"/{CachePathConfig.PATHSTR}") -def common_download(request: Request, taskId: str, filename: str): +async def common_download(request: Request, taskPath: str, taskId: str, filename: str, token: Optional[str] = None, query_db: Session = Depends(get_db)): try: def generate_file(): - with open(os.path.join(CachePathConfig.PATH, taskId, filename), 'rb') as response_file: + with open(os.path.join(CachePathConfig.PATH, taskPath, taskId, filename), 'rb') as response_file: yield from response_file + if taskPath not in ['notice']: + current_user = await get_current_user(request, token, query_db) + if current_user: + logger.info('获取成功') + return streaming_response_200(data=generate_file()) logger.info('获取成功') return streaming_response_200(data=generate_file()) except Exception as e: diff --git a/dash-fastapi-backend/module_admin/controller/dept_controller.py b/dash-fastapi-backend/module_admin/controller/dept_controller.py index 4103a9b3deccc167a6835014c48028535e4c46a1..b51aff61fe00d3efcd4d795dd63051786d05eff6 100644 --- a/dash-fastapi-backend/module_admin/controller/dept_controller.py +++ b/dash-fastapi-backend/module_admin/controller/dept_controller.py @@ -8,6 +8,7 @@ from module_admin.dao.dept_dao import * from utils.response_util import * from utils.log_util import * from module_admin.aspect.interface_auth import CheckUserInterfaceAuth +from module_admin.aspect.data_scope import GetDataScope from module_admin.annotation.log_annotation import log_decorator @@ -15,9 +16,9 @@ deptController = APIRouter(dependencies=[Depends(get_current_user)]) @deptController.post("/dept/tree", response_model=DeptTree, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) -async def get_system_dept_tree(request: Request, dept_query: DeptModel, query_db: Session = Depends(get_db)): +async def get_system_dept_tree(request: Request, dept_query: DeptModel, query_db: Session = Depends(get_db), data_scope_sql: str = Depends(GetDataScope('SysDept'))): try: - dept_query_result = DeptService.get_dept_tree_services(query_db, dept_query) + dept_query_result = DeptService.get_dept_tree_services(query_db, dept_query, data_scope_sql) logger.info('获取成功') return response_200(data=dept_query_result, message="获取成功") except Exception as e: @@ -26,9 +27,9 @@ async def get_system_dept_tree(request: Request, dept_query: DeptModel, query_db @deptController.post("/dept/forEditOption", response_model=DeptTree, dependencies=[Depends(CheckUserInterfaceAuth('common'))]) -async def get_system_dept_tree_for_edit_option(request: Request, dept_query: DeptModel, query_db: Session = Depends(get_db)): +async def get_system_dept_tree_for_edit_option(request: Request, dept_query: DeptModel, query_db: Session = Depends(get_db), data_scope_sql: str = Depends(GetDataScope('SysDept'))): try: - dept_query_result = DeptService.get_dept_tree_for_edit_option_services(query_db, dept_query) + dept_query_result = DeptService.get_dept_tree_for_edit_option_services(query_db, dept_query, data_scope_sql) logger.info('获取成功') return response_200(data=dept_query_result, message="获取成功") except Exception as e: @@ -37,9 +38,9 @@ async def get_system_dept_tree_for_edit_option(request: Request, dept_query: Dep @deptController.post("/dept/get", response_model=DeptResponse, dependencies=[Depends(CheckUserInterfaceAuth('system:dept:list'))]) -async def get_system_dept_list(request: Request, dept_query: DeptModel, query_db: Session = Depends(get_db)): +async def get_system_dept_list(request: Request, dept_query: DeptModel, query_db: Session = Depends(get_db), data_scope_sql: str = Depends(GetDataScope('SysDept'))): try: - dept_query_result = DeptService.get_dept_list_services(query_db, dept_query) + dept_query_result = DeptService.get_dept_list_services(query_db, dept_query, data_scope_sql) logger.info('获取成功') return response_200(data=dept_query_result, message="获取成功") except Exception as e: diff --git a/dash-fastapi-backend/module_admin/controller/login_controller.py b/dash-fastapi-backend/module_admin/controller/login_controller.py index 686b9d6e72108da3bd240a7fd0651a251a253fb8..e9a000bf25e400ded96d2329a489a6fe737fff11 100644 --- a/dash-fastapi-backend/module_admin/controller/login_controller.py +++ b/dash-fastapi-backend/module_admin/controller/login_controller.py @@ -2,7 +2,7 @@ from fastapi import APIRouter from module_admin.service.login_service import * from module_admin.entity.vo.login_vo import * from module_admin.dao.login_dao import * -from config.env import JwtConfig +from config.env import JwtConfig, RedisInitKeyConfig from utils.response_util import * from utils.log_util import * from module_admin.aspect.interface_auth import CheckUserInterfaceAuth @@ -16,7 +16,7 @@ loginController = APIRouter() @loginController.post("/loginByAccount", response_model=Token) @log_decorator(title='用户登录', business_type=0, log_type='login') async def login(request: Request, form_data: CustomOAuth2PasswordRequestForm = Depends(), query_db: Session = Depends(get_db)): - captcha_enabled = True if await request.app.state.redis.get(f'sys_config:sys.account.captchaEnabled') == 'true' else False + captcha_enabled = True if await request.app.state.redis.get(f"{RedisInitKeyConfig.SYS_CONFIG.get('key')}:sys.account.captchaEnabled") == 'true' else False user = UserLogin( **dict( user_name=form_data.username, @@ -44,10 +44,10 @@ async def login(request: Request, form_data: CustomOAuth2PasswordRequestForm = D }, expires_delta=access_token_expires ) - await request.app.state.redis.set(f'access_token:{session_id}', access_token, + await request.app.state.redis.set(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{session_id}", access_token, ex=timedelta(minutes=JwtConfig.REDIS_TOKEN_EXPIRE_MINUTES)) # 此方法可实现同一账号同一时间只能登录一次 - # await request.app.state.redis.set(f'access_token:{result[0].user_id}', access_token, + # await request.app.state.redis.set(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{result[0].user_id}", access_token, # ex=timedelta(minutes=JwtConfig.REDIS_TOKEN_EXPIRE_MINUTES)) logger.info('登录成功') # 判断请求是否来自于api文档,如果是返回指定格式的结果,用于修复api文档认证成功后token显示undefined的bug diff --git a/dash-fastapi-backend/module_admin/controller/user_controller.py b/dash-fastapi-backend/module_admin/controller/user_controller.py index c7f9a30c612a7aa813be324bcf2738fab4e5eed4..88433ffb216c214b906a8544e7da3e3567f85a50 100644 --- a/dash-fastapi-backend/module_admin/controller/user_controller.py +++ b/dash-fastapi-backend/module_admin/controller/user_controller.py @@ -2,7 +2,6 @@ from fastapi import APIRouter, Request from fastapi import Depends import base64 from config.get_db import get_db -from config.env import CachePathConfig from module_admin.service.login_service import get_current_user from module_admin.service.user_service import * from module_admin.entity.vo.user_vo import * @@ -109,7 +108,7 @@ async def change_system_user_profile_avatar(request: Request, edit_user: AddUser base64_string = avatar.split(',', 1)[1] # 解码 base64 字符串 file_data = base64.b64decode(base64_string) - dir_path = os.path.join(CachePathConfig.PATH, 'avatar') + dir_path = os.path.join(CachePathConfig.PATH, 'avatar', current_user.user.user_name) try: os.makedirs(dir_path) except FileExistsError: @@ -118,7 +117,7 @@ async def change_system_user_profile_avatar(request: Request, edit_user: AddUser with open(filepath, 'wb') as f: f.write(file_data) edit_user.user_id = current_user.user.user_id - edit_user.avatar = f'{request.base_url}common/{CachePathConfig.PATHSTR}?taskId=avatar&filename={current_user.user.user_name}_avatar.jpeg' + edit_user.avatar = f'/common/{CachePathConfig.PATHSTR}?taskPath=avatar&taskId={current_user.user.user_name}&filename={current_user.user.user_name}_avatar.jpeg' edit_user.update_by = current_user.user.user_name edit_user.update_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") edit_user_result = UserService.edit_user_services(query_db, edit_user) diff --git a/dash-fastapi-backend/module_admin/dao/dept_dao.py b/dash-fastapi-backend/module_admin/dao/dept_dao.py index dc5098d57a05d03f28288541298b4ca4da44d860..1686d095467808cba2426858a4cb6121d8864527 100644 --- a/dash-fastapi-backend/module_admin/dao/dept_dao.py +++ b/dash-fastapi-backend/module_admin/dao/dept_dao.py @@ -1,4 +1,6 @@ +from sqlalchemy import or_, func from sqlalchemy.orm import Session +from module_admin.entity.do.role_do import SysRoleDept from module_admin.entity.do.dept_do import SysDept from module_admin.entity.vo.dept_vo import DeptModel, DeptResponse, CrudDeptResponse from utils.time_format_util import list_format_datetime @@ -71,19 +73,25 @@ class DeptDao: return dept_info @classmethod - def get_dept_info_for_edit_option(cls, db: Session, dept_info: DeptModel): + def get_dept_info_for_edit_option(cls, db: Session, dept_info: DeptModel, data_scope_sql: str): """ 获取部门编辑对应的在用部门列表信息 :param db: orm对象 :param dept_info: 部门对象 + :param data_scope_sql: 数据权限对应的查询sql语句 :return: 部门列表信息 """ dept_result = db.query(SysDept) \ - .filter(SysDept.dept_id != dept_info.dept_id, SysDept.parent_id != dept_info.dept_id, - SysDept.del_flag == 0, SysDept.status == 0) \ + .filter(SysDept.dept_id != dept_info.dept_id, + SysDept.parent_id != dept_info.dept_id, + SysDept.del_flag == 0, SysDept.status == 0, + eval(data_scope_sql)) \ .all() + dept = cls.get_dept_by_id(db, dept_info.dept_id) + parent = cls.get_dept_by_id(db, dept.parent_id) + dept_result.insert(0, parent) - return list_format_datetime(dept_result) + return list_format_datetime(list(set(dept_result))) @classmethod def get_children_dept(cls, db: Session, dept_id: int): @@ -114,72 +122,40 @@ class DeptDao: return ancestors @classmethod - def get_dept_list_for_tree(cls, db: Session, dept_info: DeptModel): + def get_dept_list_for_tree(cls, db: Session, dept_info: DeptModel, data_scope_sql: str): """ 获取所有在用部门列表信息 :param db: orm对象 :param dept_info: 部门对象 + :param data_scope_sql: 数据权限对应的查询sql语句 :return: 在用部门列表信息 """ - if dept_info.dept_name: - dept_query_all = db.query(SysDept) \ - .filter(SysDept.status == 0, - SysDept.del_flag == 0, - SysDept.dept_name.like(f'%{dept_info.dept_name}%') if dept_info.dept_name else True) \ - .order_by(SysDept.order_num) \ - .distinct().all() - - dept = [] - if dept_query_all: - for dept_query in dept_query_all: - ancestor_info = dept_query.ancestors.split(',') - ancestor_info.append(dept_query.dept_id) - for ancestor in ancestor_info: - dept_item = cls.get_dept_by_id(db, int(ancestor)) - if dept_item: - dept.append(dept_item) - # 去重 - dept_result = list(set(dept)) - else: - dept_result = db.query(SysDept) \ - .filter(SysDept.status == 0, SysDept.del_flag == 0) \ - .order_by(SysDept.order_num) \ - .distinct().all() + dept_result = db.query(SysDept) \ + .filter(SysDept.status == 0, + SysDept.del_flag == 0, + SysDept.dept_name.like(f'%{dept_info.dept_name}%') if dept_info.dept_name else True, + eval(data_scope_sql)) \ + .order_by(SysDept.order_num) \ + .distinct().all() return list_format_datetime(dept_result) @classmethod - def get_dept_list(cls, db: Session, page_object: DeptModel): + def get_dept_list(cls, db: Session, page_object: DeptModel, data_scope_sql: str): """ 根据查询参数获取部门列表信息 :param db: orm对象 :param page_object: 不分页查询参数对象 + :param data_scope_sql: 数据权限对应的查询sql语句 :return: 部门列表信息对象 """ - if page_object.dept_name or page_object.status: - dept_query_all = db.query(SysDept) \ - .filter(SysDept.del_flag == 0, - SysDept.status == page_object.status if page_object.status else True, - SysDept.dept_name.like(f'%{page_object.dept_name}%') if page_object.dept_name else True) \ - .order_by(SysDept.order_num)\ - .distinct().all() - - dept = [] - if dept_query_all: - for dept_query in dept_query_all: - ancestor_info = dept_query.ancestors.split(',') - ancestor_info.append(dept_query.dept_id) - for ancestor in ancestor_info: - dept_item = cls.get_dept_by_id_for_list(db, int(ancestor)) - if dept_item: - dept.append(dept_item) - # 去重 - dept_result = list(set(dept)) - else: - dept_result = db.query(SysDept) \ - .filter(SysDept.del_flag == 0) \ - .order_by(SysDept.order_num) \ - .distinct().all() + dept_result = db.query(SysDept) \ + .filter(SysDept.del_flag == 0, + SysDept.status == page_object.status if page_object.status else True, + SysDept.dept_name.like(f'%{page_object.dept_name}%') if page_object.dept_name else True, + eval(data_scope_sql)) \ + .order_by(SysDept.order_num) \ + .distinct().all() result = dict( rows=list_format_datetime(dept_result), diff --git a/dash-fastapi-backend/module_admin/dao/menu_dao.py b/dash-fastapi-backend/module_admin/dao/menu_dao.py index 486b9d623e57f1e8e998eb6fa59ae3b716fd3fee..6409572fbde17b9895ca204a51c56123100f9d22 100644 --- a/dash-fastapi-backend/module_admin/dao/menu_dao.py +++ b/dash-fastapi-backend/module_admin/dao/menu_dao.py @@ -52,25 +52,25 @@ class MenuDao: :param role: 用户角色列表信息 :return: 菜单列表信息 """ - menu_result = [] - for item in role: - if item.role_id == 1: - menu_result = db.query(SysMenu) \ - .filter(SysMenu.menu_id != menu_info.menu_id, SysMenu.parent_id != menu_info.menu_id, - SysMenu.status == 0) \ - .all() - else: - menu_result = db.query(SysMenu).select_from(SysUser) \ - .filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \ - .outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \ - .outerjoin(SysRole, - and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \ - .outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \ - .outerjoin(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, - SysMenu.menu_id != menu_info.menu_id, SysMenu.parent_id != menu_info.menu_id, - SysMenu.status == 0)) \ - .order_by(SysMenu.order_num) \ - .distinct().all() + role_id_list = [item.role_id for item in role] + if 1 in role_id_list: + menu_result = db.query(SysMenu) \ + .filter(SysMenu.menu_id != menu_info.menu_id, SysMenu.parent_id != menu_info.menu_id, + SysMenu.status == 0) \ + .all() + else: + menu_result = db.query(SysMenu).select_from(SysUser) \ + .filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \ + .outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \ + .outerjoin(SysRole, + and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \ + .outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \ + .join(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, + SysMenu.menu_id != menu_info.menu_id, + SysMenu.parent_id != menu_info.menu_id, + SysMenu.status == 0)) \ + .order_by(SysMenu.order_num) \ + .distinct().all() return list_format_datetime(menu_result) @@ -84,28 +84,26 @@ class MenuDao: :param role: 用户角色列表信息 :return: 菜单列表信息 """ - menu_query_all = [] - for item in role: - if item.role_id == 1: - menu_query_all = db.query(SysMenu) \ - .filter(SysMenu.status == 0, - SysMenu.menu_name.like(f'%{menu_info.menu_name}%') if menu_info.menu_name else True) \ - .order_by(SysMenu.order_num) \ - .distinct().all() - break - else: - menu_query_all = db.query(SysMenu).select_from(SysUser) \ - .filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \ - .outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \ - .outerjoin(SysRole, - and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \ - .outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \ - .outerjoin(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, - SysMenu.status == 0, - SysMenu.menu_name.like( - f'%{menu_info.menu_name}%') if menu_info.menu_name else True)) \ - .order_by(SysMenu.order_num) \ - .distinct().all() + role_id_list = [item.role_id for item in role] + if 1 in role_id_list: + menu_query_all = db.query(SysMenu) \ + .filter(SysMenu.status == 0, + SysMenu.menu_name.like(f'%{menu_info.menu_name}%') if menu_info.menu_name else True) \ + .order_by(SysMenu.order_num) \ + .distinct().all() + else: + menu_query_all = db.query(SysMenu).select_from(SysUser) \ + .filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \ + .outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \ + .outerjoin(SysRole, + and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \ + .outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \ + .join(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, + SysMenu.status == 0, + SysMenu.menu_name.like( + f'%{menu_info.menu_name}%') if menu_info.menu_name else True)) \ + .order_by(SysMenu.order_num) \ + .distinct().all() return list_format_datetime(menu_query_all) @@ -119,29 +117,27 @@ class MenuDao: :param role: 用户角色列表 :return: 菜单列表信息对象 """ - menu_query_all = [] - for item in role: - if item.role_id == 1: - menu_query_all = db.query(SysMenu) \ - .filter(SysMenu.status == page_object.status if page_object.status else True, - SysMenu.menu_name.like( - f'%{page_object.menu_name}%') if page_object.menu_name else True) \ - .order_by(SysMenu.order_num) \ - .distinct().all() - break - else: - menu_query_all = db.query(SysMenu).select_from(SysUser) \ - .filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \ - .outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \ - .outerjoin(SysRole, - and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \ - .outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \ - .outerjoin(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, - SysMenu.status == page_object.status if page_object.status else True, - SysMenu.menu_name.like( - f'%{page_object.menu_name}%') if page_object.menu_name else True)) \ - .order_by(SysMenu.order_num) \ - .distinct().all() + role_id_list = [item.role_id for item in role] + if 1 in role_id_list: + menu_query_all = db.query(SysMenu) \ + .filter(SysMenu.status == page_object.status if page_object.status else True, + SysMenu.menu_name.like( + f'%{page_object.menu_name}%') if page_object.menu_name else True) \ + .order_by(SysMenu.order_num) \ + .distinct().all() + else: + menu_query_all = db.query(SysMenu).select_from(SysUser) \ + .filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \ + .outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \ + .outerjoin(SysRole, + and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \ + .outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \ + .join(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, + SysMenu.status == page_object.status if page_object.status else True, + SysMenu.menu_name.like( + f'%{page_object.menu_name}%') if page_object.menu_name else True)) \ + .order_by(SysMenu.order_num) \ + .distinct().all() result = dict( rows=list_format_datetime(menu_query_all), diff --git a/dash-fastapi-backend/module_admin/dao/user_dao.py b/dash-fastapi-backend/module_admin/dao/user_dao.py index 74ee0236eefd09d5170325791bf31a33e8a66206..d7a0a505e59ca812f01462153c267228cc4254e8 100644 --- a/dash-fastapi-backend/module_admin/dao/user_dao.py +++ b/dash-fastapi-backend/module_admin/dao/user_dao.py @@ -58,34 +58,32 @@ class UserDao: .distinct().all() query_user_dept_info = db.query(SysDept).select_from(SysUser) \ .filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \ - .outerjoin(SysDept, and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == 0, SysDept.del_flag == 0)) \ + .join(SysDept, and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == 0, SysDept.del_flag == 0)) \ .distinct().all() query_user_role_info = db.query(SysRole).select_from(SysUser) \ .filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \ .outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \ - .outerjoin(SysRole, and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \ + .join(SysRole, and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \ .distinct().all() query_user_post_info = db.query(SysPost).select_from(SysUser) \ .filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \ .outerjoin(SysUserPost, SysUser.user_id == SysUserPost.user_id) \ - .outerjoin(SysPost, and_(SysUserPost.post_id == SysPost.post_id, SysPost.status == 0)) \ + .join(SysPost, and_(SysUserPost.post_id == SysPost.post_id, SysPost.status == 0)) \ .distinct().all() - query_user_menu_info = [] - for item in query_user_role_info: - if item.role_id == 1: - query_user_menu_info = db.query(SysMenu) \ - .filter(SysMenu.status == 0) \ - .distinct().all() - break - else: - query_user_menu_info = db.query(SysMenu).select_from(SysUser) \ - .filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \ - .outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \ - .outerjoin(SysRole, and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \ - .outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \ - .outerjoin(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, SysMenu.status == 0)) \ - .order_by(SysMenu.order_num) \ - .distinct().all() + role_id_list = [item.role_id for item in query_user_role_info] + if 1 in role_id_list: + query_user_menu_info = db.query(SysMenu) \ + .filter(SysMenu.status == 0) \ + .distinct().all() + else: + query_user_menu_info = db.query(SysMenu).select_from(SysUser) \ + .filter(SysUser.status == 0, SysUser.del_flag == 0, SysUser.user_id == user_id) \ + .outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \ + .outerjoin(SysRole, and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \ + .outerjoin(SysRoleMenu, SysRole.role_id == SysRoleMenu.role_id) \ + .join(SysMenu, and_(SysRoleMenu.menu_id == SysMenu.menu_id, SysMenu.status == 0)) \ + .order_by(SysMenu.order_num) \ + .distinct().all() results = dict( user_basic_info=list_format_datetime(query_user_basic_info), user_dept_info=list_format_datetime(query_user_dept_info), @@ -109,24 +107,24 @@ class UserDao: .distinct().all() query_user_dept_info = db.query(SysDept).select_from(SysUser) \ .filter(SysUser.del_flag == 0, SysUser.user_id == user_id) \ - .outerjoin(SysDept, and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == 0, SysDept.del_flag == 0)) \ + .join(SysDept, and_(SysUser.dept_id == SysDept.dept_id, SysDept.status == 0, SysDept.del_flag == 0)) \ .distinct().all() query_user_role_info = db.query(SysRole).select_from(SysUser) \ .filter(SysUser.del_flag == 0, SysUser.user_id == user_id) \ .outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \ - .outerjoin(SysRole, and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \ + .join(SysRole, and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \ .distinct().all() query_user_post_info = db.query(SysPost).select_from(SysUser) \ .filter(SysUser.del_flag == 0, SysUser.user_id == user_id) \ .outerjoin(SysUserPost, SysUser.user_id == SysUserPost.user_id) \ - .outerjoin(SysPost, and_(SysUserPost.post_id == SysPost.post_id, SysPost.status == 0)) \ + .join(SysPost, and_(SysUserPost.post_id == SysPost.post_id, SysPost.status == 0)) \ .distinct().all() query_user_menu_info = db.query(SysMenu).select_from(SysUser) \ .filter(SysUser.del_flag == 0, SysUser.user_id == user_id) \ .outerjoin(SysUserRole, SysUser.user_id == SysUserRole.user_id) \ .outerjoin(SysRole, and_(SysUserRole.role_id == SysRole.role_id, SysRole.status == 0, SysRole.del_flag == 0)) \ .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() results = dict( user_basic_info=list_format_datetime(query_user_basic_info), diff --git a/dash-fastapi-backend/module_admin/entity/vo/cache_vo.py b/dash-fastapi-backend/module_admin/entity/vo/cache_vo.py index 1b2b4a1a7c21c7859f195b11beb36740d61f9952..18c23572c6b05359a19412d7d24881a78f282936 100644 --- a/dash-fastapi-backend/module_admin/entity/vo/cache_vo.py +++ b/dash-fastapi-backend/module_admin/entity/vo/cache_vo.py @@ -1,5 +1,5 @@ from pydantic import BaseModel -from typing import Optional, List +from typing import Optional, List, Any class CacheMonitorModel(BaseModel): @@ -9,3 +9,21 @@ class CacheMonitorModel(BaseModel): command_stats: Optional[List] db_size: Optional[int] info: Optional[dict] + + +class CacheInfoModel(BaseModel): + """ + 缓存监控对象对应pydantic模型 + """ + cache_key: Optional[str] + cache_name: Optional[str] + cache_value: Optional[Any] + remark: Optional[str] + + +class CrudCacheResponse(BaseModel): + """ + 操作缓存响应模型 + """ + is_success: bool + message: str diff --git a/dash-fastapi-backend/module_admin/service/cache_service.py b/dash-fastapi-backend/module_admin/service/cache_service.py index 08c4254f34b41327ed8e2869a82aeb7e8d6be314..1b0f92bfed50e7a57c8377ff67684e03d7af543d 100644 --- a/dash-fastapi-backend/module_admin/service/cache_service.py +++ b/dash-fastapi-backend/module_admin/service/cache_service.py @@ -1,5 +1,7 @@ from fastapi import Request from module_admin.entity.vo.cache_vo import * +from config.env import RedisInitKeyConfig +from config.get_redis import RedisUtil class CacheService: @@ -22,3 +24,95 @@ class CacheService: result = dict(command_stats=command_stats, db_size=db_size, info=info) return CacheMonitorModel(**result) + + @classmethod + def get_cache_monitor_cache_name_services(cls): + """ + 获取缓存名称列表信息service + :return: 缓存名称列表信息 + """ + name_list = [] + for attr_name in dir(RedisInitKeyConfig): + if not attr_name.startswith('__') and isinstance(getattr(RedisInitKeyConfig, attr_name), dict): + name_list.append( + CacheInfoModel( + cache_key="", + cache_name=getattr(RedisInitKeyConfig, attr_name).get('key'), + cache_value="", + remark=getattr(RedisInitKeyConfig, attr_name).get('remark') + ) + ) + + return name_list + + @classmethod + async def get_cache_monitor_cache_key_services(cls, request: Request, cache_name: str): + """ + 获取缓存键名列表信息service + :param request: Request对象 + :param cache_name: 缓存名称 + :return: 缓存键名列表信息 + """ + cache_keys = await request.app.state.redis.keys(f"{cache_name}*") + cache_key_list = [key.split(':', 1)[1] for key in cache_keys if key.startswith(f"{cache_name}:")] + + return cache_key_list + + @classmethod + async def get_cache_monitor_cache_value_services(cls, request: Request, cache_name: str, cache_key: str): + """ + 获取缓存内容信息service + :param request: Request对象 + :param cache_name: 缓存名称 + :param cache_key: 缓存键名 + :return: 缓存内容信息 + """ + cache_value = await request.app.state.redis.get(f"{cache_name}:{cache_key}") + + return CacheInfoModel(cache_key=cache_key, cache_name=cache_name, cache_value=cache_value, remark="") + + @classmethod + async def clear_cache_monitor_cache_name_services(cls, request: Request, cache_name: str): + """ + 清除缓存名称对应所有键值service + :param request: Request对象 + :param cache_name: 缓存名称 + :return: 操作缓存响应信息 + """ + cache_keys = await request.app.state.redis.keys(f"{cache_name}*") + if cache_keys: + await request.app.state.redis.delete(*cache_keys) + result = dict(is_success=True, message=f"{cache_name}对应键值清除成功") + + return CrudCacheResponse(**result) + + @classmethod + async def clear_cache_monitor_cache_key_services(cls, request: Request, cache_name: str, cache_key: str): + """ + 清除缓存名称对应所有键值service + :param request: Request对象 + :param cache_name: 缓存名称 + :param cache_key: 缓存键名 + :return: 操作缓存响应信息 + """ + await request.app.state.redis.delete(f"{cache_name}:{cache_key}") + result = dict(is_success=True, message=f"{cache_name}:{cache_key}清除成功") + + return CrudCacheResponse(**result) + + @classmethod + async def clear_cache_monitor_all_services(cls, request: Request): + """ + 清除所有缓存service + :param request: Request对象 + :return: 操作缓存响应信息 + """ + cache_keys = await request.app.state.redis.keys() + if cache_keys: + await request.app.state.redis.delete(*cache_keys) + + result = dict(is_success=True, message="所有缓存清除成功") + await RedisUtil.init_sys_dict(request.app.state.redis) + await RedisUtil.init_sys_config(request.app.state.redis) + + return CrudCacheResponse(**result) diff --git a/dash-fastapi-backend/module_admin/service/common_service.py b/dash-fastapi-backend/module_admin/service/common_service.py index 790b7f3eadf1f38f751b53b4f983200a1a77eb35..447f28add007cc13551c7f6dbe5b8d71e099c736 100644 --- a/dash-fastapi-backend/module_admin/service/common_service.py +++ b/dash-fastapi-backend/module_admin/service/common_service.py @@ -8,9 +8,9 @@ class CommonService: """ @classmethod - def upload_service(cls, path: str, upload_id: str, file: UploadFile): + def upload_service(cls, path: str, task_path: str, upload_id: str, file: UploadFile): - filepath = os.path.join(path, upload_id, f'{file.filename}') + filepath = os.path.join(path, task_path, upload_id, f'{file.filename}') with open(filepath, 'wb') as f: # 流式写出大型文件,这里的10代表10MB for chunk in iter(lambda: file.file.read(1024 * 1024 * 10), b''): diff --git a/dash-fastapi-backend/module_admin/service/config_service.py b/dash-fastapi-backend/module_admin/service/config_service.py index 1b3c48ebf34e244359d29dd843dc1c4947641a5e..3e9674a48db8fefe25080e8bebcfd4f5656b4e07 100644 --- a/dash-fastapi-backend/module_admin/service/config_service.py +++ b/dash-fastapi-backend/module_admin/service/config_service.py @@ -1,4 +1,5 @@ from fastapi import Request +from config.env import RedisInitKeyConfig from module_admin.entity.vo.config_vo import * from module_admin.dao.config_dao import * from utils.common_util import export_list2excel @@ -30,14 +31,14 @@ class ConfigService: :return: """ # 获取以sys_config:开头的键列表 - keys = await redis.keys('sys_config:*') + keys = await redis.keys(f"{RedisInitKeyConfig.SYS_CONFIG.get('key')}:*") # 删除匹配的键 if keys: await redis.delete(*keys) config_all = ConfigDao.get_config_list(result_db, ConfigQueryModel(**dict())) for config_obj in config_all: if config_obj.config_type == 'Y': - await redis.set(f'sys_config:{config_obj.config_key}', config_obj.config_value) + await redis.set(f"{RedisInitKeyConfig.SYS_CONFIG.get('key')}:{config_obj.config_key}", config_obj.config_value) @classmethod async def query_config_list_from_cache_services(cls, redis, config_key: str): @@ -47,7 +48,7 @@ class ConfigService: :param config_key: 参数键名 :return: 参数键名对应值 """ - result = await redis.get(f'sys_config:{config_key}') + result = await redis.get(f"{RedisInitKeyConfig.SYS_CONFIG.get('key')}:{config_key}") return result diff --git a/dash-fastapi-backend/module_admin/service/dept_service.py b/dash-fastapi-backend/module_admin/service/dept_service.py index d2ca651429ccdbe265dfa90ba42b173548376bda..0be3d4a4a123a45fe1bed07d31273ad64a5e43a7 100644 --- a/dash-fastapi-backend/module_admin/service/dept_service.py +++ b/dash-fastapi-backend/module_admin/service/dept_service.py @@ -8,40 +8,43 @@ class DeptService: """ @classmethod - def get_dept_tree_services(cls, result_db: Session, page_object: DeptModel): + def get_dept_tree_services(cls, result_db: Session, page_object: DeptModel, data_scope_sql: str): """ 获取部门树信息service :param result_db: orm对象 :param page_object: 查询参数对象 + :param data_scope_sql: 数据权限对应的查询sql语句 :return: 部门树信息对象 """ - dept_list_result = DeptDao.get_dept_list_for_tree(result_db, page_object) - dept_tree_result = cls.get_dept_tree(0, DeptTree(dept_tree=dept_list_result)) + dept_list_result = DeptDao.get_dept_list_for_tree(result_db, page_object, data_scope_sql) + dept_tree_result = cls.list_to_tree(dept_list_result) return dept_tree_result @classmethod - def get_dept_tree_for_edit_option_services(cls, result_db: Session, page_object: DeptModel): + def get_dept_tree_for_edit_option_services(cls, result_db: Session, page_object: DeptModel, data_scope_sql: str): """ 获取部门编辑部门树信息service :param result_db: orm对象 :param page_object: 查询参数对象 + :param data_scope_sql: 数据权限对应的查询sql语句 :return: 部门树信息对象 """ - dept_list_result = DeptDao.get_dept_info_for_edit_option(result_db, page_object) - dept_tree_result = cls.get_dept_tree(0, DeptTree(dept_tree=dept_list_result)) + dept_list_result = DeptDao.get_dept_info_for_edit_option(result_db, page_object, data_scope_sql) + dept_tree_result = cls.list_to_tree(dept_list_result) return dept_tree_result @classmethod - def get_dept_list_services(cls, result_db: Session, page_object: DeptModel): + def get_dept_list_services(cls, result_db: Session, page_object: DeptModel, data_scope_sql: str): """ 获取部门列表信息service :param result_db: orm对象 :param page_object: 分页查询参数对象 + :param data_scope_sql: 数据权限对应的查询sql语句 :return: 部门列表信息对象 """ - dept_list_result = DeptDao.get_dept_list(result_db, page_object) + dept_list_result = DeptDao.get_dept_list(result_db, page_object, data_scope_sql) return dept_list_result @@ -154,6 +157,34 @@ class DeptService: return dept + @classmethod + def list_to_tree(cls, permission_list: list) -> list: + """ + 工具方法:根据部门列表信息生成树形嵌套数据 + :param permission_list: 部门列表信息 + :return: 部门树形嵌套数据 + """ + permission_list = [dict(title=item.dept_name, key=str(item.dept_id), value=str(item.dept_id), parent_id=str(item.parent_id)) for item in permission_list] + # 转成dept_id为key的字典 + mapping: dict = dict(zip([i['key'] for i in permission_list], permission_list)) + + # 树容器 + container: list = [] + + for d in permission_list: + # 如果找不到父级项,则是根节点 + parent: dict = mapping.get(d['parent_id']) + if parent is None: + container.append(d) + else: + children: list = parent.get('children') + if not children: + children = [] + children.append(d) + parent.update({'children': children}) + + return container + @classmethod def get_dept_tree(cls, pid: int, permission_list: DeptTree): """ diff --git a/dash-fastapi-backend/module_admin/service/dict_service.py b/dash-fastapi-backend/module_admin/service/dict_service.py index e201a04d251625064d275054750a0564cfedcf70..e557b2f9bb68d37af0967f79a6ef0553cf3d7558 100644 --- a/dash-fastapi-backend/module_admin/service/dict_service.py +++ b/dash-fastapi-backend/module_admin/service/dict_service.py @@ -1,5 +1,6 @@ from fastapi import Request import json +from config.env import RedisInitKeyConfig from module_admin.entity.vo.dict_vo import * from module_admin.dao.dict_dao import * from utils.common_util import export_list2excel @@ -215,7 +216,7 @@ class DictDataService: :return: """ # 获取以sys_dict:开头的键列表 - keys = await redis.keys('sys_dict:*') + keys = await redis.keys(f"{RedisInitKeyConfig.SYS_DICT.get('key')}:*") # 删除匹配的键 if keys: await redis.delete(*keys) @@ -224,7 +225,7 @@ class DictDataService: dict_type = dict_type_obj.dict_type dict_data_list = DictDataDao.query_dict_data_list(result_db, dict_type) dict_data = [DictDataModel(**vars(row)).dict() for row in dict_data_list if row] - await redis.set(f'sys_dict:{dict_type}', json.dumps(dict_data, ensure_ascii=False)) + await redis.set(f"{RedisInitKeyConfig.SYS_DICT.get('key')}:{dict_type}", json.dumps(dict_data, ensure_ascii=False)) @classmethod async def query_dict_data_list_from_cache_services(cls, redis, dict_type: str): @@ -235,7 +236,7 @@ class DictDataService: :return: 字典数据列表信息对象 """ result = [] - dict_data_list_result = await redis.get(f'sys_dict:{dict_type}') + dict_data_list_result = await redis.get(f"{RedisInitKeyConfig.SYS_DICT.get('key')}:{dict_type}") if dict_data_list_result: result = json.loads(dict_data_list_result) diff --git a/dash-fastapi-backend/module_admin/service/login_service.py b/dash-fastapi-backend/module_admin/service/login_service.py index 91eda4f9e85a0ca6c0dd1c2952c14e29336d8966..7a2f71b2e791b7de04f3b49e459027560ba261e0 100644 --- a/dash-fastapi-backend/module_admin/service/login_service.py +++ b/dash-fastapi-backend/module_admin/service/login_service.py @@ -11,7 +11,7 @@ from module_admin.entity.vo.login_vo import * from module_admin.dao.login_dao import * from module_admin.service.user_service import UserService from module_admin.dao.user_dao import * -from config.env import JwtConfig +from config.env import JwtConfig, RedisInitKeyConfig from utils.pwd_util import * from utils.response_util import * from utils.message_util import * @@ -73,13 +73,13 @@ async def get_current_user(request: Request = Request, token: str = Depends(oaut if user is None: logger.warning("用户token不合法") raise AuthException(data="", message="用户token不合法") - redis_token = await request.app.state.redis.get(f'access_token:{session_id}') + redis_token = await request.app.state.redis.get(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{session_id}") # 此方法可实现同一账号同一时间只能登录一次 - # redis_token = await request.app.state.redis.get(f'access_token:{user.user_basic_info[0].user_id}') + # redis_token = await request.app.state.redis.get(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{user.user_basic_info[0].user_id}") if token == redis_token: - await request.app.state.redis.set(f'access_token:{session_id}', redis_token, + await request.app.state.redis.set(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{session_id}", redis_token, ex=timedelta(minutes=JwtConfig.REDIS_TOKEN_EXPIRE_MINUTES)) - # await request.app.state.redis.set(f'access_token:{user.user_basic_info[0].user_id}', redis_token, + # await request.app.state.redis.set(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{user.user_basic_info[0].user_id}", redis_token, # ex=timedelta(minutes=JwtConfig.REDIS_TOKEN_EXPIRE_MINUTES)) return CurrentUserInfoServiceResponse( @@ -102,14 +102,14 @@ async def get_sms_code_services(request: Request, result_db: Session, user: Rese :param user: 用户对象 :return: 短信验证码对象 """ - redis_sms_result = await request.app.state.redis.get(f"sms_code:{user.session_id}") + redis_sms_result = await request.app.state.redis.get(f"{RedisInitKeyConfig.SMS_CODE.get('key')}:{user.session_id}") if redis_sms_result: return SmsCode(**dict(is_success=False, sms_code='', session_id='', message='短信验证码仍在有效期内')) is_user = UserDao.get_user_by_name(result_db, user.user_name) if is_user: sms_code = str(random.randint(100000, 999999)) session_id = str(uuid.uuid4()) - await request.app.state.redis.set(f"sms_code:{session_id}", sms_code, ex=timedelta(minutes=2)) + await request.app.state.redis.set(f"{RedisInitKeyConfig.SMS_CODE.get('key')}:{session_id}", sms_code, ex=timedelta(minutes=2)) # 此处模拟调用短信服务 message_service(sms_code) @@ -126,7 +126,7 @@ async def forget_user_services(request: Request, result_db: Session, forget_user :param forget_user: 重置用户对象 :return: 重置结果 """ - redis_sms_result = await request.app.state.redis.get(f"sms_code:{forget_user.session_id}") + redis_sms_result = await request.app.state.redis.get(f"{RedisInitKeyConfig.SMS_CODE.get('key')}:{forget_user.session_id}") if forget_user.sms_code == redis_sms_result: forget_user.password = PwdUtil.get_password_hash(forget_user.password) forget_user.user_id = UserDao.get_user_by_name(result_db, forget_user.user_name).user_id @@ -135,7 +135,7 @@ async def forget_user_services(request: Request, result_db: Session, forget_user elif not redis_sms_result: result = dict(is_success=False, message='短信验证码已过期') else: - await request.app.state.redis.delete(f"sms_code:{forget_user.session_id}") + await request.app.state.redis.delete(f"{RedisInitKeyConfig.SMS_CODE.get('key')}:{forget_user.session_id}") result = dict(is_success=False, message='短信验证码不正确') return CrudUserResponse(**result) @@ -148,7 +148,7 @@ async def logout_services(request: Request, session_id: str): :param session_id: 会话编号 :return: 退出登录结果 """ - await request.app.state.redis.delete(f'access_token:{session_id}') + await request.app.state.redis.delete(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{session_id}") # await request.app.state.redis.delete(f'{current_user.user.user_id}_access_token') # await request.app.state.redis.delete(f'{current_user.user.user_id}_session_id') @@ -162,7 +162,7 @@ async def check_login_captcha(request: Request, login_user: UserLogin): :param login_user: 登录用户对象 :return: 校验结果 """ - captcha_value = await request.app.state.redis.get(f'captcha_codes:{login_user.session_id}') + captcha_value = await request.app.state.redis.get(f"{RedisInitKeyConfig.CAPTCHA_CODES.get('key')}:{login_user.session_id}") if not captcha_value: logger.warning("验证码已失效") raise LoginException(data="", message="验证码已失效") @@ -180,7 +180,7 @@ async def authenticate_user(request: Request, query_db: Session, login_user: Use :param login_user: 登录用户对象 :return: 校验结果 """ - account_lock = await request.app.state.redis.get(f"account_lock:{login_user.user_name}") + account_lock = await request.app.state.redis.get(f"{RedisInitKeyConfig.ACCOUNT_LOCK.get('key')}:{login_user.user_name}") if login_user.user_name == account_lock: logger.warning("账号已锁定,请稍后再试") raise LoginException(data="", message="账号已锁定,请稍后再试") @@ -192,16 +192,16 @@ async def authenticate_user(request: Request, query_db: Session, login_user: Use logger.warning("用户不存在") raise LoginException(data="", message="用户不存在") if not PwdUtil.verify_password(login_user.password, user[0].password): - cache_password_error_count = await request.app.state.redis.get(f"password_error_count:{login_user.user_name}") + cache_password_error_count = await request.app.state.redis.get(f"{RedisInitKeyConfig.PASSWORD_ERROR_COUNT.get('key')}:{login_user.user_name}") password_error_counted = 0 if cache_password_error_count: password_error_counted = cache_password_error_count password_error_count = int(password_error_counted) + 1 - await request.app.state.redis.set(f"password_error_count:{login_user.user_name}", password_error_count, + await request.app.state.redis.set(f"{RedisInitKeyConfig.PASSWORD_ERROR_COUNT.get('key')}:{login_user.user_name}", password_error_count, ex=timedelta(minutes=10)) if password_error_count > 5: - await request.app.state.redis.delete(f"password_error_count:{login_user.user_name}") - await request.app.state.redis.set(f"account_lock:{login_user.user_name}", login_user.user_name, + await request.app.state.redis.delete(f"{RedisInitKeyConfig.PASSWORD_ERROR_COUNT.get('key')}:{login_user.user_name}") + await request.app.state.redis.set(f"{RedisInitKeyConfig.ACCOUNT_LOCK.get('key')}:{login_user.user_name}", login_user.user_name, ex=timedelta(minutes=10)) logger.warning("10分钟内密码已输错超过5次,账号已锁定,请10分钟后再试") raise LoginException(data="", message="10分钟内密码已输错超过5次,账号已锁定,请10分钟后再试") @@ -210,7 +210,7 @@ async def authenticate_user(request: Request, query_db: Session, login_user: Use if user[0].status == '1': logger.warning("用户已停用") raise LoginException(data="", message="用户已停用") - await request.app.state.redis.delete(f"password_error_count:{login_user.user_name}") + await request.app.state.redis.delete(f"{RedisInitKeyConfig.PASSWORD_ERROR_COUNT.get('key')}:{login_user.user_name}") return user diff --git a/dash-fastapi-backend/module_admin/service/online_service.py b/dash-fastapi-backend/module_admin/service/online_service.py index 902acdffabd5c2d5fafb333857e744d8219fdfa8..47277ea8b58af8a36751abc9bd3e738d9d24a3d4 100644 --- a/dash-fastapi-backend/module_admin/service/online_service.py +++ b/dash-fastapi-backend/module_admin/service/online_service.py @@ -1,6 +1,6 @@ from fastapi import Request from jose import jwt -from config.env import JwtConfig +from config.env import JwtConfig, RedisInitKeyConfig from module_admin.entity.vo.online_vo import * @@ -17,7 +17,7 @@ class OnlineService: :param query_object: 查询参数对象 :return: 在线用户列表信息 """ - access_token_keys = await request.app.state.redis.keys('access_token*') + access_token_keys = await request.app.state.redis.keys(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}*") if not access_token_keys: access_token_keys = [] access_token_values_list = [await request.app.state.redis.get(key) for key in access_token_keys] @@ -62,7 +62,7 @@ class OnlineService: if page_object.session_ids.split(','): session_id_list = page_object.session_ids.split(',') for session_id in session_id_list: - await request.app.state.redis.delete(f'access_token:{session_id}') + await request.app.state.redis.delete(f"{RedisInitKeyConfig.ACCESS_TOKEN.get('key')}:{session_id}") result = dict(is_success=True, message='强退成功') else: result = dict(is_success=False, message='传入session_id为空') diff --git a/dash-fastapi-backend/sql/dash-fastapi.sql b/dash-fastapi-backend/sql/dash-fastapi.sql index 4c3bbe9d952f4093ffc09afdc458b6b3603fbefd..2699e7e2243d12a68681e6c880611399b4026015 100644 --- a/dash-fastapi-backend/sql/dash-fastapi.sql +++ b/dash-fastapi-backend/sql/dash-fastapi.sql @@ -23,27 +23,27 @@ SET FOREIGN_KEY_CHECKS = 0; DROP TABLE IF EXISTS `gen_table`; CREATE TABLE `gen_table` ( `table_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号', - `table_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '表名称', - `table_comment` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '表描述', - `sub_table_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '关联子表的表名', - `sub_table_fk_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '子表关联的外键名', - `class_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '实体类名称', - `tpl_category` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT 'crud' COMMENT '使用的模板(crud单表操作 tree树表操作)', - `package_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '生成包路径', - `module_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '生成模块名', - `business_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '生成业务名', - `function_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '生成功能名', - `function_author` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '生成功能作者', - `gen_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '生成代码方式(0zip压缩包 1自定义路径)', - `gen_path` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '/' COMMENT '生成路径(不填默认项目路径)', - `options` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '其它生成选项', - `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `table_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '表名称', + `table_comment` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '表描述', + `sub_table_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '关联子表的表名', + `sub_table_fk_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '子表关联的外键名', + `class_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '实体类名称', + `tpl_category` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT 'crud' COMMENT '使用的模板(crud单表操作 tree树表操作)', + `package_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '生成包路径', + `module_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '生成模块名', + `business_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '生成业务名', + `function_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '生成功能名', + `function_author` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '生成功能作者', + `gen_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '生成代码方式(0zip压缩包 1自定义路径)', + `gen_path` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '/' COMMENT '生成路径(不填默认项目路径)', + `options` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '其它生成选项', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', - `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者', `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', - `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注', PRIMARY KEY (`table_id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '代码生成业务表' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '代码生成业务表' ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of gen_table @@ -55,29 +55,29 @@ CREATE TABLE `gen_table` ( DROP TABLE IF EXISTS `gen_table_column`; CREATE TABLE `gen_table_column` ( `column_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号', - `table_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '归属表编号', - `column_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '列名称', - `column_comment` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '列描述', - `column_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '列类型', - `java_type` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'JAVA类型', - `java_field` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'JAVA字段名', - `is_pk` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否主键(1是)', - `is_increment` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否自增(1是)', - `is_required` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否必填(1是)', - `is_insert` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否为插入字段(1是)', - `is_edit` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否编辑字段(1是)', - `is_list` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否列表字段(1是)', - `is_query` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否查询字段(1是)', - `query_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT 'EQ' COMMENT '查询方式(等于、不等于、大于、小于、范围)', - `html_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '显示类型(文本框、文本域、下拉框、复选框、单选框、日期控件)', - `dict_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '字典类型', + `table_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '归属表编号', + `column_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '列名称', + `column_comment` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '列描述', + `column_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '列类型', + `java_type` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'JAVA类型', + `java_field` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'JAVA字段名', + `is_pk` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '是否主键(1是)', + `is_increment` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '是否自增(1是)', + `is_required` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '是否必填(1是)', + `is_insert` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '是否为插入字段(1是)', + `is_edit` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '是否编辑字段(1是)', + `is_list` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '是否列表字段(1是)', + `is_query` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '是否查询字段(1是)', + `query_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT 'EQ' COMMENT '查询方式(等于、不等于、大于、小于、范围)', + `html_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '显示类型(文本框、文本域、下拉框、复选框、单选框、日期控件)', + `dict_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '字典类型', `sort` int(11) NULL DEFAULT NULL COMMENT '排序', - `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', - `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者', `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`column_id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 26 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '代码生成业务表字段' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 26 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '代码生成业务表字段' ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of gen_table_column @@ -89,17 +89,17 @@ CREATE TABLE `gen_table_column` ( DROP TABLE IF EXISTS `sys_config`; CREATE TABLE `sys_config` ( `config_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '参数主键', - `config_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '参数名称', - `config_key` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '参数键名', - `config_value` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '参数键值', - `config_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT 'N' COMMENT '系统内置(Y是 N否)', - `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `config_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '参数名称', + `config_key` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '参数键名', + `config_value` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '参数键值', + `config_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT 'N' COMMENT '系统内置(Y是 N否)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', - `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者', `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', - `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注', PRIMARY KEY (`config_id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 101 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '参数配置表' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 101 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '参数配置表' ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of sys_config @@ -116,20 +116,20 @@ DROP TABLE IF EXISTS `sys_dept`; CREATE TABLE `sys_dept` ( `dept_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '部门id', `parent_id` bigint(20) NULL DEFAULT 0 COMMENT '父部门id', - `ancestors` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '祖级列表', - `dept_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '部门名称', + `ancestors` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '祖级列表', + `dept_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '部门名称', `order_num` int(11) NULL DEFAULT 0 COMMENT '显示顺序', - `leader` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '负责人', - `phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '联系电话', - `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '邮箱', - `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '部门状态(0正常 1停用)', - `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)', - `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `leader` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '负责人', + `phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '联系电话', + `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '邮箱', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '部门状态(0正常 1停用)', + `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', - `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者', `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`dept_id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 201 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '部门表' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 201 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '部门表' ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of sys_dept @@ -239,23 +239,23 @@ INSERT INTO `sys_dict_type` VALUES (10, '系统状态', 'sys_common_status', '0' DROP TABLE IF EXISTS `sys_job`; CREATE TABLE `sys_job` ( `job_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '任务ID', - `job_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '任务名称', - `job_group` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'default' COMMENT '任务组名', - `job_executor` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'default' COMMENT '任务执行器', - `invoke_target` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调用目标字符串', - `job_args` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '位置参数', - `job_kwargs` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '关键字参数', - `cron_expression` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT 'cron执行表达式', - `misfire_policy` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '3' COMMENT '计划执行错误策略(1立即执行 2执行一次 3放弃执行)', - `concurrent` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '1' COMMENT '是否并发执行(0允许 1禁止)', - `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '状态(0正常 1暂停)', - `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `job_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '任务名称', + `job_group` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'default' COMMENT '任务组名', + `job_executor` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'default' COMMENT '任务执行器', + `invoke_target` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '调用目标字符串', + `job_args` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '位置参数', + `job_kwargs` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '关键字参数', + `cron_expression` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT 'cron执行表达式', + `misfire_policy` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '3' COMMENT '计划执行错误策略(1立即执行 2执行一次 3放弃执行)', + `concurrent` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '1' COMMENT '是否并发执行(0允许 1禁止)', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '状态(0正常 1暂停)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', - `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者', `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', - `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '备注信息', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '备注信息', PRIMARY KEY (`job_id`, `job_name`, `job_group`, `job_executor`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 100 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '定时任务调度表' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 100 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '定时任务调度表' ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of sys_job @@ -270,19 +270,19 @@ INSERT INTO `sys_job` VALUES (3, '系统默认(多参)', 'redis', 'default', DROP TABLE IF EXISTS `sys_job_log`; CREATE TABLE `sys_job_log` ( `job_log_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '任务日志ID', - `job_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '任务名称', - `job_group` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '任务组名', - `job_executor` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '任务执行器', - `invoke_target` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调用目标字符串', - `job_args` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '位置参数', - `job_kwargs` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '关键字参数', - `job_trigger` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '任务触发器', - `job_message` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '日志信息', - `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '执行状态(0正常 1失败)', - `exception_info` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '异常信息', + `job_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '任务名称', + `job_group` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '任务组名', + `job_executor` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '任务执行器', + `invoke_target` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '调用目标字符串', + `job_args` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '位置参数', + `job_kwargs` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '关键字参数', + `job_trigger` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '任务触发器', + `job_message` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '日志信息', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '执行状态(0正常 1失败)', + `exception_info` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '异常信息', `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', PRIMARY KEY (`job_log_id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '定时任务调度日志表' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '定时任务调度日志表' ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of sys_job_log @@ -294,18 +294,18 @@ CREATE TABLE `sys_job_log` ( DROP TABLE IF EXISTS `sys_logininfor`; CREATE TABLE `sys_logininfor` ( `info_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '访问ID', - `user_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '用户账号', - `ipaddr` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '登录IP地址', - `login_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '登录地点', - `browser` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '浏览器类型', - `os` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '操作系统', - `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '登录状态(0成功 1失败)', - `msg` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '提示消息', + `user_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '用户账号', + `ipaddr` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '登录IP地址', + `login_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '登录地点', + `browser` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '浏览器类型', + `os` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '操作系统', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '登录状态(0成功 1失败)', + `msg` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '提示消息', `login_time` datetime(0) NULL DEFAULT NULL COMMENT '访问时间', PRIMARY KEY (`info_id`) USING BTREE, INDEX `idx_sys_logininfor_s`(`status`) USING BTREE, INDEX `idx_sys_logininfor_lt`(`login_time`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '系统访问记录' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统访问记录' ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of sys_logininfor @@ -317,26 +317,26 @@ CREATE TABLE `sys_logininfor` ( DROP TABLE IF EXISTS `sys_menu`; CREATE TABLE `sys_menu` ( `menu_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '菜单ID', - `menu_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '菜单名称', + `menu_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '菜单名称', `parent_id` bigint(20) NULL DEFAULT 0 COMMENT '父菜单ID', `order_num` int(11) NULL DEFAULT 0 COMMENT '显示顺序', - `path` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '路由地址', - `component` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '组件路径', - `query` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '路由参数', + `path` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '路由地址', + `component` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '组件路径', + `query` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '路由参数', `is_frame` int(11) NULL DEFAULT 1 COMMENT '是否为外链(0是 1否)', `is_cache` int(11) NULL DEFAULT 0 COMMENT '是否缓存(0缓存 1不缓存)', - `menu_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '菜单类型(M目录 C菜单 F按钮)', - `visible` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '菜单状态(0显示 1隐藏)', - `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '菜单状态(0正常 1停用)', - `perms` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '权限标识', - `icon` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '#' COMMENT '菜单图标', - `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `menu_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '菜单类型(M目录 C菜单 F按钮)', + `visible` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '菜单状态(0显示 1隐藏)', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '菜单状态(0正常 1停用)', + `perms` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '权限标识', + `icon` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '#' COMMENT '菜单图标', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', - `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者', `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', - `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '备注', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '备注', PRIMARY KEY (`menu_id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 2000 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '菜单权限表' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 2000 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '菜单权限表' ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of sys_menu @@ -433,17 +433,17 @@ INSERT INTO `sys_menu` VALUES (1060, '生成代码', 116, 6, '#', '', '', 1, 0, DROP TABLE IF EXISTS `sys_notice`; CREATE TABLE `sys_notice` ( `notice_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '公告ID', - `notice_title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '公告标题', - `notice_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '公告类型(1通知 2公告)', + `notice_title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '公告标题', + `notice_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '公告类型(1通知 2公告)', `notice_content` longblob NULL COMMENT '公告内容', - `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '公告状态(0正常 1关闭)', - `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '公告状态(0正常 1关闭)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', - `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者', `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', - `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注', PRIMARY KEY (`notice_id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '通知公告表' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '通知公告表' ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of sys_notice @@ -457,27 +457,27 @@ INSERT INTO `sys_notice` VALUES (2, '维护通知:2018-07-01 若依系统凌 DROP TABLE IF EXISTS `sys_oper_log`; CREATE TABLE `sys_oper_log` ( `oper_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '日志主键', - `title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '模块标题', + `title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '模块标题', `business_type` int(11) NULL DEFAULT 0 COMMENT '业务类型(0其它 1新增 2修改 3删除)', - `method` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '方法名称', - `request_method` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '请求方式', + `method` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '方法名称', + `request_method` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '请求方式', `operator_type` int(11) NULL DEFAULT 0 COMMENT '操作类别(0其它 1后台用户 2手机端用户)', - `oper_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '操作人员', - `dept_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '部门名称', - `oper_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '请求URL', - `oper_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '主机地址', - `oper_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '操作地点', - `oper_param` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '请求参数', - `json_result` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '返回参数', + `oper_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '操作人员', + `dept_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '部门名称', + `oper_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '请求URL', + `oper_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '主机地址', + `oper_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '操作地点', + `oper_param` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '请求参数', + `json_result` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '返回参数', `status` int(11) NULL DEFAULT 0 COMMENT '操作状态(0正常 1异常)', - `error_msg` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '错误消息', + `error_msg` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '错误消息', `oper_time` datetime(0) NULL DEFAULT NULL COMMENT '操作时间', `cost_time` bigint(20) NULL DEFAULT 0 COMMENT '消耗时间', PRIMARY KEY (`oper_id`) USING BTREE, INDEX `idx_sys_oper_log_bt`(`business_type`) USING BTREE, INDEX `idx_sys_oper_log_s`(`status`) USING BTREE, INDEX `idx_sys_oper_log_ot`(`oper_time`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '操作日志记录' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '操作日志记录' ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of sys_oper_log @@ -489,17 +489,17 @@ CREATE TABLE `sys_oper_log` ( DROP TABLE IF EXISTS `sys_post`; CREATE TABLE `sys_post` ( `post_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '岗位ID', - `post_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '岗位编码', - `post_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '岗位名称', + `post_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '岗位编码', + `post_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '岗位名称', `post_sort` int(11) NOT NULL COMMENT '显示顺序', - `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '状态(0正常 1停用)', - `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '状态(0正常 1停用)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', - `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者', `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', - `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注', PRIMARY KEY (`post_id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '岗位信息表' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '岗位信息表' ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of sys_post @@ -515,21 +515,21 @@ INSERT INTO `sys_post` VALUES (4, 'user', '普通员工', 4, '0', 'admin', '2023 DROP TABLE IF EXISTS `sys_role`; CREATE TABLE `sys_role` ( `role_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '角色ID', - `role_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色名称', - `role_key` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色权限字符串', + `role_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '角色名称', + `role_key` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '角色权限字符串', `role_sort` int(11) NOT NULL COMMENT '显示顺序', - `data_scope` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '1' COMMENT '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)', + `data_scope` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '1' COMMENT '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)', `menu_check_strictly` tinyint(1) NULL DEFAULT 1 COMMENT '菜单树选择项是否关联显示', `dept_check_strictly` tinyint(1) NULL DEFAULT 1 COMMENT '部门树选择项是否关联显示', - `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色状态(0正常 1停用)', - `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)', - `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '角色状态(0正常 1停用)', + `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', - `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者', `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', - `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注', PRIMARY KEY (`role_id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 100 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '角色信息表' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 100 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '角色信息表' ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of sys_role @@ -545,7 +545,7 @@ CREATE TABLE `sys_role_dept` ( `role_id` bigint(20) NOT NULL COMMENT '角色ID', `dept_id` bigint(20) NOT NULL COMMENT '部门ID', PRIMARY KEY (`role_id`, `dept_id`) USING BTREE -) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '角色和部门关联表' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '角色和部门关联表' ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of sys_role_dept @@ -562,7 +562,7 @@ CREATE TABLE `sys_role_menu` ( `role_id` bigint(20) NOT NULL COMMENT '角色ID', `menu_id` bigint(20) NOT NULL COMMENT '菜单ID', PRIMARY KEY (`role_id`, `menu_id`) USING BTREE -) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '角色和菜单关联表' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '角色和菜单关联表' ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of sys_role_menu @@ -660,31 +660,31 @@ DROP TABLE IF EXISTS `sys_user`; CREATE TABLE `sys_user` ( `user_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用户ID', `dept_id` bigint(20) NULL DEFAULT NULL COMMENT '部门ID', - `user_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户账号', - `nick_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户昵称', - `user_type` varchar(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '00' COMMENT '用户类型(00系统用户)', - `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '用户邮箱', - `phonenumber` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '手机号码', - `sex` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '用户性别(0男 1女 2未知)', - `avatar` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '头像地址', - `password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '密码', - `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '帐号状态(0正常 1停用)', - `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)', - `login_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '最后登录IP', + `user_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户账号', + `nick_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用户昵称', + `user_type` varchar(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '00' COMMENT '用户类型(00系统用户)', + `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '用户邮箱', + `phonenumber` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '手机号码', + `sex` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '用户性别(0男 1女 2未知)', + `avatar` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '头像地址', + `password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '密码', + `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '帐号状态(0正常 1停用)', + `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)', + `login_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '最后登录IP', `login_date` datetime(0) NULL DEFAULT NULL COMMENT '最后登录时间', - `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者', + `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', - `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者', + `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者', `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', - `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注', + `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '备注', PRIMARY KEY (`user_id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 100 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '用户信息表' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB AUTO_INCREMENT = 100 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户信息表' ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of sys_user -- ---------------------------- -INSERT INTO `sys_user` VALUES (1, 103, 'admin', '超级管理员', '00', 'niangao@163.com', '18888888888', '1', 'http://127.0.0.1:9099/common/caches?taskId=avatar&filename=admin_avatar.jpeg', '$2b$12$dW/S5ummJs3Z5fMXqsesWuJgTimgtpK85L0zFhUAuFmHDznII/F66', '0', '0', '127.0.0.1', '2023-05-23 16:13:33', 'admin', '2023-05-23 16:13:33', 'admin', '2023-05-23 16:13:33', '管理员'); -INSERT INTO `sys_user` VALUES (2, 105, 'niangao', '年糕', '00', 'niangao@qq.com', '16688888888', '0', 'http://127.0.0.1:9099/common/caches?taskId=avatar&filename=ry_avatar.jpeg', '$2b$12$UkNwXNmyQ2RbS1BROXmCRelWLkEgKWQmVsY1S9O1/nZpUSPud1Oz2', '0', '0', '127.0.0.1', '2023-05-23 16:13:33', 'admin', '2023-05-23 16:13:33', 'admin', '2023-05-23 16:13:33', '测试员'); +INSERT INTO `sys_user` VALUES (1, 103, 'admin', '超级管理员', '00', 'niangao@163.com', '18888888888', '1', '/common/caches?taskPath=avatar&taskId=admin&filename=admin_avatar.jpeg', '$2b$12$dW/S5ummJs3Z5fMXqsesWuJgTimgtpK85L0zFhUAuFmHDznII/F66', '0', '0', '127.0.0.1', '2023-05-23 16:13:33', 'admin', '2023-05-23 16:13:33', 'admin', '2023-05-23 16:13:33', '管理员'); +INSERT INTO `sys_user` VALUES (2, 105, 'niangao', '年糕', '00', 'niangao@qq.com', '16688888888', '0', '/common/caches?taskPath=avatar&taskId=ry&filename=ry_avatar.jpeg', '$2b$12$UkNwXNmyQ2RbS1BROXmCRelWLkEgKWQmVsY1S9O1/nZpUSPud1Oz2', '0', '0', '127.0.0.1', '2023-05-23 16:13:33', 'admin', '2023-05-23 16:13:33', 'admin', '2023-05-23 16:13:33', '测试员'); -- ---------------------------- -- Table structure for sys_user_post @@ -694,7 +694,7 @@ CREATE TABLE `sys_user_post` ( `user_id` bigint(20) NOT NULL COMMENT '用户ID', `post_id` bigint(20) NOT NULL COMMENT '岗位ID', PRIMARY KEY (`user_id`, `post_id`) USING BTREE -) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '用户与岗位关联表' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户与岗位关联表' ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of sys_user_post @@ -710,7 +710,7 @@ CREATE TABLE `sys_user_role` ( `user_id` bigint(20) NOT NULL COMMENT '用户ID', `role_id` bigint(20) NOT NULL COMMENT '角色ID', PRIMARY KEY (`user_id`, `role_id`) USING BTREE -) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '用户和角色关联表' ROW_FORMAT = Dynamic; +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户和角色关联表' ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of sys_user_role diff --git a/dash-fastapi-backend/utils/common_util.py b/dash-fastapi-backend/utils/common_util.py index 1cf60f608d6989dc20de497bf53b46c3732c8e26..b1e8233daafb0260396721017a672a0c05869935 100644 --- a/dash-fastapi-backend/utils/common_util.py +++ b/dash-fastapi-backend/utils/common_util.py @@ -142,6 +142,7 @@ def get_filepath_from_url(url: str): file_info = url.split("?")[1].split("&") task_id = file_info[0].split("=")[1] file_name = file_info[1].split("=")[1] - filepath = os.path.join(CachePathConfig.PATH, task_id, file_name) + task_path = file_info[2].split("=")[1] + filepath = os.path.join(CachePathConfig.PATH, task_path, task_id, file_name) return filepath diff --git a/dash-fastapi-backend/utils/response_util.py b/dash-fastapi-backend/utils/response_util.py index cf0e8ba904fe041a958d7d31c717c3ca0dc6130f..4ac66e30fac59e9d9a2f60eac87fac5d59bdd33e 100644 --- a/dash-fastapi-backend/utils/response_util.py +++ b/dash-fastapi-backend/utils/response_util.py @@ -50,6 +50,21 @@ def response_401(*, data: Any = None, message: str = "获取失败") -> Response ) +def response_403(*, data: Any = None, message: str = "获取失败") -> Response: + return JSONResponse( + status_code=status.HTTP_403_FORBIDDEN, + content=jsonable_encoder( + { + 'code': 403, + 'message': message, + 'data': data, + 'success': 'false', + 'time': datetime.now().strftime("%Y-%m-%d %H:%M:%S") + } + ) + ) + + def response_500(*, data: Any = None, message: str = "接口异常") -> Response: return JSONResponse( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, @@ -81,6 +96,15 @@ class AuthException(Exception): self.message = message +class PermissionException(Exception): + """ + 自定义权限异常PermissionException + """ + def __init__(self, data: str = None, message: str = None): + self.data = data + self.message = message + + class LoginException(Exception): """ 自定义登录异常LoginException diff --git a/dash-fastapi-frontend/api/cache.py b/dash-fastapi-frontend/api/cache.py index 2cb2d2bbd8e2d380dfc6a129c6b4bae2fdf21ce8..a29a58a99ae3388e88722439410b7a6ea29db84f 100644 --- a/dash-fastapi-frontend/api/cache.py +++ b/dash-fastapi-frontend/api/cache.py @@ -4,3 +4,33 @@ from utils.request import api_request def get_cache_statistical_info_api(): return api_request(method='post', url='/monitor/cache/statisticalInfo', is_headers=True) + + +def get_cache_name_list_api(): + + return api_request(method='post', url='/monitor/cache/getNames', is_headers=True) + + +def get_cache_key_list_api(cache_name: str): + + return api_request(method='post', url=f'/monitor/cache/getKeys/{cache_name}', is_headers=True) + + +def get_cache_value_api(cache_name: str, cache_key: str): + + return api_request(method='post', url=f'/monitor/cache/getValue/{cache_name}/{cache_key}', is_headers=True) + + +def clear_cache_name_api(cache_name: str): + + return api_request(method='post', url=f'/monitor/cache/clearCacheName/{cache_name}', is_headers=True) + + +def clear_cache_key_api(cache_name: str, cache_key: str): + + return api_request(method='post', url=f'/monitor/cache/clearCacheKey/{cache_name}/{cache_key}', is_headers=True) + + +def clear_all_cache_api(): + + return api_request(method='post', url='/monitor/cache/clearCacheAll', is_headers=True) diff --git a/dash-fastapi-frontend/app.py b/dash-fastapi-frontend/app.py index cf8cd500fd759cbab61a0753e82b7c8ee5fc3c6a..029167cc9467901d64d6dba9811a86d9dfcbc27c 100644 --- a/dash-fastapi-frontend/app.py +++ b/dash-fastapi-frontend/app.py @@ -5,6 +5,7 @@ from dash.dependencies import Input, Output, State import feffery_antd_components as fac import feffery_utils_components as fuc from flask import session +from operator import itemgetter from server import app from config.global_config import RouterConfig @@ -106,7 +107,7 @@ def router(pathname, url_trigger, session_token): if current_user_result['code'] == 200: current_user = current_user_result['data'] menu_list = current_user['menu'] - user_menu_list = [item for item in menu_list if item.get('visible') == '0'] + user_menu_list = sorted([item for item in menu_list if item.get('visible') == '0'], key=itemgetter('order_num')) menu_info = deal_user_menu_info(0, menu_list) user_menu_info = deal_user_menu_info(0, user_menu_list) search_panel_data = get_search_panel_data(user_menu_list) @@ -255,4 +256,4 @@ def router(pathname, url_trigger, session_token): if __name__ == '__main__': - app.run(host='127.0.0.1', port=8088, debug=True) + app.run(host='0.0.0.0', port=8088, debug=True) diff --git a/dash-fastapi-frontend/callbacks/layout_c/index_c.py b/dash-fastapi-frontend/callbacks/layout_c/index_c.py index cfcb6d91a8b50568914d533750a7b696c991633e..82b8cd47c6e2634c58ce78c42eea89b8f7e961dd 100644 --- a/dash-fastapi-frontend/callbacks/layout_c/index_c.py +++ b/dash-fastapi-frontend/callbacks/layout_c/index_c.py @@ -15,14 +15,15 @@ from utils.tree_tool import find_title_by_key, find_modules_by_key, find_href_by [Output('tabs-container', 'items', allow_duplicate=True), Output('tabs-container', 'activeKey', allow_duplicate=True)], [Input('index-side-menu', 'currentKey'), - Input('tabs-container', 'latestDeletePane')], - [State('tabs-container', 'items'), + Input('tabs-container', 'tabCloseCounts')], + [State('tabs-container', 'latestDeletePane'), + State('tabs-container', 'items'), State('tabs-container', 'activeKey'), State('menu-info-store-container', 'data'), State('menu-list-store-container', 'data')], prevent_initial_call=True ) -def handle_tab_switch_and_create(currentKey, latestDeletePane, origin_items, activeKey, menu_info, menu_list): +def handle_tab_switch_and_create(currentKey, tabCloseCounts, latestDeletePane, origin_items, activeKey, menu_info, menu_list): """ 这个回调函数用于处理标签页子项的新建、切换及删除 具体策略: @@ -175,7 +176,7 @@ def handle_tab_switch_and_create(currentKey, latestDeletePane, origin_items, act else: if index == len(origin_items) - 1: new_items[index - 1]['contextMenu'] = item['contextMenu'] - new_items.remove(item) + del new_items[index] break new_origin_items = [ item for item in @@ -254,7 +255,7 @@ def handle_via_context_menu(clickedContextMenu, origin_items, activeKey): else: if index == len(origin_items) - 1: new_items[index - 1]['contextMenu'] = item['contextMenu'] - new_items.remove(item) + del new_items[index] break new_origin_items = [ item for item in @@ -268,9 +269,14 @@ def handle_via_context_menu(clickedContextMenu, origin_items, activeKey): ] elif clickedContextMenu['menuKey'] == '关闭其他': - for item in origin_items: - if item['key'] != clickedContextMenu['tabKey'] and item['key'] != '首页': - new_items.remove(item) + current_index = 0 + for index, item in enumerate(origin_items): + if item['key'] == clickedContextMenu['tabKey']: + current_index = index + for i in range(1, current_index): + del new_items[1] + for j in range(current_index+1, len(origin_items)+1): + del new_items[2] context_menu = [ { 'key': '刷新页面', @@ -316,8 +322,8 @@ def handle_via_context_menu(clickedContextMenu, origin_items, activeKey): }) new_items[index]['contextMenu'] = item['contextMenu'] break - for item in origin_items[1:current_index]: - new_items.remove(item) + for i in range(1, current_index): + del new_items[1] return [ new_items, @@ -337,8 +343,8 @@ def handle_via_context_menu(clickedContextMenu, origin_items, activeKey): }) new_items[index]['contextMenu'] = item['contextMenu'] break - for item in origin_items[current_index+1:]: - new_items.remove(item) + for i in range(current_index+1, len(origin_items)+1): + del new_items[current_index+1] return [ new_items, @@ -346,9 +352,8 @@ def handle_via_context_menu(clickedContextMenu, origin_items, activeKey): dash.no_update ] - for item in origin_items: - if item['key'] != '首页': - new_items.remove(item) + for i in range(len(origin_items)): + del new_items[1] new_items[0]['contextMenu'] = [ { 'key': '刷新页面', diff --git a/dash-fastapi-frontend/callbacks/monitor_c/cache_c/list_c.py b/dash-fastapi-frontend/callbacks/monitor_c/cache_c/list_c.py new file mode 100644 index 0000000000000000000000000000000000000000..c701177243011170a3d09bad5c0b63403e5f9eb3 --- /dev/null +++ b/dash-fastapi-frontend/callbacks/monitor_c/cache_c/list_c.py @@ -0,0 +1,271 @@ +import dash +import time +import uuid +from dash.dependencies import Input, Output, State, ALL +from dash.exceptions import PreventUpdate +import feffery_utils_components as fuc + +from server import app +from api.cache import get_cache_name_list_api, get_cache_key_list_api, get_cache_value_api, clear_cache_name_api, clear_cache_key_api, clear_all_cache_api + + +@app.callback( + [Output('cache_name-list-table', 'data'), + Output('cache_name-list-table', 'key'), + Output('api-check-token', 'data', allow_duplicate=True)], + Input('refresh-cache_name', 'nClicks'), + prevent_initial_call=True +) +def get_cache_name_list(refresh_click): + """ + 刷新键名列表回调 + """ + if refresh_click: + + cache_name_res = get_cache_name_list_api() + if cache_name_res.get('code') == 200: + cache_name_list = cache_name_res.get('data') + cache_name_data = [{'key': item.get('cache_name'), 'id': index + 1, 'operation': {'type': 'link', 'icon': 'antd-delete'}, **item} for index, item in enumerate(cache_name_list)] + + return [ + cache_name_data, + str(uuid.uuid4()), + {'timestamp': time.time()} + ] + + return [ + dash.no_update, + dash.no_update, + {'timestamp': time.time()} + ] + + raise PreventUpdate + + +@app.callback( + output=dict( + cache_key_table_data=Output('cache_key-list-table', 'data'), + cache_key_table_key=Output('cache_key-list-table', 'key'), + cache_name_store=Output('current-cache_name-store', 'data'), + api_check_token_trigger=Output('api-check-token', 'data', allow_duplicate=True) + ), + inputs=dict( + cache_name_table_row_click=Input('cache_name-list-table', 'nClicksCell'), + cache_key_refresh_click=Input('refresh-cache_key', 'nClicks'), + operations=Input('cache_list-operations-store', 'data') + ), + state=dict( + cache_name_table_click_row_record=State('cache_name-list-table', 'recentlyCellClickRecord'), + ), + prevent_initial_call=True +) +def get_cache_key_list(cache_name_table_row_click, cache_key_refresh_click, operations, cache_name_table_click_row_record): + """ + 获取键名列表回调 + """ + if cache_name_table_row_click or cache_key_refresh_click or operations: + + cache_key_res = get_cache_key_list_api(cache_name=cache_name_table_click_row_record.get('key')) + if cache_key_res.get('code') == 200: + cache_key_list = cache_key_res.get('data') + cache_key_data = [ + {'key': item, 'id': index + 1, 'cache_key': item, 'operation': {'type': 'link', 'icon': 'antd-delete'}} for index, item in enumerate(cache_key_list)] + + return dict( + cache_key_table_data=cache_key_data, + cache_key_table_key=str(uuid.uuid4()), + cache_name_store=cache_name_table_click_row_record.get('key'), + api_check_token_trigger={'timestamp': time.time()} + ) + + return dict( + cache_key_table_data=dash.no_update, + cache_key_table_key=dash.no_update, + cache_name_store=dash.no_update, + api_check_token_trigger={'timestamp': time.time()} + ) + + raise PreventUpdate + + +@app.callback( + output=dict( + cache_name=Output('cache_name-input', 'value', allow_duplicate=True), + cache_key=Output('cache_key-input', 'value', allow_duplicate=True), + cache_value=Output('cache_value-input', 'value', allow_duplicate=True), + cache_key_store=Output('current-cache_key-store', 'data'), + api_check_token_trigger=Output('api-check-token', 'data', allow_duplicate=True) + ), + inputs=dict( + cache_key_table_row_click=Input('cache_key-list-table', 'nClicksCell') + ), + state=dict( + cache_key_table_click_row_record=State('cache_key-list-table', 'recentlyCellClickRecord'), + cache_name_store=State('current-cache_name-store', 'data'), + ), + prevent_initial_call=True +) +def get_cache_value(cache_key_table_row_click, cache_key_table_click_row_record, cache_name_store): + """ + 获取缓存内容回调 + """ + if cache_key_table_row_click: + + cache_value_res = get_cache_value_api(cache_name=cache_name_store, cache_key=cache_key_table_click_row_record.get('key')) + if cache_value_res.get('code') == 200: + cache = cache_value_res.get('data') + + return dict( + cache_name=cache.get('cache_name'), + cache_key=cache.get('cache_key'), + cache_value=cache.get('cache_value'), + cache_key_store=cache_key_table_click_row_record.get('key'), + api_check_token_trigger={'timestamp': time.time()} + ) + + return dict( + cache_name=dash.no_update, + cache_key=dash.no_update, + cache_value=dash.no_update, + cache_key_store=dash.no_update, + api_check_token_trigger={'timestamp': time.time()} + ) + + raise PreventUpdate + + +@app.callback( + [Output('cache_list-operations-store', 'data', allow_duplicate=True), + Output('api-check-token', 'data', allow_duplicate=True), + Output('global-message-container', 'children', allow_duplicate=True)], + Input('cache_name-list-table', 'nClicksButton'), + State('cache_name-list-table', 'recentlyButtonClickedRow'), + prevent_initial_call=True +) +def clear_cache_name(clear_click, recently_button_clicked_row): + """ + 缓存列表表格内部清除缓存回调 + """ + if clear_click: + clear_cache_name_res = clear_cache_name_api(cache_name=recently_button_clicked_row.get('key')) + if clear_cache_name_res.get('code') == 200: + + return [ + {'type': 'clear_cache_name'}, + {'timestamp': time.time()}, + fuc.FefferyFancyMessage(clear_cache_name_res.get('message'), type='success') + ] + + return [ + {'type': 'clear_cache_name'}, + {'timestamp': time.time()}, + fuc.FefferyFancyMessage(clear_cache_name_res.get('message'), type='error') + ] + + raise PreventUpdate + + +@app.callback( + output=dict( + cache_name=Output('cache_name-input', 'value', allow_duplicate=True), + cache_key=Output('cache_key-input', 'value', allow_duplicate=True), + cache_value=Output('cache_value-input', 'value', allow_duplicate=True), + operations=Output('cache_list-operations-store', 'data', allow_duplicate=True), + api_check_token_trigger=Output('api-check-token', 'data', allow_duplicate=True), + global_message_container=Output('global-message-container', 'children', allow_duplicate=True) + ), + inputs=dict( + clear_click=Input('cache_key-list-table', 'nClicksButton') + ), + state=dict( + recently_button_clicked_row=State('cache_key-list-table', 'recentlyButtonClickedRow'), + cache_name_store=State('current-cache_name-store', 'data'), + cache_key_store=State('current-cache_key-store', 'data') + ), + prevent_initial_call=True +) +def clear_cache_key(clear_click, recently_button_clicked_row, cache_name_store, cache_key_store): + """ + 键名列表表格内部清除键名回调 + """ + if clear_click: + clear_cache_key_res = clear_cache_key_api(cache_name=cache_name_store, cache_key=recently_button_clicked_row.get('key')) + if clear_cache_key_res.get('code') == 200: + if cache_key_store == recently_button_clicked_row.get('key'): + return dict( + cache_name=None, + cache_key=None, + cache_value=None, + operations={'type': 'clear_cache_key'}, + api_check_token_trigger={'timestamp': time.time()}, + global_message_container=fuc.FefferyFancyMessage(clear_cache_key_res.get('message'), type='success') + ) + else: + return dict( + cache_name=dash.no_update, + cache_key=dash.no_update, + cache_value=dash.no_update, + operations={'type': 'clear_cache_key'}, + api_check_token_trigger={'timestamp': time.time()}, + global_message_container=fuc.FefferyFancyMessage(clear_cache_key_res.get('message'), type='success') + ) + + return dict( + cache_name=dash.no_update, + cache_key=dash.no_update, + cache_value=dash.no_update, + operations={'type': 'clear_cache_key'}, + api_check_token_trigger={'timestamp': time.time()}, + global_message_container=fuc.FefferyFancyMessage(clear_cache_key_res.get('message'), type='error') + ) + + raise PreventUpdate + + +@app.callback( + output=dict( + cache_name=Output('cache_name-input', 'value', allow_duplicate=True), + cache_key=Output('cache_key-input', 'value', allow_duplicate=True), + cache_value=Output('cache_value-input', 'value', allow_duplicate=True), + refresh_cache_name=Output('refresh-cache_name', 'nClicks'), + refresh_cache_key=Output('refresh-cache_key', 'nClicks'), + api_check_token_trigger=Output('api-check-token', 'data', allow_duplicate=True), + global_message_container=Output('global-message-container', 'children', allow_duplicate=True) + ), + inputs=dict( + clear_all_click=Input('clear-all-cache', 'nClicks') + ), + state=dict( + refresh_cache_name_click=State('refresh-cache_name', 'nClicks'), + refresh_cache_key_click=State('refresh-cache_key', 'nClicks') + ), + prevent_initial_call=True +) +def clear_all_cache(clear_all_click, refresh_cache_name_click, refresh_cache_key_click): + """ + 清除所有缓存回调 + """ + if clear_all_click: + clear_all_cache_res = clear_all_cache_api() + if clear_all_cache_res.get('code') == 200: + return dict( + cache_name=None, + cache_key=None, + cache_value=None, + refresh_cache_name=refresh_cache_name_click + 1 if refresh_cache_name_click else 1, + refresh_cache_key=refresh_cache_key_click + 1 if refresh_cache_key_click else 1, + api_check_token_trigger={'timestamp': time.time()}, + global_message_container=fuc.FefferyFancyMessage(clear_all_cache_res.get('message'), type='success') + ) + + return dict( + cache_name=dash.no_update, + cache_key=dash.no_update, + cache_value=dash.no_update, + refresh_cache_name=dash.no_update, + refresh_cache_key=dash.no_update, + api_check_token_trigger={'timestamp': time.time()}, + global_message_container=fuc.FefferyFancyMessage(clear_all_cache_res.get('message'), type='error') + ) + + raise PreventUpdate diff --git a/dash-fastapi-frontend/callbacks/system_c/dept_c.py b/dash-fastapi-frontend/callbacks/system_c/dept_c.py index 660cc533e75a8b263be416062c4a72d73209a906..41645cd2a5f92ac35f3b15628c5b36ac852d0946 100644 --- a/dash-fastapi-frontend/callbacks/system_c/dept_c.py +++ b/dash-fastapi-frontend/callbacks/system_c/dept_c.py @@ -6,7 +6,7 @@ from dash.exceptions import PreventUpdate import feffery_utils_components as fuc from server import app -from utils.tree_tool import get_dept_tree +from utils.tree_tool import list_to_tree from api.dept import get_dept_tree_api, get_dept_list_api, add_dept_api, edit_dept_api, delete_dept_api, \ get_dept_detail_api, get_dept_tree_for_edit_option_api @@ -98,7 +98,7 @@ def get_dept_table_data(search_click, refresh_click, operations, fold_click, dep item['status'] = dict(tag='正常', color='blue') else: item['status'] = dict(tag='停用', color='volcano') - table_data_new = get_dept_tree(0, table_data) + table_data_new = list_to_tree(table_data, 'dept_id', 'parent_id') if fold_click: if in_default_expanded_row_keys: diff --git a/dash-fastapi-frontend/callbacks/system_c/menu_c/menu_c.py b/dash-fastapi-frontend/callbacks/system_c/menu_c/menu_c.py index dfcdedd7c464005b753eb268fb866359596840c8..36efee91334b19f84814d6ef17fb5d2fb4defb95 100644 --- a/dash-fastapi-frontend/callbacks/system_c/menu_c/menu_c.py +++ b/dash-fastapi-frontend/callbacks/system_c/menu_c/menu_c.py @@ -96,7 +96,7 @@ def get_menu_table_data(search_click, refresh_click, operations, fold_click, men item['status'] = dict(tag='正常', color='blue') else: item['status'] = dict(tag='停用', color='volcano') - table_data_new = list_to_tree(table_data) + table_data_new = list_to_tree(table_data, 'menu_id', 'parent_id') if fold_click: if not in_default_expanded_row_keys: diff --git a/dash-fastapi-frontend/callbacks/system_c/notice_c.py b/dash-fastapi-frontend/callbacks/system_c/notice_c.py index accdfd307c2fb8589f00f320f414439fc60c6518..310fb8028550105b27340645f0c5b5ca5bbd814f 100644 --- a/dash-fastapi-frontend/callbacks/system_c/notice_c.py +++ b/dash-fastapi-frontend/callbacks/system_c/notice_c.py @@ -252,7 +252,9 @@ def init_render_editor(html_string): allowedFileTypes: ['image/*'], // 自定义上传参数,例如传递验证的 token 等。参数会被添加到 formData 中,一起上传到服务端。 meta: { + baseUrl: '% s', uploadId: '% s', + taskPath: 'notice' }, // 将 meta 拼接到 url 参数中,默认 false metaWithUrl: true, @@ -279,7 +281,9 @@ def init_render_editor(html_string): allowedFileTypes: ['video/*'], // 自定义上传参数,例如传递验证的 token 等。参数会被添加到 formData 中,一起上传到服务端。 meta: { + baseUrl: '% s', uploadId: '% s', + taskPath: 'notice' }, // 将 meta 拼接到 url 参数中,默认 false metaWithUrl: true, @@ -311,7 +315,7 @@ def init_render_editor(html_string): config: toolbarConfig, mode: 'default' }) - ''' % (url, f'notice_{uuid.uuid4()}', token, url, f'notice_{uuid.uuid4()}', token, html_string) + ''' % (url, ApiBaseUrlConfig.BaseUrl, str(uuid.uuid4()), token, url, ApiBaseUrlConfig.BaseUrl, str(uuid.uuid4()), token, html_string) return js_string diff --git a/dash-fastapi-frontend/callbacks/system_c/user_c/profile_c/reset_pwd_c.py b/dash-fastapi-frontend/callbacks/system_c/user_c/profile_c/reset_pwd_c.py index ca81b66d2d2b6645e9f4b2e288e4204e5a109580..a33a8123895c354855455e29aa49aa838b9c3e30 100644 --- a/dash-fastapi-frontend/callbacks/system_c/user_c/profile_c/reset_pwd_c.py +++ b/dash-fastapi-frontend/callbacks/system_c/user_c/profile_c/reset_pwd_c.py @@ -84,15 +84,17 @@ def reset_submit_user_info(reset_click, old_password, new_password, confirm_pass @app.callback( - Output('tabs-container', 'latestDeletePane', allow_duplicate=True), + [Output('tabs-container', 'latestDeletePane', allow_duplicate=True), + Output('tabs-container', 'tabCloseCounts', allow_duplicate=True)], Input('reset-password-close', 'nClicks'), + State('tabs-container', 'tabCloseCounts'), prevent_initial_call=True ) -def close_personal_info_modal(close_click): +def close_personal_info_modal(close_click, tab_close_counts): """ 关闭当前个人资料标签页回调 """ if close_click: - return '个人资料' + return ['个人资料', tab_close_counts + 1 if tab_close_counts else 1] raise PreventUpdate diff --git a/dash-fastapi-frontend/callbacks/system_c/user_c/profile_c/user_info_c.py b/dash-fastapi-frontend/callbacks/system_c/user_c/profile_c/user_info_c.py index 6b2769d84537e601a4ecdaf328386f562195a5f9..14a882bfd109ec6b7b66014f990db036429b25bb 100644 --- a/dash-fastapi-frontend/callbacks/system_c/user_c/profile_c/user_info_c.py +++ b/dash-fastapi-frontend/callbacks/system_c/user_c/profile_c/user_info_c.py @@ -72,15 +72,17 @@ def reset_submit_user_info(reset_click, nick_name, phonenumber, email, sex): @app.callback( - Output('tabs-container', 'latestDeletePane', allow_duplicate=True), + [Output('tabs-container', 'latestDeletePane', allow_duplicate=True), + Output('tabs-container', 'tabCloseCounts', allow_duplicate=True)], Input('reset-close', 'nClicks'), + State('tabs-container', 'tabCloseCounts'), prevent_initial_call=True ) -def close_personal_info_modal(close_click): +def close_personal_info_modal(close_click, tab_close_counts): """ 关闭当前个人资料标签页回调 """ if close_click: - return '个人资料' + return ['个人资料', tab_close_counts + 1 if tab_close_counts else 1] raise PreventUpdate diff --git a/dash-fastapi-frontend/utils/request.py b/dash-fastapi-frontend/utils/request.py index 1c4e4ee72564291074650bb3f788b636d57bb837..08e31fc800817823a128247b575c25d6848f1df1 100644 --- a/dash-fastapi-frontend/utils/request.py +++ b/dash-fastapi-frontend/utils/request.py @@ -60,6 +60,9 @@ def api_request(method: str, url: str, is_headers: bool, params: Optional[dict] return response if stream else response.json() except Exception as e: logger.error("[api]请求人:{}||请求IP:{}||请求方法:{}||请求Api:{}||请求结果:{}", - session.get('user')['user_name'], request.remote_addr, method, url, str(e)) + session.get('user_info').get('user_name') if session.get('user_info') else None, + request.remote_addr, method, url, str(e)) + session['code'] = 500 + session['message'] = str(e) - raise Exception + return dict(code=500, data='', message=str(e)) diff --git a/dash-fastapi-frontend/utils/tree_tool.py b/dash-fastapi-frontend/utils/tree_tool.py index d07799919a9b6affba797dd847bff01778adca28..7ebd634e1064770c40adc4615761d46c2d19887f 100644 --- a/dash-fastapi-frontend/utils/tree_tool.py +++ b/dash-fastapi-frontend/utils/tree_tool.py @@ -206,21 +206,23 @@ def get_dept_tree(pid: int, permission_list: list): return dept_list -def list_to_tree(permission_list: list) -> list: +def list_to_tree(permission_list: list, sub_id_str: str, parent_id_str: str) -> list: """ - 工具方法:根据菜单信息生成树形嵌套数据 - :param permission_list: 菜单列表信息 - :return: 菜单树形嵌套数据 + 工具方法:根据列表信息生成树形嵌套数据 + :param permission_list: 列表信息 + :param sub_id_str: 子id字符串 + :param parent_id_str: 父id字符串 + :return: 树形嵌套数据 """ - # 转成menu_id为Key的字典 - mapping: dict = dict(zip([i['menu_id'] for i in permission_list], permission_list)) + # 转成id为key的字典 + mapping: dict = dict(zip([i[sub_id_str] for i in permission_list], permission_list)) # 树容器 container: list = [] for d in permission_list: # 如果找不到父级项,则是根节点 - parent: dict = mapping.get(d['parent_id']) + parent: dict = mapping.get(d[parent_id_str]) if parent is None: container.append(d) else: diff --git a/dash-fastapi-frontend/views/dashboard/components/page_top.py b/dash-fastapi-frontend/views/dashboard/components/page_top.py index dff95c995ad9cab9dc4700c086569aac025cfdf9..e4073482106e6f561aaaf7665801e8c2f61d38a6 100644 --- a/dash-fastapi-frontend/views/dashboard/components/page_top.py +++ b/dash-fastapi-frontend/views/dashboard/components/page_top.py @@ -3,6 +3,7 @@ import feffery_antd_components as fac import feffery_utils_components as fuc from flask import session +from config.global_config import ApiBaseUrlConfig def render_page_top(): @@ -13,7 +14,7 @@ def render_page_top(): fac.AntdAvatar( id='dashboard-avatar-info', mode='image', - src=session.get('user_info').get('avatar'), + src=f"{ApiBaseUrlConfig.BaseUrl}{session.get('user_info').get('avatar')}&token={session.get('Authorization')}", size='large' ), className='avatar', diff --git a/dash-fastapi-frontend/views/layout/components/head.py b/dash-fastapi-frontend/views/layout/components/head.py index 2d56290841689ce20304531e8c7d0cf4f9175ad3..95efcf85bada766ed40de518c6a4f3a5f48e2977 100644 --- a/dash-fastapi-frontend/views/layout/components/head.py +++ b/dash-fastapi-frontend/views/layout/components/head.py @@ -1,6 +1,7 @@ from dash import html import feffery_antd_components as fac from flask import session +from config.global_config import ApiBaseUrlConfig import callbacks.layout_c.head_c @@ -95,7 +96,7 @@ def render_head_content(): fac.AntdAvatar( id='avatar-info', mode='image', - src=session.get('user_info').get('avatar'), + src=f"{ApiBaseUrlConfig.BaseUrl}{session.get('user_info').get('avatar')}&token={session.get('Authorization')}", size=36 ), count=6, diff --git a/dash-fastapi-frontend/views/monitor/cache/list/__init__.py b/dash-fastapi-frontend/views/monitor/cache/list/__init__.py index f0951b609d961347f1555ed53ee9f4079b29c466..7db8b26f7ab1548560ae4e6d14a022026deb218a 100644 --- a/dash-fastapi-frontend/views/monitor/cache/list/__init__.py +++ b/dash-fastapi-frontend/views/monitor/cache/list/__init__.py @@ -1,8 +1,215 @@ -from dash import html -import feffery_utils_components as fuc +from dash import html, dcc import feffery_antd_components as fac +from api.cache import get_cache_name_list_api +import callbacks.monitor_c.cache_c.list_c + def render(button_perms): + cache_name_data = [] + cache_name_res = get_cache_name_list_api() + if cache_name_res.get('code') == 200: + cache_name_list = cache_name_res.get('data') + cache_name_data = [{'key': item.get('cache_name'), 'id': index + 1, 'operation': {'type': 'link', 'icon': 'antd-delete'}, **item} for index, item in enumerate(cache_name_list)] - return html.Div('我是缓存列表') + return html.Div( + [ + dcc.Store(id='cache_list-operations-store'), + dcc.Store(id='current-cache_name-store'), + dcc.Store(id='current-cache_key-store'), + fac.AntdRow( + [ + fac.AntdCol( + fac.AntdCard( + fac.AntdSpin( + fac.AntdTable( + id='cache_name-list-table', + data=cache_name_data, + columns=[ + { + 'dataIndex': 'id', + 'title': '序号', + 'renderOptions': { + 'renderType': 'ellipsis' + }, + }, + { + 'dataIndex': 'cache_name', + 'title': '缓存名称', + 'renderOptions': { + 'renderType': 'ellipsis' + }, + }, + { + 'dataIndex': 'remark', + 'title': '备注', + 'renderOptions': { + 'renderType': 'ellipsis' + }, + }, + { + 'title': '操作', + 'dataIndex': 'operation', + 'renderOptions': { + 'renderType': 'button' + }, + } + ], + enableCellClickListenColumns=['id', 'cache_name', 'remark'], + bordered=False, + pagination={ + 'showSizeChanger': True, + 'showQuickJumper': True, + 'hideOnSinglePage': True + }, + ) + ), + title=fac.AntdSpace( + [ + fac.AntdIcon(icon='antd-book'), + fac.AntdText('缓存列表') + ] + ), + extra=fac.AntdButton( + id='refresh-cache_name', + type='link', + icon=fac.AntdIcon( + icon='antd-reload' + ) + ), + size='small', + style={ + 'boxShadow': 'rgba(99, 99, 99, 0.2) 0px 2px 8px 0px' + } + ), + span=8 + ), + fac.AntdCol( + fac.AntdCard( + fac.AntdSpin( + fac.AntdTable( + id='cache_key-list-table', + data=[], + columns=[ + { + 'dataIndex': 'id', + 'title': '序号', + 'renderOptions': { + 'renderType': 'ellipsis' + }, + }, + { + 'dataIndex': 'cache_key', + 'title': '缓存键名', + 'renderOptions': { + 'renderType': 'ellipsis' + }, + }, + { + 'title': '操作', + 'dataIndex': 'operation', + 'renderOptions': { + 'renderType': 'button' + }, + } + ], + enableCellClickListenColumns=['id', 'cache_key'], + bordered=False, + pagination={ + 'showSizeChanger': True, + 'showQuickJumper': True, + 'hideOnSinglePage': True, + } + ) + ), + title=fac.AntdSpace( + [ + fac.AntdIcon(icon='antd-key'), + fac.AntdText('键名列表') + ] + ), + extra=fac.AntdButton( + id='refresh-cache_key', + type='link', + icon=fac.AntdIcon( + icon='antd-reload' + ) + ), + size='small', + style={ + 'boxShadow': 'rgba(99, 99, 99, 0.2) 0px 2px 8px 0px' + } + ), + span=8 + ), + fac.AntdCol( + fac.AntdCard( + fac.AntdForm( + [ + fac.AntdFormItem( + fac.AntdInput( + id='cache_name-input', + readOnly=True, + style={ + 'width': '100%' + } + ), + label='缓存名称' + ), + fac.AntdFormItem( + fac.AntdInput( + id='cache_key-input', + readOnly=True, + style={ + 'width': '100%' + } + ), + label='缓存键名' + ), + fac.AntdFormItem( + fac.AntdInput( + id='cache_value-input', + mode='text-area', + readOnly=True, + autoSize={ + 'minRows': 5, + 'maxRows': 10 + }, + style={ + 'width': '100%' + } + ), + label='缓存内容' + ) + ], + layout='vertical', + style={ + 'width': '100%' + } + ), + title=fac.AntdSpace( + [ + fac.AntdIcon(icon='antd-file-text'), + fac.AntdText('缓存内容') + ] + ), + extra=fac.AntdButton( + '清除全部', + id='clear-all-cache', + type='link', + icon=fac.AntdIcon( + icon='antd-clear' + ) + ), + size='small', + style={ + 'boxShadow': 'rgba(99, 99, 99, 0.2) 0px 2px 8px 0px' + } + ), + span=8 + ) + ], + gutter=10 + ) + ] + ) diff --git a/dash-fastapi-frontend/views/system/dept/__init__.py b/dash-fastapi-frontend/views/system/dept/__init__.py index bc8de1b4b673d7b0da5aadf076c1023395f14a30..354bb6effe299ef7d35364f2f7208a598f9f941f 100644 --- a/dash-fastapi-frontend/views/system/dept/__init__.py +++ b/dash-fastapi-frontend/views/system/dept/__init__.py @@ -3,7 +3,7 @@ import feffery_antd_components as fac import callbacks.system_c.dept_c from api.dept import get_dept_list_api -from utils.tree_tool import get_dept_tree +from utils.tree_tool import list_to_tree def render(button_perms): @@ -63,7 +63,7 @@ def render(button_perms): item['status'] = dict(tag='正常', color='blue') else: item['status'] = dict(tag='停用', color='volcano') - table_data_new = get_dept_tree(0, table_data) + table_data_new = list_to_tree(table_data, 'dept_id', 'parent_id') return [ dcc.Store(id='dept-button-perms-container', data=button_perms), diff --git a/dash-fastapi-frontend/views/system/menu/__init__.py b/dash-fastapi-frontend/views/system/menu/__init__.py index a8038a1bf3504b491c993f5bcbdf9ce18794ac46..12f0f2a45db86a07fab1b1bbea3299c28f186629 100644 --- a/dash-fastapi-frontend/views/system/menu/__init__.py +++ b/dash-fastapi-frontend/views/system/menu/__init__.py @@ -59,7 +59,7 @@ def render(button_perms): item['status'] = dict(tag='正常', color='blue') else: item['status'] = dict(tag='停用', color='volcano') - table_data_new = list_to_tree(table_data) + table_data_new = list_to_tree(table_data, 'menu_id', 'parent_id') return [ dcc.Store(id='menu-button-perms-container', data=button_perms), diff --git a/dash-fastapi-frontend/views/system/user/__init__.py b/dash-fastapi-frontend/views/system/user/__init__.py index 34651a886ac670935e9a2e7b58af2c096c9e4193..646878e7236ff33d21c3114dd689c8e26771866b 100644 --- a/dash-fastapi-frontend/views/system/user/__init__.py +++ b/dash-fastapi-frontend/views/system/user/__init__.py @@ -999,7 +999,9 @@ def render(button_perms): fac.AntdDraggerUpload( id='user-upload-choose', apiUrl=f'{ApiBaseUrlConfig.BaseUrl}/common/upload', + apiUrlExtraParams={'taskPath': 'userUpload'}, downloadUrl=f'{ApiBaseUrlConfig.BaseUrl}/common/caches', + downloadUrlExtraParams={'taskPath': 'userUpload', 'token': session.get('Authorization')}, headers={'Authorization': 'Bearer ' + session.get('Authorization')}, fileTypes=['xls', 'xlsx'], fileListMaxLength=1, diff --git a/dash-fastapi-frontend/views/system/user/profile/user_avatar.py b/dash-fastapi-frontend/views/system/user/profile/user_avatar.py index a70c29ef5ffcc62b80be3d67188168e613a1baa6..2772d74826dd3d5f567e075b538562ea4ba5ca20 100644 --- a/dash-fastapi-frontend/views/system/user/profile/user_avatar.py +++ b/dash-fastapi-frontend/views/system/user/profile/user_avatar.py @@ -19,7 +19,7 @@ def render(): [ fac.AntdImage( id='user-avatar-image-info', - src=session.get('user_info').get('avatar'), + src=f"{ApiBaseUrlConfig.BaseUrl}{session.get('user_info').get('avatar')}&token={session.get('Authorization')}", preview=False, height='120px', width='120px', @@ -112,7 +112,9 @@ def render(): fac.AntdUpload( id='avatar-upload-choose', apiUrl=f'{ApiBaseUrlConfig.BaseUrl}/common/upload', - downloadUrl=f'{ApiBaseUrlConfig.BaseUrl}/common/caches', + apiUrlExtraParams={'taskPath': 'avatarUpload'}, + downloadUrl=f"{ApiBaseUrlConfig.BaseUrl}/common/caches", + downloadUrlExtraParams={'taskPath': 'avatarUpload', 'token': session.get('Authorization')}, headers={'Authorization': 'Bearer ' + session.get('Authorization')}, fileMaxSize=10, showUploadList=False, diff --git "a/demo-pictures/\347\274\223\345\255\230\345\210\227\350\241\250.png" "b/demo-pictures/\347\274\223\345\255\230\345\210\227\350\241\250.png" new file mode 100644 index 0000000000000000000000000000000000000000..f1112e7527b17a118a28a28f90ba664fa886ab96 Binary files /dev/null and "b/demo-pictures/\347\274\223\345\255\230\345\210\227\350\241\250.png" differ diff --git "a/demo-pictures/\350\247\222\350\211\262\347\256\241\347\220\206.png" "b/demo-pictures/\350\247\222\350\211\262\347\256\241\347\220\206.png" index 1f1f63c5ceeafcb05859b360f7c51c2072851e35..c0c224c1e62ef2c933fbb484165cb2cecc3a2b67 100644 Binary files "a/demo-pictures/\350\247\222\350\211\262\347\256\241\347\220\206.png" and "b/demo-pictures/\350\247\222\350\211\262\347\256\241\347\220\206.png" differ diff --git "a/demo-pictures/\351\246\226\351\241\265.png" "b/demo-pictures/\351\246\226\351\241\265.png" new file mode 100644 index 0000000000000000000000000000000000000000..b4c240c753114a250737591ec76593bfd3e0fbce Binary files /dev/null and "b/demo-pictures/\351\246\226\351\241\265.png" differ diff --git a/requirements.txt b/requirements.txt index c6b2a71e419e9976206382cf18d58fa3688e9ad8..fd36650a8c4e9079506fc1866b9bbedf766ba98a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -23,7 +23,7 @@ email-validator==2.0.0.post2 et-xmlfile==1.1.0 fastapi==0.95.1 feffery-antd-charts==0.0.1rc17 -feffery-antd-components==0.2.10rc18 +feffery-antd-components==0.2.11rc0 feffery-markdown-components==0.2.10 feffery-utils-components==0.2.0b1 Flask==2.2.5