Skip to content

Commit 1f6e2d0

Browse files
committed
Merge branch 'main' of https://github.com/dataease/SQLBot
2 parents f695dba + 13dbe95 commit 1f6e2d0

File tree

5 files changed

+165
-17
lines changed

5 files changed

+165
-17
lines changed

backend/apps/chat/models/chat_model.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
from datetime import datetime
22
from typing import List, Optional
33

4+
from fastapi import Body
45
from pydantic import BaseModel
56
from sqlalchemy import Column, Integer, Text, BigInteger, DateTime, Identity, Boolean
67
from sqlmodel import SQLModel, Field
78

9+
from apps.template.filter.generator import get_permissions_template
810
from apps.template.generate_analysis.generator import get_analysis_template
911
from apps.template.generate_chart.generator import get_chart_template
1012
from apps.template.generate_guess_question.generator import get_guess_question_template
1113
from apps.template.generate_predict.generator import get_predict_template
1214
from apps.template.generate_sql.generator import get_sql_template
1315
from apps.template.select_datasource.generator import get_datasource_template
14-
from apps.template.filter.generator import get_permissions_template
1516

1617

1718
class Chat(SQLModel, table=True):
@@ -24,7 +25,8 @@ class Chat(SQLModel, table=True):
2425
chat_type: str = Field(max_length=20, default="chat") # chat, datasource
2526
datasource: int = Field(sa_column=Column(BigInteger, nullable=True))
2627
engine_type: str = Field(max_length=64)
27-
origin: Optional[int] = Field(sa_column=Column(Integer, nullable=False, default=0)) # 0: default, 1: mcp, 2: assistant
28+
origin: Optional[int] = Field(
29+
sa_column=Column(Integer, nullable=False, default=0)) # 0: default, 1: mcp, 2: assistant
2830

2931

3032
class ChatRecord(SQLModel, table=True):
@@ -152,13 +154,14 @@ def filter_user_question(self):
152154

153155

154156
class ChatQuestion(AiModelQuestion):
155-
question: str = ''
156-
chat_id: int = 0
157+
question: str = Body(description='用户提问')
158+
chat_id: int = Body(description='会话ID')
159+
157160

158161
class ChatMcp(ChatQuestion):
159-
token: str = ''
162+
token: str = Body(description='token')
160163

161164

162165
class ChatStart(BaseModel):
163-
username: str = ''
164-
password: str = ''
166+
username: str = Body(description='用户名')
167+
password: str = Body(description='密码')

backend/apps/system/crud/assistant.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,24 @@ def get_simple_ds_list(self):
132132
def get_db_schema(self, ds_id: int) -> str:
133133
ds = self.get_ds(ds_id)
134134
schema_str = ""
135-
db_name = ds.db_schema
135+
#db_name = ds.db_schema
136+
db_name = ds.db_schema if ds.db_schema is not None and ds.db_schema != "" else ds.dataBase
136137
schema_str += f"【DB_ID】 {db_name}\n【Schema】\n"
137138
for table in ds.tables:
138-
schema_str += f"# Table: {db_name}.{table.name}"
139-
schema_str += f", {table.comment}\n[\n"
139+
schema_str += f"# Table: {db_name}.{table.name}" if ds.type != "mysql" else f"# Table: {table.name}"
140+
table_comment = table.comment
141+
if table_comment == '':
142+
schema_str += '\n[\n'
143+
else:
144+
schema_str += f", {table_comment}\n[\n"
145+
140146
field_list = []
141147
for field in table.fields:
142-
field_list.append(f"({field.name}:{field.type}, {field.comment})")
148+
field_comment = field.comment
149+
if field_comment == '':
150+
field_list.append(f"({field.name}:{field.type})")
151+
else:
152+
field_list.append(f"({field.name}:{field.type}, {field_comment})")
143153
schema_str += ",\n".join(field_list)
144154
schema_str += '\n]\n'
145155
return schema_str

backend/common/utils/utils.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ def extract_nested_json(text):
7676

7777
def string_to_numeric_hash(text: str, bits: Optional[int] = 64) -> int:
7878
hash_bytes = hashlib.sha256(text.encode()).digest()
79-
return int.from_bytes(hash_bytes[:bits//8], byteorder='big')
79+
hash_num = int.from_bytes(hash_bytes, byteorder='big')
80+
max_bigint = 2**63 - 1
81+
return hash_num % max_bigint
8082

8183

8284
def setup_logging():

frontend/src/views/dashboard/components/sq-view/index.vue

Lines changed: 137 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import ChartComponent from '@/views/chat/component/ChartComponent.vue'
33
import icon_window_mini_outlined from '@/assets/svg/icon_window-mini_outlined.svg'
44
import SqViewDisplay from '@/views/dashboard/components/sq-view/index.vue'
5-
defineProps({
5+
const props = defineProps({
66
viewInfo: {
77
type: Object,
88
required: true,
@@ -14,20 +14,80 @@ defineProps({
1414
},
1515
})
1616
17-
import { ref } from 'vue'
17+
import { computed, nextTick, ref } from 'vue'
1818
import { useI18n } from 'vue-i18n'
19+
import ChartPopover from '@/views/chat/chat-block/ChartPopover.vue'
20+
import ICON_TABLE from '@/assets/svg/chart/icon_form_outlined.svg'
21+
import ICON_COLUMN from '@/assets/svg/chart/icon_dashboard_outlined.svg'
22+
import ICON_BAR from '@/assets/svg/chart/icon_bar_outlined.svg'
23+
import ICON_LINE from '@/assets/svg/chart/icon_chart-line.svg'
24+
import ICON_PIE from '@/assets/svg/chart/icon_pie_outlined.svg'
25+
import type { ChartTypes } from '@/views/chat/component/BaseChart.ts'
1926
const { t } = useI18n()
2027
const chartRef = ref(null)
28+
const currentChartType = ref<ChartTypes | undefined>(undefined)
29+
2130
const renderChart = () => {
2231
//@ts-expect-error eslint-disable-next-line @typescript-eslint/no-unused-expressions
2332
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
2433
chartRef.value?.renderChart
2534
}
35+
2636
const enlargeDialogVisible = ref(false)
2737
2838
const enlargeView = () => {
2939
enlargeDialogVisible.value = true
3040
}
41+
42+
const chartTypeList = computed(() => {
43+
const _list = []
44+
if (props.viewInfo.chart) {
45+
switch (props.viewInfo.chart.type) {
46+
case 'table':
47+
break
48+
case 'column':
49+
case 'bar':
50+
case 'line':
51+
_list.push({
52+
value: 'column',
53+
name: t('chat.chart_type.column'),
54+
icon: ICON_COLUMN,
55+
})
56+
_list.push({
57+
value: 'bar',
58+
name: t('chat.chart_type.bar'),
59+
icon: ICON_BAR,
60+
})
61+
_list.push({
62+
value: 'line',
63+
name: t('chat.chart_type.line'),
64+
icon: ICON_LINE,
65+
})
66+
break
67+
case 'pie':
68+
_list.push({
69+
value: 'pie',
70+
name: t('chat.chart_type.pie'),
71+
icon: ICON_PIE,
72+
})
73+
}
74+
}
75+
76+
return _list
77+
})
78+
79+
function changeTable() {
80+
onTypeChange('table')
81+
}
82+
83+
function onTypeChange(val: any) {
84+
// eslint-disable-next-line vue/no-mutating-props
85+
props.viewInfo.chart.type = val
86+
nextTick(() => {
87+
//@ts-expect-error eslint-disable-next-line @typescript-eslint/no-unused-expressions
88+
chartRef.value?.renderChart()
89+
})
90+
}
3191
defineExpose({
3292
renderChart,
3393
enlargeView,
@@ -40,6 +100,32 @@ defineExpose({
40100
<div class="title">
41101
{{ viewInfo.chart.title }}
42102
</div>
103+
<div class="buttons-bar">
104+
<div class="chart-select-container">
105+
<el-tooltip effect="dark" :content="t('chat.type')" placement="top">
106+
<ChartPopover
107+
v-if="chartTypeList.length > 0"
108+
:chart-type-list="chartTypeList"
109+
:chart-type="viewInfo.chartType"
110+
:title="t('chat.type')"
111+
@type-change="onTypeChange"
112+
></ChartPopover>
113+
</el-tooltip>
114+
<el-tooltip effect="dark" :content="t('chat.chart_type.table')" placement="top">
115+
<el-button
116+
class="tool-btn"
117+
:class="{ 'chart-active': currentChartType === 'table' }"
118+
text
119+
@click="changeTable"
120+
>
121+
<el-icon size="16">
122+
<ICON_TABLE />
123+
</el-icon>
124+
</el-button>
125+
</el-tooltip>
126+
</div>
127+
<div class="divider" />
128+
</div>
43129
</div>
44130
<div class="chart-show-area">
45131
<ChartComponent
@@ -109,6 +195,7 @@ defineExpose({
109195
.header-bar {
110196
height: 32px;
111197
display: flex;
198+
margin-bottom: 16px;
112199
113200
align-items: center;
114201
flex-direction: row;
@@ -172,9 +259,8 @@ defineExpose({
172259
display: flex;
173260
flex-direction: row;
174261
align-items: center;
175-
176262
gap: 16px;
177-
263+
margin-right: 36px;
178264
.divider {
179265
width: 1px;
180266
height: 16px;
@@ -221,4 +307,51 @@ defineExpose({
221307
width: 100%;
222308
height: calc(100% - 32px);
223309
}
310+
311+
.buttons-bar {
312+
display: flex;
313+
flex-direction: row;
314+
align-items: center;
315+
316+
gap: 16px;
317+
318+
.divider {
319+
width: 1px;
320+
height: 16px;
321+
border-left: 1px solid rgba(31, 35, 41, 0.15);
322+
}
323+
}
324+
325+
.chart-select-container {
326+
padding: 3px;
327+
display: flex;
328+
flex-direction: row;
329+
gap: 4px;
330+
border-radius: 6px;
331+
332+
border: 1px solid rgba(217, 220, 223, 1);
333+
334+
.chart-select {
335+
min-width: 40px;
336+
width: 40px;
337+
height: 24px;
338+
339+
:deep(.ed-select__wrapper) {
340+
padding: 4px;
341+
min-height: 24px;
342+
box-shadow: unset;
343+
border-radius: 6px;
344+
345+
&:hover {
346+
background: rgba(31, 35, 41, 0.1);
347+
}
348+
&:active {
349+
background: rgba(31, 35, 41, 0.1);
350+
}
351+
}
352+
:deep(.ed-select__caret) {
353+
font-size: 12px !important;
354+
}
355+
}
356+
}
224357
</style>

frontend/src/views/dashboard/editor/ChartSelection.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ const curSelectChange = (value: boolean) => {
3939
overflow: hidden;
4040
.select-area {
4141
position: absolute;
42-
top: 20px;
42+
top: 26px;
4343
right: 20px;
4444
}
4545
}

0 commit comments

Comments
 (0)