mirror of
https://gh-proxy.org/https://github.com/klinsmaya/SQLBot.git
synced 2026-11-08 01:06:59 +08:00
refactor:update recommended questions custom config. (#491)
This commit is contained in:
@@ -8,7 +8,8 @@ from sqlalchemy.orm import aliased
|
||||
|
||||
from apps.chat.models.chat_model import Chat, ChatRecord, CreateChat, ChatInfo, RenameChat, ChatQuestion, ChatLog, \
|
||||
TypeEnum, OperationEnum, ChatRecordResult
|
||||
from apps.datasource.models.datasource import CoreDatasource
|
||||
from apps.datasource.crud.recommended_problem import get_datasource_recommended, get_datasource_recommended_chart
|
||||
from apps.datasource.models.datasource import CoreDatasource, DsRecommendedProblem
|
||||
from apps.system.crud.assistant import AssistantOutDsFactory
|
||||
from common.core.deps import CurrentAssistant, SessionDep, CurrentUser
|
||||
from common.utils.utils import extract_nested_json
|
||||
@@ -70,6 +71,7 @@ def get_chart_config(session: SessionDep, chart_record_id: int):
|
||||
pass
|
||||
return {}
|
||||
|
||||
|
||||
def format_chart_fields(chart_info: dict):
|
||||
fields = []
|
||||
if chart_info.get('columns') and len(chart_info.get('columns')) > 0:
|
||||
@@ -88,6 +90,7 @@ def format_chart_fields(chart_info: dict):
|
||||
fields.append(column_str)
|
||||
return fields
|
||||
|
||||
|
||||
def get_last_execute_sql_error(session: SessionDep, chart_id: int):
|
||||
stmt = select(ChatRecord.error).where(and_(ChatRecord.chat_id == chart_id)).order_by(
|
||||
ChatRecord.create_time.desc()).limit(1)
|
||||
@@ -396,6 +399,12 @@ def create_chat(session: SessionDep, current_user: CurrentUser, create_chat_obj:
|
||||
record.finish = True
|
||||
record.create_time = datetime.datetime.now()
|
||||
record.create_by = current_user.id
|
||||
if ds.recommended_config == 2:
|
||||
questions = get_datasource_recommended_chart(session, ds.id)
|
||||
record.recommended_question = orjson.dumps(questions).decode()
|
||||
record.recommended_question_answer = orjson.dumps({
|
||||
"content": questions
|
||||
}).decode()
|
||||
|
||||
_record = ChatRecord(**record.model_dump())
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
from fastapi import APIRouter
|
||||
|
||||
from apps.datasource.crud.recommended_problem import get_datasource_recommended
|
||||
from common.core.deps import SessionDep
|
||||
from apps.datasource.crud.datasource import update_ds_recommended_config
|
||||
from apps.datasource.crud.recommended_problem import get_datasource_recommended, \
|
||||
save_recommended_problem
|
||||
from apps.datasource.models.datasource import RecommendedProblemBase
|
||||
from common.core.deps import SessionDep, CurrentUser
|
||||
|
||||
router = APIRouter(tags=["recommended_problem"], prefix="/recommended_problem")
|
||||
|
||||
@@ -10,3 +13,8 @@ router = APIRouter(tags=["recommended_problem"], prefix="/recommended_problem")
|
||||
async def datasource_recommended(session: SessionDep, ds_id: int):
|
||||
return get_datasource_recommended(session, ds_id)
|
||||
|
||||
|
||||
@router.post("/save_recommended_problem")
|
||||
async def datasource_recommended(session: SessionDep, user: CurrentUser, data_info: RecommendedProblemBase):
|
||||
update_ds_recommended_config(session, data_info.datasource_id, data_info.recommended_config)
|
||||
return save_recommended_problem(session, user, data_info)
|
||||
|
||||
@@ -109,6 +109,11 @@ def update_ds(session: SessionDep, trans: Trans, user: CurrentUser, ds: CoreData
|
||||
run_save_ds_embeddings([ds.id])
|
||||
return ds
|
||||
|
||||
def update_ds_recommended_config(session: SessionDep,datasource_id: int, recommended_config:int):
|
||||
record = session.exec(select(CoreDatasource).where(CoreDatasource.id == datasource_id)).first()
|
||||
record.recommended_config = recommended_config
|
||||
session.add(record)
|
||||
session.commit()
|
||||
|
||||
def delete_ds(session: SessionDep, id: int):
|
||||
term = session.exec(select(CoreDatasource).where(CoreDatasource.id == id)).first()
|
||||
|
||||
@@ -1,11 +1,31 @@
|
||||
import datetime
|
||||
|
||||
from sqlmodel import select
|
||||
|
||||
from common.core.deps import SessionDep
|
||||
from ..models.datasource import DsRecommendedProblem
|
||||
from common.core.deps import SessionDep, CurrentUser, Trans
|
||||
from ..models.datasource import DsRecommendedProblem, RecommendedProblemBase, RecommendedProblemBaseChat
|
||||
|
||||
|
||||
def get_datasource_recommended(session: SessionDep, ds_id: int):
|
||||
statement = select(DsRecommendedProblem).where(DsRecommendedProblem.datasource_id == ds_id)
|
||||
dsRecommendedProblem = session.exec(statement)
|
||||
dsRecommendedProblem = session.exec(statement).all()
|
||||
return dsRecommendedProblem
|
||||
|
||||
def get_datasource_recommended_chart(session: SessionDep, ds_id: int):
|
||||
statement = select(DsRecommendedProblem.question).where(DsRecommendedProblem.datasource_id == ds_id)
|
||||
dsRecommendedProblems = session.exec(statement).all()
|
||||
return dsRecommendedProblems
|
||||
|
||||
def save_recommended_problem(session: SessionDep,user: CurrentUser, data_info: RecommendedProblemBase):
|
||||
session.query(DsRecommendedProblem).filter(DsRecommendedProblem.datasource_id == data_info.datasource_id).delete(synchronize_session=False)
|
||||
problemInfo = data_info.problemInfo
|
||||
if problemInfo is not None:
|
||||
for problemItem in problemInfo:
|
||||
problemItem.id = None
|
||||
problemItem.create_time = datetime.datetime.now()
|
||||
problemItem.create_by = user.id
|
||||
record = DsRecommendedProblem(**problemItem.model_dump())
|
||||
session.add(record)
|
||||
session.flush()
|
||||
session.refresh(record)
|
||||
session.commit()
|
||||
|
||||
@@ -74,6 +74,18 @@ class CreateDatasource(BaseModel):
|
||||
tables: List[CoreTable] = []
|
||||
recommended_config: int = 1
|
||||
|
||||
class RecommendedProblemBase(BaseModel):
|
||||
datasource_id: int = None
|
||||
recommended_config: int = None
|
||||
problemInfo: List[DsRecommendedProblem] = []
|
||||
|
||||
|
||||
class RecommendedProblemBaseChat:
|
||||
def __init__(self, content):
|
||||
self.content = content
|
||||
|
||||
content: List[str] = []
|
||||
|
||||
|
||||
# edit local saved table and fields
|
||||
class TableObj(BaseModel):
|
||||
|
||||
@@ -3,5 +3,6 @@ import { request } from '@/utils/request'
|
||||
export const recommendedApi = {
|
||||
get_recommended_problem: (dsId: any) =>
|
||||
request.get(`/recommended_problem/get_datasource_recommended/${dsId}`),
|
||||
save_recommended_problem: (data: any) => request.post(`/recommended_problem/save`, data),
|
||||
save_recommended_problem: (data: any) =>
|
||||
request.post(`/recommended_problem/save_recommended_problem`, data),
|
||||
}
|
||||
|
||||
@@ -309,6 +309,7 @@
|
||||
}
|
||||
},
|
||||
"datasource": {
|
||||
"recommended_problem_tips": "Custom configuration requires at least one problem, each problem should be 2-200 characters",
|
||||
"recommended_problem_configuration": "Recommended Problem Configuration",
|
||||
"problem_generation_method": "Problem Generation Method",
|
||||
"ai_automatic_generation": "AI Automatic Generation",
|
||||
|
||||
@@ -309,6 +309,7 @@
|
||||
}
|
||||
},
|
||||
"datasource": {
|
||||
"recommended_problem_tips": "사용자 정의 구성으로 최소 한 개의 문제를 생성하세요, 각 문제는 2~200자로 작성",
|
||||
"recommended_problem_configuration": "추천 문제 구성",
|
||||
"problem_generation_method": "문제 생성 방식",
|
||||
"ai_automatic_generation": "AI 자동 생성",
|
||||
|
||||
@@ -309,6 +309,7 @@
|
||||
}
|
||||
},
|
||||
"datasource": {
|
||||
"recommended_problem_tips": "自定义配置至少一个问题,每个问题2-200个字符",
|
||||
"recommended_problem_configuration": "推荐问题配置",
|
||||
"problem_generation_method": "问题生成方式",
|
||||
"ai_automatic_generation": "AI 自动生成",
|
||||
|
||||
@@ -704,7 +704,7 @@ function onChatCreatedQuick(chat: ChatInfo) {
|
||||
}
|
||||
|
||||
function onChatCreated(chat: ChatInfo) {
|
||||
if (chat.records.length === 1) {
|
||||
if (chat.records.length === 1 && !chat.records[0].recommended_question) {
|
||||
getRecommendQuestions(chat.records[0].id)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ const onClickOutside = () => {
|
||||
</el-icon>
|
||||
{{ $t('datasource.edit') }}
|
||||
</div>
|
||||
<div class="item" style="display: none" @click.stop="handleRecommendation">
|
||||
<div class="item" @click.stop="handleRecommendation">
|
||||
<el-icon size="16">
|
||||
<icon_recommended_problem></icon_recommended_problem>
|
||||
</el-icon>
|
||||
@@ -287,7 +287,7 @@ const onClickOutside = () => {
|
||||
&::after {
|
||||
position: absolute;
|
||||
content: '';
|
||||
top: 40px;
|
||||
top: 80px !important;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
|
||||
@@ -328,6 +328,7 @@ useEmitt({
|
||||
</template>
|
||||
<RecommendedProblemConfigDialog
|
||||
ref="recommendedProblemConfigRef"
|
||||
@recommended-problem-change="search"
|
||||
></RecommendedProblemConfigDialog>
|
||||
<AddDrawer ref="addDrawerRef" @search="search"></AddDrawer>
|
||||
</div>
|
||||
|
||||
@@ -1,29 +1,35 @@
|
||||
<script setup lang="ts">
|
||||
import { reactive, ref } from 'vue'
|
||||
import { recommendedApi } from '@/api/recommendedApi.ts'
|
||||
import { Delete } from '@element-plus/icons-vue'
|
||||
import { ElMessage } from 'element-plus-secondary'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
const { t } = useI18n()
|
||||
|
||||
interface RecommendedProblem {
|
||||
id?: number
|
||||
question: string
|
||||
datasourceId?: any | undefined
|
||||
datasource_id?: any | undefined
|
||||
sort: number
|
||||
}
|
||||
|
||||
const emits = defineEmits(['recommendedProblemChange'])
|
||||
|
||||
const dialogShow = ref(false)
|
||||
|
||||
const state = reactive({
|
||||
dsId: null,
|
||||
datasource_id: null,
|
||||
recommended: {
|
||||
recommendedConfig: 1,
|
||||
recommended_config: 1,
|
||||
recommendedProblemList: [] as RecommendedProblem[],
|
||||
},
|
||||
})
|
||||
|
||||
const init = (params: any) => {
|
||||
dialogShow.value = true
|
||||
state.recommended.recommendedConfig = params.recommendedConfig
|
||||
state.dsId = params.id
|
||||
recommendedApi.get_recommended_problem(state.dsId).then((res: any) => {
|
||||
state.recommended.recommended_config = params.recommended_config || 1
|
||||
state.datasource_id = params.id
|
||||
recommendedApi.get_recommended_problem(state.datasource_id).then((res: any) => {
|
||||
state.recommended.recommendedProblemList = res
|
||||
})
|
||||
}
|
||||
@@ -31,27 +37,47 @@ const init = (params: any) => {
|
||||
const addRecommendedProblem = (): void => {
|
||||
state.recommended.recommendedProblemList.push({
|
||||
question: '',
|
||||
datasourceId: state.dsId,
|
||||
datasource_id: state.datasource_id,
|
||||
} as RecommendedProblem)
|
||||
}
|
||||
|
||||
const closeDialog = () => {
|
||||
dialogShow.value = false
|
||||
state.recommended = {
|
||||
recommendedConfig: 1,
|
||||
recommended_config: 1,
|
||||
recommendedProblemList: [] as RecommendedProblem[],
|
||||
}
|
||||
}
|
||||
const save = () => {
|
||||
recommendedApi.save_recommended_problem(state.recommended.recommendedProblemList)
|
||||
closeDialog()
|
||||
if (state.recommended.recommended_config == 2) {
|
||||
let checkProblem = false
|
||||
if (state.recommended.recommendedProblemList.length === 0) {
|
||||
checkProblem = true
|
||||
}
|
||||
state.recommended.recommendedProblemList.forEach((problem: RecommendedProblem): void => {
|
||||
if (problem.question.length > 200 || problem.question.length < 2) {
|
||||
checkProblem = true
|
||||
}
|
||||
})
|
||||
if (checkProblem) {
|
||||
ElMessage.error(t('datasource.recommended_problem_tips'))
|
||||
return
|
||||
}
|
||||
}
|
||||
recommendedApi
|
||||
.save_recommended_problem({
|
||||
recommended_config: state.recommended.recommended_config,
|
||||
datasource_id: state.datasource_id,
|
||||
problemInfo: state.recommended.recommendedProblemList,
|
||||
})
|
||||
.then(() => {
|
||||
emits('recommendedProblemChange')
|
||||
closeDialog()
|
||||
})
|
||||
}
|
||||
const deleteRecommendedProblem = (index: number): void => {
|
||||
state.recommended.recommendedProblemList.splice(index, 1)
|
||||
}
|
||||
|
||||
const form = ref<any>({
|
||||
id: null,
|
||||
question: '',
|
||||
sort: null,
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
init,
|
||||
@@ -69,31 +95,40 @@ defineExpose({
|
||||
@before-closed="closeDialog"
|
||||
>
|
||||
<el-form-item :label="$t('datasource.problem_generation_method')" prop="mode">
|
||||
<el-radio-group v-model="form.mode">
|
||||
<el-radio value="1">{{ $t('datasource.ai_automatic_generation') }}</el-radio>
|
||||
<el-radio value="2">{{ $t('datasource.user_defined') }}</el-radio>
|
||||
<el-radio-group v-model="state.recommended.recommended_config">
|
||||
<el-radio :value="1">{{ $t('datasource.ai_automatic_generation') }}</el-radio>
|
||||
<el-radio :value="2">{{ $t('datasource.user_defined') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-for="(recommendedItem, index) in state.recommended.recommendedProblemList"
|
||||
:key="index"
|
||||
prop="mode"
|
||||
>
|
||||
<el-input
|
||||
v-model="recommendedItem.question"
|
||||
clearable
|
||||
:placeholder="$t('datasource.question_tips')"
|
||||
<template v-if="state.recommended.recommended_config === 2">
|
||||
<el-form-item
|
||||
v-for="(recommendedItem, index) in state.recommended.recommendedProblemList"
|
||||
:key="index"
|
||||
prop="mode"
|
||||
>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<div>
|
||||
<el-button text @click="addRecommendedProblem">
|
||||
{{ $t('datasource.add_question') }}</el-button
|
||||
>
|
||||
</div>
|
||||
<el-row class="question-item">
|
||||
<el-input
|
||||
v-model="recommendedItem.question"
|
||||
max="200"
|
||||
min="2"
|
||||
class="input-item"
|
||||
clearable
|
||||
:placeholder="$t('datasource.question_tips')"
|
||||
>
|
||||
</el-input>
|
||||
<el-icon class="delete-item"><Delete @click="deleteRecommendedProblem(index)" /></el-icon>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
<div v-if="state.recommended.recommendedProblemList.length < 4">
|
||||
<el-button text @click="addRecommendedProblem">
|
||||
{{ $t('datasource.add_question') }}</el-button
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div style="display: flex; justify-content: flex-end; margin-top: 20px">
|
||||
<el-button secondary @click="closeDialog">{{ $t('common.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="save">{{ $t('model.add') }}</el-button>
|
||||
<el-button type="primary" @click="save">{{ $t('common.save') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
@@ -104,6 +139,21 @@ defineExpose({
|
||||
background-color: #fff;
|
||||
padding: 0 12px;
|
||||
}
|
||||
.question-item {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.input-item {
|
||||
width: calc(100% - 40px);
|
||||
}
|
||||
.delete-item {
|
||||
margin-left: 8px;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.value-input {
|
||||
.ed-input-group__append {
|
||||
|
||||
Reference in New Issue
Block a user