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
11 changes: 10 additions & 1 deletion backend/apps/chat/curd/chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@

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
Expand Down Expand Up @@ -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:
Expand All @@ -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)
Expand Down Expand Up @@ -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())

Expand Down
12 changes: 10 additions & 2 deletions backend/apps/datasource/api/recommended_problem.py
Original file line number Diff line number Diff line change
@@ -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")

Expand All @@ -10,3 +13,8 @@
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)
5 changes: 5 additions & 0 deletions backend/apps/datasource/crud/datasource.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
26 changes: 23 additions & 3 deletions backend/apps/datasource/crud/recommended_problem.py
Original file line number Diff line number Diff line change
@@ -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()
12 changes: 12 additions & 0 deletions backend/apps/datasource/models/datasource.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/api/recommendedApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}
1 change: 1 addition & 0 deletions frontend/src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,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",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/i18n/ko-KR.json
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@
}
},
"datasource": {
"recommended_problem_tips": "사용자 정의 구성으로 최소 한 개의 문제를 생성하세요, 각 문제는 2~200자로 작성",
"recommended_problem_configuration": "추천 문제 구성",
"problem_generation_method": "문제 생성 방식",
"ai_automatic_generation": "AI 자동 생성",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/i18n/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@
}
},
"datasource": {
"recommended_problem_tips": "自定义配置至少一个问题,每个问题2-200个字符",
"recommended_problem_configuration": "推荐问题配置",
"problem_generation_method": "问题生成方式",
"ai_automatic_generation": "AI 自动生成",
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/views/chat/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/views/ds/Card.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -287,7 +287,7 @@ const onClickOutside = () => {
&::after {
position: absolute;
content: '';
top: 40px;
top: 80px !important;
left: 0;
width: 100%;
height: 1px;
Expand Down
1 change: 1 addition & 0 deletions frontend/src/views/ds/Datasource.vue
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ useEmitt({
</template>
<RecommendedProblemConfigDialog
ref="recommendedProblemConfigRef"
@recommended-problem-change="search"
></RecommendedProblemConfigDialog>
<AddDrawer ref="addDrawerRef" @search="search"></AddDrawer>
</div>
Expand Down
122 changes: 86 additions & 36 deletions frontend/src/views/ds/RecommendedProblemConfigDialog.vue
Original file line number Diff line number Diff line change
@@ -1,57 +1,83 @@
<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
})
}

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,
Expand All @@ -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>
Expand All @@ -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 {
Expand Down