refactor: refactor log management (#682)

This commit is contained in:
王嘉豪
2025-12-25 11:46:11 +08:00
committed by GitHub
parent 6039c68f88
commit af99f105e2
22 changed files with 393 additions and 195 deletions
+3
View File
@@ -8,6 +8,7 @@ from apps.mcp import mcp
from apps.system.api import login, user, aimodel, workspace, assistant, parameter, apikey
from apps.terminology.api import terminology
from apps.settings.api import base
#from apps.audit.api import audit_api
api_router = APIRouter()
@@ -28,3 +29,5 @@ api_router.include_router(parameter.router)
api_router.include_router(apikey.router)
api_router.include_router(recommended_problem.router)
#api_router.include_router(audit_api.router)
+6 -8
View File
@@ -21,8 +21,8 @@ from apps.system.schemas.permission import SqlbotPermission, require_permissions
from common.core.deps import CurrentAssistant, SessionDep, CurrentUser, Trans
from common.utils.command_utils import parse_quick_command
from common.utils.data_format import DataFormat
from sqlbot_xpack.audit.models.log_model import OperationType, OperationDetails, OperationModules
from sqlbot_xpack.audit.schemas.logger_decorator import system_log, LogConfig
from sqlbot_xpack.audit.models.log_model import OperationType, OperationModules
from sqlbot_xpack.audit.schemas.logger_decorator import LogConfig, system_log
router = APIRouter(tags=["Data Q&A"], prefix="/chat")
@@ -83,9 +83,8 @@ async def rename(session: SessionDep, chat: RenameChat):
@router.delete("/{chart_id}/{brief}", response_model=str, summary=f"{PLACEHOLDER_PREFIX}delete_chat")
@system_log(LogConfig(
operation_type=OperationType.DELETE_QA,
operation_detail=OperationDetails.DELETE_QA_DETAILS,
module=OperationModules.QA,
operation_type=OperationType.DELETE,
module=OperationModules.CHAT,
resource_id_expr="chart_id",
remark_expr="brief"
))
@@ -102,9 +101,8 @@ async def delete(session: SessionDep, chart_id: int, brief: str):
@router.post("/start", response_model=ChatInfo, summary=f"{PLACEHOLDER_PREFIX}start_chat")
@require_permissions(permission=SqlbotPermission(type='ds', keyExpression="create_chat_obj.datasource"))
@system_log(LogConfig(
operation_type=OperationType.CREATE_QA,
operation_detail=OperationDetails.CREATE_QA_DETAILS,
module=OperationModules.QA,
operation_type=OperationType.CREATE,
module=OperationModules.CHAT,
result_id_expr="id"
))
async def start_chat(session: SessionDep, current_user: CurrentUser, create_chat_obj: CreateChat):
+5 -8
View File
@@ -3,8 +3,8 @@ from fastapi import APIRouter, File, UploadFile, HTTPException
from apps.dashboard.crud.dashboard_service import list_resource, load_resource, \
create_resource, create_canvas, validate_name, delete_resource, update_resource, update_canvas
from apps.dashboard.models.dashboard_model import CreateDashboard, BaseDashboard, QueryDashboard, DashboardResponse
from sqlbot_xpack.audit.models.log_model import OperationType, OperationDetails, OperationModules
from sqlbot_xpack.audit.schemas.logger_decorator import system_log, LogConfig
from sqlbot_xpack.audit.models.log_model import OperationType, OperationModules
from sqlbot_xpack.audit.schemas.logger_decorator import LogConfig, system_log
from common.core.deps import SessionDep, CurrentUser
router = APIRouter(tags=["dashboard"], prefix="/dashboard")
@@ -32,8 +32,7 @@ async def update_resource_api(session: SessionDep, user: CurrentUser, dashboard:
@router.delete("/delete_resource/{resource_id}/{name}")
@system_log(LogConfig(
operation_type=OperationType.DELETE_DASHBOARD,
operation_detail=OperationDetails.DELETE_DASHBOARD_DETAILS,
operation_type=OperationType.DELETE,
module=OperationModules.DASHBOARD,
resource_id_expr="resource_id",
remark_expr="name"
@@ -44,8 +43,7 @@ async def delete_resource_api(session: SessionDep, resource_id: str, name: str):
@router.post("/create_canvas", response_model=BaseDashboard)
@system_log(LogConfig(
operation_type=OperationType.CREATE_DASHBOARD,
operation_detail=OperationDetails.CREATE_DASHBOARD_DETAILS,
operation_type=OperationType.CREATE,
module=OperationModules.DASHBOARD,
result_id_expr="id"
))
@@ -55,8 +53,7 @@ async def create_canvas_api(session: SessionDep, user: CurrentUser, dashboard: C
@router.post("/update_canvas", response_model=BaseDashboard)
@system_log(LogConfig(
operation_type=OperationType.UPDATE_DASHBOARD,
operation_detail=OperationDetails.UPDATE_DASHBOARD_DETAILS,
operation_type=OperationType.UPDATE,
module=OperationModules.DASHBOARD,
resource_id_expr="dashboard.id"
))
+5 -8
View File
@@ -28,8 +28,8 @@ from ..crud.field import get_fields_by_table_id
from ..crud.table import get_tables_by_ds_id
from ..models.datasource import CoreDatasource, CreateDatasource, TableObj, CoreTable, CoreField, FieldObj, \
TableSchemaResponse, ColumnSchemaResponse, PreviewResponse
from sqlbot_xpack.audit.models.log_model import OperationType, OperationDetails, OperationModules
from sqlbot_xpack.audit.schemas.logger_decorator import system_log, LogConfig
from sqlbot_xpack.audit.models.log_model import OperationType, OperationModules
from sqlbot_xpack.audit.schemas.logger_decorator import LogConfig, system_log
router = APIRouter(tags=["Datasource"], prefix="/datasource")
path = settings.EXCEL_PATH
@@ -72,8 +72,7 @@ async def check_by_id(session: SessionDep, trans: Trans,
@router.post("/add", response_model=CoreDatasource, summary=f"{PLACEHOLDER_PREFIX}ds_add")
@system_log(LogConfig(
operation_type=OperationType.CREATE_DATASOURCE,
operation_detail=OperationDetails.CREATE_DATASOURCE_DETAILS,
operation_type=OperationType.CREATE,
module=OperationModules.DATASOURCE,
result_id_expr="id"
))
@@ -96,8 +95,7 @@ async def choose_tables(session: SessionDep, trans: Trans, tables: List[CoreTabl
@router.post("/update", response_model=CoreDatasource, summary=f"{PLACEHOLDER_PREFIX}ds_update")
@require_permissions(permission=SqlbotPermission(type='ds', keyExpression="ds.id"))
@system_log(LogConfig(
operation_type=OperationType.UPDATE_DATASOURCE,
operation_detail=OperationDetails.UPDATE_DATASOURCE_DETAILS,
operation_type=OperationType.UPDATE,
module=OperationModules.DATASOURCE,
resource_id_expr="ds.id"
))
@@ -111,8 +109,7 @@ async def update(session: SessionDep, trans: Trans, user: CurrentUser, ds: CoreD
@router.post("/delete/{id}/{name}", response_model=None, summary=f"{PLACEHOLDER_PREFIX}ds_delete")
@require_permissions(permission=SqlbotPermission(type='ds', keyExpression="id"))
@system_log(LogConfig(
operation_type=OperationType.DELETE_DATASOURCE,
operation_detail=OperationDetails.DELETE_DATASOURCE_DETAILS,
operation_type=OperationType.DELETE,
module=OperationModules.DATASOURCE,
resource_id_expr="id",
remark_expr="name"
+9
View File
@@ -11,9 +11,18 @@ from datetime import timedelta
from common.core.config import settings
from common.core.schemas import Token
from sqlbot_xpack.authentication.manage import logout as xpack_logout
from sqlbot_xpack.audit.models.log_model import OperationType, OperationModules
from sqlbot_xpack.audit.schemas.logger_decorator import system_log, LogConfig
router = APIRouter(tags=["login"], prefix="/login")
@router.post("/access-token")
@system_log(LogConfig(
operation_type=OperationType.LOGIN,
module=OperationModules.USER,
result_id_expr="id"
))
async def local_login(
session: SessionDep,
trans: Trans,
@@ -36,6 +36,7 @@ class BaseUserDTO(BaseUser, BaseCreatorDTO):
password: str
status: int = 1
origin: int = 0
name: str
def to_dict(self):
return {
+23 -33
View File
@@ -125,44 +125,34 @@
"i18n_audit": {
"success": "Success",
"failed": "Failed",
"create_qa": "Create Q&A",
"delete_qa": "Delete Q&A",
"create_datasource": "Create Datasource",
"update_datasource": "Edit Datasource",
"delete_datasource": "Delete Datasource",
"create_dashboard": "Create Dashboard",
"update_dashboard": "Edit Dashboard",
"delete_dashboard": "Delete Dashboard",
"setting_create_user": "Add Member",
"setting_delete_user": "Remove Member",
"setting_create_rule": "Add Rule Group",
"setting_delete_rule": "Remove Rule Group",
"setting_update_rule": "Configure Rules",
"setting_update_rule_user": "Configure Users",
"setting_create_terminology": "Create Terminology",
"create_qa_details": "Create Q&A【{resource_name}】",
"delete_qa_details": "Delete Q&A【{resource_name}】",
"create_datasource_details": "Create Datasource【{resource_name}】",
"update_datasource_details": "Edit Datasource【{resource_name}】",
"delete_datasource_details": "Delete Datasource【{resource_name}】",
"create_dashboard_details": "Create Dashboard【{resource_name}】",
"update_dashboard_details": "Edit Dashboard【{resource_name}】",
"delete_dashboard_details": "Delete Dashboard【{resource_name}】",
"setting_create_user_details": "Add Member【{resource_name}】",
"setting_delete_user_details": "Remove Member【{resource_name}】",
"setting_create_rule_details": "Add Rule Group【{resource_name}】",
"setting_delete_rule_details": "Remove Rule Group【{resource_name}】",
"setting_update_rule_details": "Configure Rules【{resource_name}】",
"setting_update_rule_user_details": "Configure Users【{resource_name}】",
"setting_create_terminology_details": "Create Terminology【{resource_name}】",
"system_log": "System Log",
"system_log": "Operation Log",
"operation_type_name": "Operation Type",
"operation_detail_info": "Operation Details",
"user_name": "Operating User",
"user_name": "Operator",
"oid_name": "Workspace",
"operation_status_name": "Operation Status",
"error_message": "Error Message",
"ip_address": "IP Address",
"create_time": "Operation Time"
"create_time": "Operation Time",
"chat": "AI Q&A",
"datasource": "Datasource",
"dashboard": "Dashboard",
"member": "Member",
"permission": "Permission",
"terminology": "Terminology",
"data_training": "SQL Examples",
"prompt_words": "Prompt Words",
"user": "User",
"workspace": "Workspace",
"ai_model": "AI Model",
"application": "Application",
"theme": "Appearance Settings",
"create": "Create",
"delete": "Delete",
"update": "Update",
"edit": "Edit",
"login": "Login",
"export": "Export",
"import": "Import"
}
}
+24 -34
View File
@@ -125,44 +125,34 @@
"i18n_audit": {
"success": "성공",
"failed": "실패",
"create_qa": "Q&A 생성",
"delete_qa": "Q&A 삭제",
"create_datasource": "데이터 소스 생성",
"update_datasource": "데이터 소스 편집",
"delete_datasource": "데이터 소스 삭제",
"create_dashboard": "대시보드 생성",
"update_dashboard": "대시보드 편집",
"delete_dashboard": "대시보드 삭제",
"setting_create_user": "멤버 추가",
"setting_delete_user": "멤버 제거",
"setting_create_rule": "규칙 그룹 추가",
"setting_delete_rule": "규칙 그룹 제거",
"setting_update_rule": "규칙 설정",
"setting_update_rule_user": "사용자 설정",
"setting_create_terminology": "용어 생성",
"create_qa_details": "Q&A 생성【{resource_name}】",
"delete_qa_details": "Q&A 삭제【{resource_name}】",
"create_datasource_details": "데이터 소스 생성【{resource_name}】",
"update_datasource_details": "데이터 소스 편집【{resource_name}】",
"delete_datasource_details": "데이터 소스 삭제【{resource_name}】",
"create_dashboard_details": "대시보드 생성【{resource_name}】",
"update_dashboard_details": "대시보드 편집【{resource_name}】",
"delete_dashboard_details": "대시보드 삭제【{resource_name}】",
"setting_create_user_details": "멤버 추가【{resource_name}】",
"setting_delete_user_details": "멤버 제거【{resource_name}】",
"setting_create_rule_details": "규칙 그룹 추가【{resource_name}】",
"setting_delete_rule_details": "규칙 그룹 제거【{resource_name}】",
"setting_update_rule_details": "규칙 설정【{resource_name}】",
"setting_update_rule_user_details": "사용자 설정【{resource_name}】",
"setting_create_terminology_details": "용어 생성【{resource_name}】",
"system_log": "시스템 로그",
"system_log": "작업 로그",
"operation_type_name": "작업 유형",
"operation_detail_info": "작업 상세 정보",
"user_name": "작업 사용자",
"operation_detail_info": "작업 상세",
"user_name": "작업자",
"oid_name": "작업 공간",
"operation_status_name": "작업 상태",
"error_message": "오류 메시지",
"ip_address": "IP 주소",
"create_time": "작업 시간"
"create_time": "작업 시간",
"chat": "지능형 질의",
"datasource": "데이터 소스",
"dashboard": "대시보드",
"member": "구성원",
"permission": "권한",
"terminology": "용어",
"data_training": "SQL 예제 라이브러리",
"prompt_words": "프롬프트 단어",
"user": "사용자",
"workspace": "작업 공간",
"ai_model": "AI 모델",
"application": "애플리케이션",
"theme": "외관 설정",
"create": "생성",
"delete": "삭제",
"update": "수정",
"edit": "편집",
"login": "로그인",
"export": "내보내기",
"import": "가져오기"
}
}
+22 -32
View File
@@ -125,36 +125,6 @@
"i18n_audit": {
"success": "成功",
"failed": "失败",
"create_qa": "新建问数",
"delete_qa": "删除问数",
"create_datasource": "新建数据源",
"update_datasource": "编辑数据源",
"delete_datasource": "删除数据源",
"create_dashboard": "新建仪表板",
"update_dashboard": "编辑仪表板",
"delete_dashboard": "删除仪表板",
"setting_create_user": "添加成员",
"setting_delete_user": "移除成员",
"setting_create_rule": "添加规则组",
"setting_delete_rule": "移除规则组",
"setting_update_rule": "设置规则",
"setting_update_rule_user": "设置用户",
"setting_create_terminology": "新建术语",
"create_qa_details": "新建问数【{resource_name}】",
"delete_qa_details": "删除问数【{resource_name}】",
"create_datasource_details": "新建数据源【{resource_name}】",
"update_datasource_details": "编辑数据源【{resource_name}】",
"delete_datasource_details": "删除数据源【{resource_name}】",
"create_dashboard_details": "新建仪表板【{resource_name}】",
"update_dashboard_details": "编辑仪表板【{resource_name}】",
"delete_dashboard_details": "删除仪表板【{resource_name}】",
"setting_create_user_details": "添加成员【{resource_name}】",
"setting_delete_user_details": "移除成员【{resource_name}】",
"setting_create_rule_details": "添加规则组【{resource_name}】",
"setting_delete_rule_details": "移除规则组【{resource_name}】",
"setting_update_rule_details": "设置规则【{resource_name}】",
"setting_update_rule_user_details": "设置用户【{resource_name}】",
"setting_create_terminology_details": "新建术语【{resource_name}】",
"system_log": "操作日志",
"operation_type_name": "操作类型",
"operation_detail_info": "操作详情",
@@ -163,6 +133,26 @@
"operation_status_name": "操作状态",
"error_message": "错误信息",
"ip_address": "IP 地址",
"create_time": "操作时间"
"create_time": "操作时间",
"chat": "智能问数",
"datasource": "数据源",
"dashboard": "仪表板",
"member": "成员",
"permission": "权限",
"terminology": "术语",
"data_training": "SQL 示例库",
"prompt_words": "提示词",
"user": "用户",
"workspace": "工作空间",
"ai_model": "AI 模型",
"application": "应用",
"theme": "外观配置",
"create": "新建",
"delete": "删除",
"update": "更新",
"edit": "编辑",
"login": "登录",
"export": "导出",
"import": "导入"
}
}
}
+1
View File
@@ -3,6 +3,7 @@ import { request } from '@/utils/request'
export const audit = {
getList: (pageNum: any, pageSize: any, params: any) =>
request.get(`/system/audit/page/${pageNum}/${pageSize}${params}`),
getOptions: () => request.get(`/system/audit/get_options`),
export2Excel: (params: any) =>
request.get(`/system/audit/export`, {
params,
+3
View File
@@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path d="M13.3333 2.49967H4.16667V17.4997H15.8333V5.01592H13.75C13.6395 5.01592 13.5335 4.97203 13.4554 4.89389C13.3772 4.81575 13.3333 4.70976 13.3333 4.59926V2.49967ZM3.33333 0.833008H14.2379C14.3474 0.832976 14.4558 0.854524 14.557 0.89642C14.6582 0.938316 14.7501 0.999737 14.8275 1.07717L17.2563 3.50676C17.4124 3.66307 17.5001 3.87499 17.5 4.09592V18.333C17.5 18.554 17.4122 18.766 17.2559 18.9223C17.0996 19.0785 16.8877 19.1663 16.6667 19.1663H3.33333C3.11232 19.1663 2.90036 19.0785 2.74408 18.9223C2.5878 18.766 2.5 18.554 2.5 18.333V1.66634C2.5 1.44533 2.5878 1.23337 2.74408 1.07709C2.90036 0.920805 3.11232 0.833008 3.33333 0.833008ZM6.66667 8.33301H13.3333C13.4438 8.33301 13.5498 8.37691 13.628 8.45505C13.7061 8.53319 13.75 8.63917 13.75 8.74967V9.58301C13.75 9.69351 13.7061 9.7995 13.628 9.87764C13.5498 9.95578 13.4438 9.99967 13.3333 9.99967H6.66667C6.55616 9.99967 6.45018 9.95578 6.37204 9.87764C6.2939 9.7995 6.25 9.69351 6.25 9.58301V8.74967C6.25 8.63917 6.2939 8.53319 6.37204 8.45505C6.45018 8.37691 6.55616 8.33301 6.66667 8.33301ZM6.66667 12.4997H10.4167C10.4714 12.4997 10.5256 12.5105 10.5761 12.5314C10.6267 12.5523 10.6726 12.583 10.7113 12.6217C10.75 12.6604 10.7807 12.7063 10.8016 12.7569C10.8226 12.8074 10.8333 12.8616 10.8333 12.9163V13.7497C10.8333 13.8044 10.8226 13.8586 10.8016 13.9091C10.7807 13.9597 10.75 14.0056 10.7113 14.0443C10.6726 14.083 10.6267 14.1137 10.5761 14.1346C10.5256 14.1556 10.4714 14.1663 10.4167 14.1663H6.66667C6.55616 14.1663 6.45018 14.1224 6.37204 14.0443C6.2939 13.9662 6.25 13.8602 6.25 13.7497V12.9163C6.25 12.8058 6.2939 12.6999 6.37204 12.6217C6.45018 12.5436 6.55616 12.4997 6.66667 12.4997Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

@@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path d="M13.3333 2.49967H4.16667V17.4997H15.8333V5.01592H13.75C13.6395 5.01592 13.5335 4.97203 13.4554 4.89389C13.3772 4.81575 13.3333 4.70976 13.3333 4.59926V2.49967ZM3.33333 0.833008H14.2379C14.3474 0.832976 14.4558 0.854524 14.557 0.89642C14.6582 0.938316 14.7501 0.999737 14.8275 1.07717L17.2563 3.50676C17.4124 3.66307 17.5001 3.87499 17.5 4.09592V18.333C17.5 18.554 17.4122 18.766 17.2559 18.9223C17.0996 19.0785 16.8877 19.1663 16.6667 19.1663H3.33333C3.11232 19.1663 2.90036 19.0785 2.74408 18.9223C2.5878 18.766 2.5 18.554 2.5 18.333V1.66634C2.5 1.44533 2.5878 1.23337 2.74408 1.07709C2.90036 0.920805 3.11232 0.833008 3.33333 0.833008ZM6.66667 8.33301H13.3333C13.4438 8.33301 13.5498 8.37691 13.628 8.45505C13.7061 8.53319 13.75 8.63917 13.75 8.74967V9.58301C13.75 9.69351 13.7061 9.7995 13.628 9.87764C13.5498 9.95578 13.4438 9.99967 13.3333 9.99967H6.66667C6.55616 9.99967 6.45018 9.95578 6.37204 9.87764C6.2939 9.7995 6.25 9.69351 6.25 9.58301V8.74967C6.25 8.63917 6.2939 8.53319 6.37204 8.45505C6.45018 8.37691 6.55616 8.33301 6.66667 8.33301ZM6.66667 12.4997H10.4167C10.4714 12.4997 10.5256 12.5105 10.5761 12.5314C10.6267 12.5523 10.6726 12.583 10.7113 12.6217C10.75 12.6604 10.7807 12.7063 10.8016 12.7569C10.8226 12.8074 10.8333 12.8616 10.8333 12.9163V13.7497C10.8333 13.8044 10.8226 13.8586 10.8016 13.9091C10.7807 13.9597 10.75 14.0056 10.7113 14.0443C10.6726 14.083 10.6267 14.1137 10.5761 14.1346C10.5256 14.1556 10.4714 14.1663 10.4167 14.1663H6.66667C6.55616 14.1663 6.45018 14.1224 6.37204 14.0443C6.2939 13.9662 6.25 13.8602 6.25 13.7497V12.9163C6.25 12.8058 6.2939 12.6999 6.37204 12.6217C6.45018 12.5436 6.55616 12.4997 6.66667 12.4997Z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

@@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path d="M13.3333 2.49967H4.16667V17.4997H15.8333V5.01592H13.75C13.6395 5.01592 13.5335 4.97203 13.4554 4.89389C13.3772 4.81575 13.3333 4.70976 13.3333 4.59926V2.49967ZM3.33333 0.833008H14.2379C14.3474 0.832976 14.4558 0.854524 14.557 0.89642C14.6582 0.938316 14.7501 0.999737 14.8275 1.07717L17.2563 3.50676C17.4124 3.66307 17.5001 3.87499 17.5 4.09592V18.333C17.5 18.554 17.4122 18.766 17.2559 18.9223C17.0996 19.0785 16.8877 19.1663 16.6667 19.1663H3.33333C3.11232 19.1663 2.90036 19.0785 2.74408 18.9223C2.5878 18.766 2.5 18.554 2.5 18.333V1.66634C2.5 1.44533 2.5878 1.23337 2.74408 1.07709C2.90036 0.920805 3.11232 0.833008 3.33333 0.833008ZM6.66667 8.33301H13.3333C13.4438 8.33301 13.5498 8.37691 13.628 8.45505C13.7061 8.53319 13.75 8.63917 13.75 8.74967V9.58301C13.75 9.69351 13.7061 9.7995 13.628 9.87764C13.5498 9.95578 13.4438 9.99967 13.3333 9.99967H6.66667C6.55616 9.99967 6.45018 9.95578 6.37204 9.87764C6.2939 9.7995 6.25 9.69351 6.25 9.58301V8.74967C6.25 8.63917 6.2939 8.53319 6.37204 8.45505C6.45018 8.37691 6.55616 8.33301 6.66667 8.33301ZM6.66667 12.4997H10.4167C10.4714 12.4997 10.5256 12.5105 10.5761 12.5314C10.6267 12.5523 10.6726 12.583 10.7113 12.6217C10.75 12.6604 10.7807 12.7063 10.8016 12.7569C10.8226 12.8074 10.8333 12.8616 10.8333 12.9163V13.7497C10.8333 13.8044 10.8226 13.8586 10.8016 13.9091C10.7807 13.9597 10.75 14.0056 10.7113 14.0443C10.6726 14.083 10.6267 14.1137 10.5761 14.1346C10.5256 14.1556 10.4714 14.1663 10.4167 14.1663H6.66667C6.55616 14.1663 6.45018 14.1224 6.37204 14.0443C6.2939 13.9662 6.25 13.8602 6.25 13.7497V12.9163C6.25 12.8058 6.2939 12.6999 6.37204 12.6217C6.45018 12.5436 6.55616 12.4997 6.66667 12.4997Z" fill="#1F2329"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

@@ -0,0 +1,96 @@
<script setup lang="ts">
import { propTypes } from '@/utils/propTypes'
import { computed, reactive, toRefs } from 'vue'
import { useI18n } from 'vue-i18n'
import { useEmitt } from '@/utils/useEmitt.ts'
const { t } = useI18n()
const props = defineProps({
property: {
type: Object,
default: () => ({}),
},
index: propTypes.number,
title: propTypes.string,
})
const { property } = toRefs(props)
const timeConfig = computed(() => {
let obj = Object.assign(
{
showType: 'datetime',
rangeSeparator: '-',
startPlaceholder: t('common.start_time'),
endPlaceholder: t('common.end_time'),
format: 'YYYY-MM-DD HH:mm:ss',
valueFormat: 'YYYY-MM-DD HH:mm:ss',
size: 'default',
placement: 'bottom-end',
},
property.value
)
return obj
})
const state = reactive({
modelValue: [],
})
const emits = defineEmits(['filter-change'])
const onChange = () => {
emits('filter-change', state.modelValue)
}
const clear = (index: number) => {
if (index !== props.index) return
state.modelValue = []
}
useEmitt({
name: 'clear-drawer_main',
callback: clear,
})
defineExpose({
clear,
})
</script>
<template>
<div class="draw-filter_time">
<span>{{ title }}</span>
<div class="filter-item">
<el-date-picker
key="drawer-time-filt"
v-model="state.modelValue"
:type="timeConfig.showType"
:range-separator="timeConfig.rangeSeparator"
:start-placeholder="timeConfig.startPlaceholder"
:end-placeholder="timeConfig.endPlaceholder"
:format="timeConfig.format"
:value-format="timeConfig.valueFormat"
:size="timeConfig.size"
:placement="timeConfig.placement"
@change="onChange"
/>
</div>
</div>
</template>
<style lang="less" scope>
.draw-filter_time {
margin-bottom: 16px;
> :nth-child(1) {
color: var(--deTextSecondary, #1f2329);
font-style: normal;
font-weight: 400;
font-size: 14px;
line-height: 22px;
white-space: nowrap;
}
.filter-item {
margin-top: 8px;
.ed-date-editor {
width: 100%;
}
}
}
</style>
@@ -0,0 +1,127 @@
<script setup lang="ts">
import { propTypes } from '@/utils/propTypes'
import { ElTreeSelect } from 'element-plus-secondary'
import { computed, reactive, ref, toRefs, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import { useEmitt } from '@/utils/useEmitt.ts'
const { t } = useI18n()
const props = defineProps({
optionList: propTypes.arrayOf(
propTypes.shape({
value: propTypes.string,
label: propTypes.string,
children: Array,
disabled: Boolean,
})
),
index: propTypes.number,
title: propTypes.string,
property: {
type: Object,
default: () => ({}),
},
})
const { property } = toRefs(props)
const treeConfig = computed(() => {
let obj = Object.assign(
{
checkStrictly: false,
showCheckbox: true,
checkOnClickNode: true,
placeholder: t('user.role'),
},
property.value
)
return obj
})
const state = reactive({
currentStatus: [],
activeStatus: [],
})
const emits = defineEmits(['filter-change'])
const filterTree = ref()
const treeChange = () => {
const nodes = state.currentStatus.map((id) => {
return filterTree.value?.getNode(id).data
})
// @ts-expect-error eslint-disable-next-line @typescript-eslint/ban-ts-comment
state.activeStatus = [...nodes]
emits(
'filter-change',
// @ts-expect-error eslint-disable-next-line @typescript-eslint/ban-ts-comment
state.activeStatus.map((item) => item.value)
)
}
const optionListNotSelect = computed(() => {
// @ts-expect-error eslint-disable-next-line @typescript-eslint/ban-ts-comment
return [...props.optionList]
})
const clear = (index: number) => {
if (index !== props.index) return
state.currentStatus = []
}
useEmitt({
name: 'clear-drawer_main',
callback: clear,
})
watch(
() => state.currentStatus,
() => {
treeChange()
},
{
immediate: true,
}
)
defineExpose({
clear,
})
</script>
<template>
<div class="draw-filter_tree">
<span>{{ title }}</span>
<div class="filter-item">
<el-tree-select
ref="filterTree"
v-model="state.currentStatus"
node-key="value"
:teleported="false"
style="width: 100%"
:data="optionListNotSelect"
:highlight-current="true"
multiple
:render-after-expand="false"
:placeholder="t('datasource.Please_select') + treeConfig.placeholder"
:show-checkbox="treeConfig.showCheckbox"
:check-strictly="treeConfig.checkStrictly"
:check-on-click-node="treeConfig.checkOnClickNode"
/>
</div>
</div>
</template>
<style lang="less" scope>
.draw-filter_tree {
margin-bottom: 16px;
> :nth-child(1) {
color: var(--deTextSecondary, #1f2329);
font-family: var(--de-custom_font, 'PingFang');
font-style: normal;
font-weight: 400;
font-size: 14px;
line-height: 22px;
white-space: nowrap;
}
.filter-item {
margin-top: 8px;
}
}
</style>
@@ -6,6 +6,8 @@ import DrawerFilter from '@/components/drawer-filter/src/DrawerFilter.vue'
import DrawerEnumFilter from '@/components/drawer-filter/src/DrawerEnumFilter.vue'
import { useEmitt } from '@/utils/useEmitt'
import { useI18n } from 'vue-i18n'
import DrawerTreeFilter from '@/components/drawer-filter/src/DrawerTreeFilter.vue'
import DrawerTimeFilter from '@/components/drawer-filter/src/DrawerTimeFilter.vue'
const { t } = useI18n()
const props = defineProps({
filterOptions: propTypes.arrayOf(
@@ -126,6 +128,14 @@ defineExpose({
direction="rtl"
>
<div v-for="(component, index) in componentList" :key="index">
<drawer-tree-filter
v-if="component.type === 'tree-select'"
:option-list="component.option"
:title="component.title"
:property="component.property"
:index="index"
@filter-change="(v) => filterChange(v, component.field, 'in')"
/>
<drawer-filter
v-if="component.type === 'select'"
:option-list="component.option"
@@ -141,6 +151,13 @@ defineExpose({
:index="index"
@filter-change="(v) => filterChange(v, component.field, 'in')"
/>
<drawer-time-filter
v-if="component.type === 'time'"
:title="component.title"
:property="component.property"
:index="index"
@filter-change="(v) => filterChange(v, component.field, component.operator)"
/>
</div>
<template #footer>
@@ -19,6 +19,8 @@ import workspace from '@/assets/svg/menu/icon_moments-categories_filled.svg'
import noWorkspace from '@/assets/svg/menu/icon_moments-categories_outlined.svg'
import set from '@/assets/svg/menu/icon_setting_filled.svg'
import noSet from '@/assets/svg/menu/icon-setting.svg'
import log from '@/assets/svg/menu/icon_log_filled.svg'
import noLog from '@/assets/svg/menu/icon_log_outlined.svg'
const iconMap = {
chat,
@@ -37,6 +39,8 @@ const iconMap = {
noModel,
embedded,
noEmbedded,
log,
noLog,
} as { [key: string]: any }
const MenuItem = defineComponent({
+3 -15
View File
@@ -95,6 +95,8 @@
"the_term_gmv": "Delete the term: {msg}?"
},
"common": {
"start_time": "Start Time",
"end_time": "End Time",
"require": "Required",
"zoom_in": "Zoom in",
"zoom_out": "Zoom out",
@@ -840,21 +842,7 @@
"success": "Success",
"failed": "Failed",
"failed_info": "Operation Failure Details",
"create_qa": "Create Q&A",
"delete_qa": "Delete Q&A",
"create_datasource": "Create Datasource",
"update_datasource": "Edit Datasource",
"delete_datasource": "Delete Datasource",
"create_dashboard": "Create Dashboard",
"update_dashboard": "Edit Dashboard",
"delete_dashboard": "Delete Dashboard",
"setting_create_user": "Add Member",
"setting_delete_user": "Remove Member",
"setting_create_rule": "Add Rule Group",
"setting_delete_rule": "Remove Rule Group",
"setting_update_rule": "Configure Rules",
"setting_update_rule_user": "Configure Users",
"setting_create_terminology": "Create Terminology"
"opt_time": "Operation Time"
},
"api_key": {
"info_tips": "The API Key is your credential for accessing the SQLBot API, with full permissions for your account. Please keep it secure! Do not disclose the API Key in any public channels to avoid security risks from unauthorized use.",
+3 -15
View File
@@ -95,6 +95,8 @@
"the_term_gmv": "용어를 삭제하시겠습니까: {msg}?"
},
"common": {
"start_time": "시작 시간",
"end_time": "종료 시간",
"require": "필수 입력 항목",
"zoom_in": "확대",
"zoom_out": "축소",
@@ -840,21 +842,7 @@
"success": "성공",
"failed": "실패",
"failed_info": "작업 실패 상세",
"create_qa": "Q&A 생성",
"delete_qa": "Q&A 삭제",
"create_datasource": "데이터 소스 생성",
"update_datasource": "데이터 소스 편집",
"delete_datasource": "데이터 소스 삭제",
"create_dashboard": "대시보드 생성",
"update_dashboard": "대시보드 편집",
"delete_dashboard": "대시보드 삭제",
"setting_create_user": "멤버 추가",
"setting_delete_user": "멤버 제거",
"setting_create_rule": "규칙 그룹 추가",
"setting_delete_rule": "규칙 그룹 제거",
"setting_update_rule": "규칙 설정",
"setting_update_rule_user": "사용자 설정",
"setting_create_terminology": "용어 생성"
"opt_time": "작업 시간"
},
"api_key": {
"info_tips": "API 키는 SQLBot API에 액세스하는 비밀키로 계정의 모든 권한을 갖고 있습니다. 꼭 안전하게 보관하세요! 외부 채널에 어떠한 방식으로도 API 키를 공개하지 마시고, 타인이 악용하여 보안 위협이 발생하는 것을 방지하세요.",
+3 -15
View File
@@ -95,6 +95,8 @@
"the_term_gmv": "是否删除术语:{msg}?"
},
"common": {
"start_time": "开始时间",
"end_time": "结束时间",
"require": "必填",
"zoom_in": "放大",
"zoom_out": "缩小",
@@ -841,21 +843,7 @@
"success": "成功",
"failed": "失败",
"failed_info": "操作失败详情",
"create_qa": "新建问数",
"delete_qa": "删除问数",
"create_datasource": "新建数据源",
"update_datasource": "编辑数据源",
"delete_datasource": "删除数据源",
"create_dashboard": "新建仪表板",
"update_dashboard": "编辑仪表板",
"delete_dashboard": "删除仪表板",
"setting_create_user": "添加成员",
"setting_delete_user": "移除成员",
"setting_create_rule": "添加规则组",
"setting_delete_rule": "移除规则组",
"setting_update_rule": "设置规则",
"setting_update_rule_user": "设置用户",
"setting_create_terminology": "新建术语"
"opt_time": "操作时间"
},
"api_key": {
"info_tips": "API Key 是您访问 SQLBot API 的密钥,具有账户的完全权限,请您务必妥善保管!不要以任何方式公开 API Key 到外部渠道,避免被他人利用造成安全威胁。",
+6 -6
View File
@@ -131,12 +131,6 @@ export const routes = [
component: Prompt,
meta: { title: t('prompt.customize_prompt_words') },
},
{
path: '/set/audit',
name: 'audit',
component: Audit,
meta: { title: t('audit.system_log') },
},
],
},
{
@@ -220,6 +214,12 @@ export const routes = [
},
],
},
{
path: 'audit',
name: 'audit',
component: Audit,
meta: { title: t('audit.system_log'), iconActive: 'log', iconDeActive: 'noLog' },
},
],
},
+26 -21
View File
@@ -25,6 +25,7 @@ onMounted(() => {
search()
initWorkspace()
initUsers()
initOptions()
})
const multipleTableRef = ref()
const fieldList = ref<any>([])
@@ -98,14 +99,17 @@ const toggleRowLoading = ref(false)
const configParams = () => {
let str = ''
let str_conditions = ''
if (keywords.value) {
str += `name=${keywords.value}`
}
state.conditions.forEach((ele: any) => {
str_conditions = ''
ele.value.forEach((itx: any) => {
str += str ? `__${itx}` : `${ele.field}=${itx}`
str_conditions += str_conditions ? `__${itx}` : `${ele.field}=${itx}`
})
str += str ? `&${str_conditions}` : `${str_conditions}`
})
if (str.length) {
@@ -150,27 +154,10 @@ const onErrorInfoOpen = (info: string) => {
const onErrorInfoClose = () => {
rowInfoDialog.value = false
}
const operationTypeOptions = [
{ id: 'create_qa', name: t('audit.create_qa') },
{ id: 'delete_qa', name: t('audit.delete_qa') },
{ id: 'create_datasource', name: t('audit.create_datasource') },
{ id: 'update_datasource', name: t('audit.update_datasource') },
{ id: 'delete_datasource', name: t('audit.delete_datasource') },
{ id: 'create_dashboard', name: t('audit.create_dashboard') },
{ id: 'update_dashboard', name: t('audit.update_dashboard') },
{ id: 'delete_dashboard', name: t('audit.delete_dashboard') },
{ id: 'setting_create_user', name: t('audit.setting_create_user') },
{ id: 'setting_delete_user', name: t('audit.setting_delete_user') },
{ id: 'setting_create_rule', name: t('audit.setting_create_rule') },
{ id: 'setting_delete_rule', name: t('audit.setting_delete_rule') },
{ id: 'setting_update_rule', name: t('audit.setting_update_rule') },
{ id: 'setting_update_rule_user', name: t('audit.setting_update_rule_user') },
{ id: 'setting_create_terminology', name: t('audit.setting_create_terminology') },
]
const filterOption = ref<any[]>([
{
type: 'select',
option: operationTypeOptions,
type: 'tree-select',
option: [],
field: 'opt_type_list',
title: t('audit.operation_type'),
operate: 'in',
@@ -202,6 +189,18 @@ const filterOption = ref<any[]>([
title: t('user.user_status'),
operate: 'in',
},
{
type: 'time',
option: [],
field: 'time_range',
title: t('audit.opt_time'),
operate: 'between',
property: {
showType: 'datetimerange',
format: 'YYYY-MM-DD HH:mm:ss',
valueFormat: 'x',
},
},
])
const fillFilterText = () => {
@@ -246,6 +245,12 @@ const initUsers = () => {
filterOption.value[1].option = [{ id: 1, name: 'Administrator' }, ...res.items]
})
}
const initOptions = () => {
audit.getOptions().then((res: any) => {
filterOption.value[0].option = [...res]
})
}
</script>
<template>
@@ -318,7 +323,7 @@ const initUsers = () => {
</div>
</template>
</el-table-column>
<el-table-column prop="word" :label="$t('audit.ip_address')" width="120">
<el-table-column prop="word" :label="$t('audit.ip_address')" width="140">
<template #default="scope">
{{ scope.row.ip_address }}
</template>