Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions backend/apps/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from apps.terminology.api import terminology
from apps.settings.api import base


api_router = APIRouter()
api_router.include_router(login.router)
api_router.include_router(user.router)
Expand Down
9 changes: 5 additions & 4 deletions backend/apps/chat/api/chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,15 @@ async def rename(session: SessionDep, chat: RenameChat):
)


@router.delete("/{chart_id}", response_model=str, summary=f"{PLACEHOLDER_PREFIX}delete_chat")
@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,
resource_id_expr="chart_id"
resource_id_expr="chart_id",
remark_expr="brief"
))
async def delete(session: SessionDep, chart_id: int):
async def delete(session: SessionDep, chart_id: int, brief: str):
try:
return delete_chat(session=session, chart_id=chart_id)
except Exception as e:
Expand Down Expand Up @@ -158,7 +159,7 @@ def _err(_e: Exception):

@router.get("/recent_questions/{datasource_id}", response_model=List[str],
summary=f"{PLACEHOLDER_PREFIX}get_recommend_questions")
@require_permissions(permission=SqlbotPermission(type='ds', keyExpression="datasource_id"))
#@require_permissions(permission=SqlbotPermission(type='ds', keyExpression="datasource_id"))
async def recommend_questions(session: SessionDep, current_user: CurrentUser,
datasource_id: int = Path(..., description=f"{PLACEHOLDER_PREFIX}ds_id")):
return list_recent_questions(session=session, current_user=current_user, datasource_id=datasource_id)
Expand Down
7 changes: 4 additions & 3 deletions backend/apps/dashboard/api/dashboard_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,15 @@ async def update_resource_api(session: SessionDep, user: CurrentUser, dashboard:
return update_resource(session=session, user=user, dashboard=dashboard)


@router.delete("/delete_resource/{resource_id}")
@router.delete("/delete_resource/{resource_id}/{name}")
@system_log(LogConfig(
operation_type=OperationType.DELETE_DASHBOARD,
operation_detail=OperationDetails.DELETE_DASHBOARD_DETAILS,
module=OperationModules.DASHBOARD,
resource_id_expr="resource_id"
resource_id_expr="resource_id",
remark_expr="name"
))
async def delete_resource_api(session: SessionDep, resource_id: str):
async def delete_resource_api(session: SessionDep, resource_id: str, name: str):
return delete_resource(session, resource_id)


Expand Down
40 changes: 27 additions & 13 deletions backend/apps/datasource/api/datasource.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
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

router = APIRouter(tags=["Datasource"], prefix="/datasource")
path = settings.EXCEL_PATH

Expand Down Expand Up @@ -107,15 +108,16 @@ def inner():
return await asyncio.to_thread(inner)


@router.post("/delete/{id}", response_model=None, summary=f"{PLACEHOLDER_PREFIX}ds_delete")
@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,
module=OperationModules.DATASOURCE,
resource_id_expr="id"
resource_id_expr="id",
remark_expr="name"
))
async def delete(session: SessionDep, id: int = Path(..., description=f"{PLACEHOLDER_PREFIX}ds_id")):
async def delete(session: SessionDep, id: int = Path(..., description=f"{PLACEHOLDER_PREFIX}ds_id"), name: str = None):
return delete_ds(session, id)


Expand Down Expand Up @@ -385,6 +387,7 @@ def insert_pg(df, tableName, engine):


t_sheet = "数据表列表"
t_s_col = "Sheet名称"
t_n_col = "表名"
t_c_col = "表备注"
f_n_col = "字段名"
Expand All @@ -404,7 +407,8 @@ def inner():
if id == 0: # download template
file_name = '批量上传备注'
df_list = [
{'sheet': t_sheet, 'c1_h': t_n_col, 'c2_h': t_c_col, 'c1': ["user", "score"],
{'sheet': t_sheet, 'c0_h': t_s_col, 'c1_h': t_n_col, 'c2_h': t_c_col, 'c0': ["数据表1", "数据表2"],
'c1': ["user", "score"],
'c2': ["用来存放用户信息的数据表", "用来存放用户课程信息的数据表"]},
{'sheet': '数据表1', 'c1_h': f_n_col, 'c2_h': f_c_col, 'c1': ["id", "name"],
'c2': ["用户id", "用户姓名"]},
Expand All @@ -419,14 +423,15 @@ def inner():
raise HTTPException(400, "No tables")

df_list = []
df1 = {'sheet': t_sheet, 'c1_h': t_n_col, 'c2_h': t_c_col, 'c1': [], 'c2': []}
df1 = {'sheet': t_sheet, 'c0_h': t_s_col,'c1_h': t_n_col, 'c2_h': t_c_col,'c0': [], 'c1': [], 'c2': []}
df_list.append(df1)
for table in tables:
for index, table in enumerate(tables):
df1['c0'].append(f"Sheet{index}")
df1['c1'].append(table.table_name)
df1['c2'].append(table.custom_comment)

fields = session.query(CoreField).filter(CoreField.table_id == table.id).all()
df_fields = {'sheet': table.table_name, 'c1_h': f_n_col, 'c2_h': f_c_col, 'c1': [], 'c2': []}
df_fields = {'sheet': f"Sheet{index}", 'c1_h': f_n_col, 'c2_h': f_c_col, 'c1': [], 'c2': []}
for field in fields:
df_fields['c1'].append(field.field_name)
df_fields['c2'].append(field.custom_comment)
Expand All @@ -435,10 +440,14 @@ def inner():
# build dataframe and export
output = io.BytesIO()

with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
for df in df_list:
pd.DataFrame({df['c1_h']: df['c1'], df['c2_h']: df['c2']}).to_excel(writer, sheet_name=df['sheet'],
index=False)
with (pd.ExcelWriter(output, engine='xlsxwriter') as writer):
for index, df in enumerate(df_list):
if index == 0:
pd.DataFrame({df['c0_h']: df['c0'], df['c1_h']: df['c1'], df['c2_h']: df['c2']}
).to_excel(writer, sheet_name=df['sheet'], index=False)
else:
pd.DataFrame({df['c1_h']: df['c1'], df['c2_h']: df['c2']}).to_excel(writer, sheet_name=df['sheet'],
index=False)

output.seek(0)

Expand Down Expand Up @@ -484,10 +493,14 @@ async def upload_ds_schema(session: SessionDep, id: int = Path(..., description=

# print(field_sheets)

# sheet table mapping
sheet_table_map = {}

# get data and update
# update table comment
if table_sheet and len(table_sheet) > 0:
for table in table_sheet:
sheet_table_map[table[t_s_col]] = table[t_n_col]
session.query(CoreTable).filter(
and_(CoreTable.ds_id == id, CoreTable.table_name == table[t_n_col])).update(
{'custom_comment': table[t_c_col]})
Expand All @@ -497,8 +510,9 @@ async def upload_ds_schema(session: SessionDep, id: int = Path(..., description=
for fields in field_sheets:
if len(fields['data']) > 0:
# get table id
table_name = sheet_table_map[fields['sheet_name']]
table = session.query(CoreTable).filter(
and_(CoreTable.ds_id == id, CoreTable.table_name == fields['sheet_name'])).first()
and_(CoreTable.ds_id == id, CoreTable.table_name == table_name)).first()
if table:
for field in fields['data']:
session.query(CoreField).filter(
Expand All @@ -510,4 +524,4 @@ async def upload_ds_schema(session: SessionDep, id: int = Path(..., description=

return True
except Exception as e:
raise HTTPException(status_code=500, detail=f"解析 Excel 失败: {str(e)}")
raise HTTPException(status_code=500, detail=f"Parse Excel Failed: {str(e)}")
13 changes: 9 additions & 4 deletions backend/apps/system/api/aimodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
router = APIRouter(tags=["system_model"], prefix="/system/aimodel")

@router.post("/status", include_in_schema=False)
@require_permissions(permission=SqlbotPermission(role=['admin']))
async def check_llm(info: AiModelCreator, trans: Trans):
async def generate():
try:
Expand Down Expand Up @@ -92,6 +93,7 @@ async def query(
return items

@router.get("/{id}", response_model=AiModelEditor, summary=f"{PLACEHOLDER_PREFIX}system_model_query", description=f"{PLACEHOLDER_PREFIX}system_model_query")
@require_permissions(permission=SqlbotPermission(role=['admin']))
async def get_model_by_id(
session: SessionDep,
id: int = Path(description="ID")
Expand All @@ -107,10 +109,13 @@ async def get_model_by_id(
config_list = [AiModelConfigItem(**item) for item in raw]
except Exception:
pass
if db_model.api_key:
db_model.api_key = await sqlbot_decrypt(db_model.api_key)
if db_model.api_domain:
db_model.api_domain = await sqlbot_decrypt(db_model.api_domain)
try:
if db_model.api_key:
db_model.api_key = await sqlbot_decrypt(db_model.api_key)
if db_model.api_domain:
db_model.api_domain = await sqlbot_decrypt(db_model.api_domain)
except Exception:
pass
data = AiModelDetail.model_validate(db_model).model_dump(exclude_unset=True)
data.pop("config", None)
data["config_list"] = config_list
Expand Down
13 changes: 7 additions & 6 deletions backend/apps/system/middleware/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,12 @@ async def validateEmbedded(self, param: str, trans: I18n) -> tuple[any]:
return False, f"Miss account payload error!"
account = payload['account']
with Session(engine) as session:
assistant_info = await get_assistant_info(session=session, assistant_id=embeddedId)
assistant_info = AssistantModel.model_validate(assistant_info)
payload = jwt.decode(
param, assistant_info.app_secret, algorithms=[security.ALGORITHM]
)
assistant_info = AssistantHeader.model_validate(assistant_info.model_dump(exclude_unset=True))
""" session_user = await get_user_info(session = session, user_id = token_data.id)
session_user = UserInfoDTO.model_validate(session_user) """
session_user = get_user_by_account(session = session, account=account)
Expand All @@ -220,12 +226,7 @@ async def validateEmbedded(self, param: str, trans: I18n) -> tuple[any]:
if not session_user.oid or session_user.oid == 0:
message = trans('i18n_login.no_associated_ws', msg = trans('i18n_concat_admin'))
raise Exception(message)
assistant_info = await get_assistant_info(session=session, assistant_id=embeddedId)
assistant_info = AssistantModel.model_validate(assistant_info)
payload = jwt.decode(
param, assistant_info.app_secret, algorithms=[security.ALGORITHM]
)
assistant_info = AssistantHeader.model_validate(assistant_info.model_dump(exclude_unset=True))

return True, session_user, assistant_info
except Exception as e:
SQLBotLogUtil.exception(f"Embedded validation error: {str(e)}")
Expand Down
43 changes: 43 additions & 0 deletions backend/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -121,5 +121,48 @@
},
"i18n_authentication": {
"record_not_exist": "{msg} record does not exist. Please save it first!"
},
"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",
"operation_type_name": "Operation Type",
"operation_detail_info": "Operation Details",
"user_name": "Operating User",
"oid_name": "Workspace",
"operation_status_name": "Operation Status",
"error_message": "Error Message",
"ip_address": "IP Address",
"create_time": "Operation Time"
}
}
43 changes: 43 additions & 0 deletions backend/locales/ko-KR.json
Original file line number Diff line number Diff line change
Expand Up @@ -121,5 +121,48 @@
},
"i18n_authentication": {
"record_not_exist": "{msg} 기록이 존재하지 않습니다. 먼저 저장해 주세요!"
},
"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": "시스템 로그",
"operation_type_name": "작업 유형",
"operation_detail_info": "작업 상세 정보",
"user_name": "작업 사용자",
"oid_name": "작업 공간",
"operation_status_name": "작업 상태",
"error_message": "오류 메시지",
"ip_address": "IP 주소",
"create_time": "작업 시간"
}
}
45 changes: 44 additions & 1 deletion backend/locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -121,5 +121,48 @@
},
"i18n_authentication": {
"record_not_exist": "{msg} 记录不存在,请先保存!"
},
"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": "操作详情",
"user_name": "操作用户",
"oid_name": "工作空间",
"operation_status_name": "操作状态",
"error_message": "错误信息",
"ip_address": "IP 地址",
"create_time": "操作时间"
}
}
}
12 changes: 12 additions & 0 deletions frontend/src/api/audit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { request } from '@/utils/request'

export const audit = {
getList: (pageNum: any, pageSize: any, params: any) =>
request.get(`/system/audit/page/${pageNum}/${pageSize}${params}`),
export2Excel: (params: any) =>
request.get(`/system/audit/export`, {
params,
responseType: 'blob',
requestOptions: { customError: true },
}),
}
Loading