refactor: 智能问数优化 (#17228)

This commit is contained in:
王嘉豪
2025-10-20 18:24:12 +08:00
committed by GitHub
parent e05ade7bab
commit b792f85cfa
8 changed files with 132 additions and 21 deletions

View File

@@ -57,7 +57,6 @@ public interface DataSetAssistantMapper {
left join `core_dataset_table` cdt on cdg.id = cdt.dataset_group_id
left join `core_dataset_table_field` cdtf on cdtf.dataset_group_id = cdg.id and (cdtf.dataset_table_id is NULL or cdtf.dataset_table_id = cdt.id)
inner join `core_datasource` cd on cdt.datasource_id = cd.id
where cdg.is_cross != 1 and (cd.STATUS IS NULL OR cd.STATUS != 'Error')
${ew.customSqlSegment}
"""
)
@@ -120,8 +119,6 @@ public interface DataSetAssistantMapper {
INNER JOIN `core_dataset_group` cdg ON cdg.id = cdt.dataset_group_id
AND cdg.is_cross != 1
INNER JOIN `core_dataset_table_field` cdtf ON cdtf.dataset_group_id = cdg.id and (cdtf.dataset_table_id is NULL or cdtf.dataset_table_id = cdt.id)
where not exists( select 1 from user_ds_permissions ds_p where cd.id = ds_p.resource_id )
and not exists( select 1 from user_dg_permissions dg_p where cdg.id = dg_p.resource_id )
${ew.customSqlSegment}
""")
List<Map<String, Object>> queryCommunity(@Param("ew") QueryWrapper queryWrapper);

View File

@@ -179,11 +179,17 @@ public class DatasetSQLBotManage {
if (!isAdmin) {
return null;
}
queryWrapper.eq("cdg.is_cross", 0)
.and(wrapper -> wrapper.isNull("cd.STATUS").or().ne("cd.STATUS", "Error"));
list = dataSetAssistantMapper.queryAll(queryWrapper);
} else if (!model) {
if (!isAdmin) {
return null;
}
queryWrapper.apply("""
not exists( select 1 from user_ds_permissions ds_p where cd.id = ds_p.resource_id )
and not exists( select 1 from user_dg_permissions dg_p where cdg.id = dg_p.resource_id )
""");
list = dataSetAssistantMapper.queryCommunity(queryWrapper);
} else {
boolean isRootRole = isAdmin;

View File

@@ -2930,6 +2930,7 @@ export default {
column_name: 'Field name'
},
visualization: {
sqlbot_query_tips: 'Smart Data Query',
cur_sq_dataset: 'Currently selected dataset:',
data_match_type: 'Data match type',
select_resource: 'Select {0}',

View File

@@ -2849,6 +2849,7 @@ export default {
column_name: '欄位名稱'
},
visualization: {
sqlbot_query_tips: '智能問數',
cur_sq_dataset: '當前選擇的數據集:',
data_match_type: '資料匹配方式',
select_resource: '請選擇{0}',

View File

@@ -2858,6 +2858,7 @@ export default {
column_name: '字段名称'
},
visualization: {
sqlbot_query_tips: '智能问数',
cur_sq_dataset: '当前选择的数据集:',
data_match_type: '数据匹配方式',
select_resource: '请选择{0}',

View File

@@ -0,0 +1,37 @@
<template>
<div class="dataease-v2-embedded-assistant-sqlbot-head">
<div class="head-inner">
<span>{{ t('visualization.sqlbot_query_tips') }}</span>
</div>
</div>
</template>
<script lang="ts" setup>
import { useI18n } from '@/hooks/web/useI18n'
const { t } = useI18n()
</script>
<style lang="less" scoped>
.dataease-v2-embedded-assistant-sqlbot-head {
width: calc(100% - 140px);
left: 0;
top: 0;
z-index: 300;
line-height: 56px;
background: #fff;
height: 56px;
display: flex;
align-items: center;
position: absolute;
.head-inner {
display: flex;
width: 100%;
font-size: 16px;
align-items: center;
background: #1cba901a;
line-height: 56px;
font-weight: bold;
padding: 0 16px;
}
}
</style>

View File

@@ -4,15 +4,33 @@ import { onMounted, reactive } from 'vue'
import { storeToRefs } from 'pinia'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { useI18n } from '@/hooks/web/useI18n'
import { Refresh } from '@element-plus/icons-vue'
const { t } = useI18n()
const dvMainStore = dvMainStoreWithOut()
const { dvInfo } = storeToRefs(dvMainStore)
const props = defineProps({
assistantId: {
type: String,
required: false
}
})
const newChat = (param?: any) => {
const handler = window['sqlbot_assistant_handler']
if (handler && handler[props.assistantId]) {
handler[props.assistantId].createConversation(param)
}
}
const init = () => {
if (dvInfo.value.id) {
findDvSqlBotDataset(dvInfo.value.id).then(res => {
state.baseDatasetInfo = res.data
state.curDatasetInfo = state.baseDatasetInfo[0]
state.curDatasetId = state.curDatasetInfo.tableId
datasetSelect()
})
}
@@ -28,8 +46,18 @@ const state = reactive({
})
const datasetSelect = () => {
localStorage.setItem('dsId', state.curDatasetInfo.dsId)
localStorage.setItem('tableId', state.curDatasetInfo.tableId)
state.baseDatasetInfo.forEach(datasetInfo => {
if (datasetInfo.tableId === state.curDatasetId) {
localStorage.setItem('dsId', state.curDatasetInfo.dsId)
localStorage.setItem('tableId', state.curDatasetInfo.tableId)
newChat()
}
})
}
const refresh = () => {
init()
newChat()
}
</script>
@@ -37,7 +65,7 @@ const datasetSelect = () => {
<el-row class="de-sq-assistant">
<span class="de-sq-tips">{{ t('visualization.cur_sq_dataset') }}</span>
<el-select
v-model="state.curDatasetInfo"
v-model="state.curDatasetId"
class="de-sq-select"
:teleported="false"
size="small"
@@ -47,13 +75,28 @@ const datasetSelect = () => {
v-for="option in state.baseDatasetInfo"
size="mini"
:key="option.tableId"
:value="option"
:value="option.tableId"
:label="option.tableName"
></el-option>
</el-select>
<div class="de-sq-button">
<el-button
size="small"
:title="t('visualization.refresh')"
:icon="Refresh"
text
@click="refresh"
/>
</div>
</el-row>
</template>
<style lang="less">
.assistant-chat-main {
padding: 0 0 40px;
}
</style>
<style scoped lang="less">
.de-sq-assistant {
position: absolute;
@@ -63,6 +106,7 @@ const datasetSelect = () => {
width: 100%;
z-index: 10;
color: #646a73;
background-color: #fff;
font-size: 14px;
}
@@ -71,7 +115,18 @@ const datasetSelect = () => {
line-height: 28px;
}
.de-sq-icon {
font-size: 14px;
line-height: 28px;
}
.de-sq-select {
width: 150px;
width: auto;
min-width: 150px;
max-width: 400px;
}
.de-sq-button {
margin-left: 4px;
}
</style>

View File

@@ -10,6 +10,7 @@ import { createApp, onMounted, onUnmounted, reactive, ref } from 'vue'
import request from '@/config/axios'
import { useUserStoreWithOut } from '@/store/modules/user'
import SQDatasetSelect from '@/views/sqlbot/SQDatasetSelect.vue'
import AssistantHead from '@/views/sqlbot/AssistantHead.vue'
const userStore = useUserStoreWithOut()
const loading = ref(true)
const state = reactive({
@@ -17,7 +18,8 @@ const state = reactive({
id: '',
enabled: false,
valid: false,
historyShow: false
historyShow: false,
sqlbotScript: null
})
const sqlbotExist = ref(false)
const timer = ref()
@@ -49,7 +51,6 @@ const loadSqlbotPage = () => {
mountedEmbeddedPage()
return
}
console.log('==test==0=')
const script = document.createElement('script')
script.defer = true
script.async = true
@@ -62,33 +63,35 @@ const loadSqlbotPage = () => {
userStore.getUid
}&t=${new Date().getTime()}`
script.onload = () => {
console.log('==test==00=')
mountedEmbeddedPage()
}
document.head.appendChild(script)
state.sqlbotScript = script
}
const mountedEmbeddedPage = () => {
if (sqlbotExist.value) {
return
}
const tempTimer = setTimeout(() => {
console.log('==test==1=' + window['sqlbot_assistant_handler'])
if (window['sqlbot_assistant_handler']) {
console.log('==test==2=')
// window['sqlbot_assistant_handler'].mounted('#dataease-v2-embedded-assistant-sqlbot', {
// embeddedId: state.id,
// online: true,
// userFlag: userStore.getUid
// })
const container = document.getElementById('sqlbot-assistant-chat-container')
if (container) {
// 数据集选择
const mountPoint = document.createElement('div')
mountPoint.id = 'chat-component-mount-point'
container.appendChild(mountPoint)
const chatApp = createApp(SQDatasetSelect)
const chatApp = createApp(SQDatasetSelect, {
// 在这里传递 props
assistantId: state.id
})
chatApp.mount(mountPoint)
// 头部样式
const mountPointHead = document.createElement('div')
mountPointHead.id = 'chat-component-mount-point-head'
container.appendChild(mountPointHead)
const chatHeadApp = createApp(AssistantHead)
chatHeadApp.mount(mountPointHead)
}
loading.value = false
sqlbotExist.value = true
@@ -111,6 +114,16 @@ onUnmounted(() => {
clearInterval(timer.value)
timer.value = null
}
// 移除 script 标签
if (state.sqlbotScript && state.sqlbotScript.parentNode) {
state.sqlbotScript.parentNode.removeChild(state.sqlbotScript)
}
// 可选:清理全局变量
if (window['sqlbot_assistant_handler']) {
delete window['sqlbot_assistant_handler']
}
})
</script>