Skip to content

Commit 7b2695e

Browse files
committed
Merge remote-tracking branch 'origin/main'
# Conflicts: # frontend/src/views/dashboard/preview/SQPreviewShow.vue
2 parents f46b721 + 4cba4a4 commit 7b2695e

File tree

10 files changed

+63
-44
lines changed

10 files changed

+63
-44
lines changed

backend/apps/chat/api/chat.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ async def start_chat(session: SessionDep, current_user: CurrentUser, create_chat
6868
)
6969

7070

71-
@router.post("/question")
71+
@router.post("/question", operation_id="question")
7272
async def stream_sql(session: SessionDep, current_user: CurrentUser, request_question: ChatQuestion):
7373
"""Stream SQL analysis results
7474

backend/apps/datasource/crud/datasource.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ def get_table_schema(session: SessionDep, ds: CoreDatasource) -> str:
244244
db_name = table_objs[0].schema
245245
schema_str += f"【DB_ID】 {db_name}\n【Schema】\n"
246246
for obj in table_objs:
247-
schema_str += f"# Table: {db_name}.{obj.table.table_name}"
247+
schema_str += f"# Table: {db_name}.{obj.table.table_name}" if ds.type != "mysql" else f"# Table: {obj.table.table_name}"
248248
table_comment = ''
249249
if obj.table.custom_comment:
250250
table_comment = obj.table.custom_comment.strip()

backend/apps/system/api/aimodel.py

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
from datetime import datetime
21
from fastapi import APIRouter
3-
from sqlmodel import select
2+
from sqlmodel import select
3+
44
from apps.system.models.system_model import AiModelDetail
55
from apps.system.schemas.system_schema import model_status
66
from common.core.deps import SessionDep
@@ -13,9 +13,9 @@
1313

1414
@router.get("/pager/{pageNum}/{pageSize}", response_model=PaginatedResponse[AiModelDetail])
1515
async def pager(
16-
session: SessionDep,
17-
pageNum: int,
18-
pageSize: int
16+
session: SessionDep,
17+
pageNum: int,
18+
pageSize: int
1919
):
2020
pagination = PaginationParams(page=pageNum, size=pageSize)
2121
paginator = Paginator(session)
@@ -24,30 +24,33 @@ async def pager(
2424
model=AiModelDetail,
2525
pagination=pagination,
2626
**filters)
27-
27+
28+
2829
@router.get("/{id}", response_model=AiModelDetail)
2930
async def get_model_by_id(
30-
session: SessionDep,
31-
id: int
31+
session: SessionDep,
32+
id: int
3233
):
3334
term = session.get(AiModelDetail, id)
3435
return term
35-
36+
37+
3638
@router.post("", response_model=AiModelDetail)
3739
async def add_model(
38-
session: SessionDep,
39-
creator: AiModelDetail
40+
session: SessionDep,
41+
creator: AiModelDetail
4042
):
4143
data = AiModelDetail.model_validate(creator)
4244
data.create_time = get_timestamp()
4345
session.add(data)
4446
session.commit()
4547
return creator
4648

49+
4750
@router.put("", response_model=AiModelDetail)
4851
async def update_terminology(
49-
session: SessionDep,
50-
model: AiModelDetail
52+
session: SessionDep,
53+
model: AiModelDetail
5154
):
5255
model.id = int(model.id)
5356
term = session.exec(select(AiModelDetail).where(AiModelDetail.id == model.id)).first()
@@ -58,18 +61,19 @@ async def update_terminology(
5861
session.commit()
5962
return model
6063

64+
6165
@router.delete("/{id}", response_model=AiModelDetail)
6266
async def delete_terminology(
63-
session: SessionDep,
64-
id: int
67+
session: SessionDep,
68+
id: int
6569
):
6670
term = session.exec(select(AiModelDetail).where(AiModelDetail.id == id)).first()
6771
session.delete(term)
6872
session.commit()
6973
return {
7074
"message": f"AiModel with ID {id} deleted successfully."
7175
}
72-
76+
7377

7478
@router.patch("/status", response_model=dict)
7579
async def status(session: SessionDep, dto: model_status):
@@ -83,4 +87,9 @@ async def status(session: SessionDep, dto: model_status):
8387
term.status = status
8488
session.add(term)
8589
session.commit()
86-
return {"message": f"AiModel with IDs {ids} updated successfully."}
90+
return {"message": f"AiModel with IDs {ids} updated successfully."}
91+
92+
93+
@router.get("/list", operation_id="get_model_list")
94+
async def get_model_list(session: SessionDep):
95+
return session.query(AiModelDetail).all()

backend/common/utils/whitelist.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@
2222
"*.eot",
2323
"*.otf",
2424
"/mcp",
25-
"/mcp/message"
25+
"/mcp/message",
26+
"/datasource/list",
27+
"/system/aimodel/list",
28+
"/chat/question"
2629
]
2730

2831
class WhitelistChecker:

backend/main.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def custom_generate_unique_id(route: APIRoute) -> str:
4949
app,
5050
name="SQLBot MCP Server",
5151
description="SQLBot MCP Server",
52-
include_operations=["get_datasource_list"]
52+
include_operations=["get_datasource_list", "get_model_list", "question"]
5353
)
5454

5555
mcp.mount(mcp_app)
@@ -76,7 +76,7 @@ def custom_generate_unique_id(route: APIRoute) -> str:
7676
if not os.path.exists(frontend_dist):
7777
logging.warning(f"The front-end build directory does not exist: {frontend_dist}")
7878
logging.warning("Please make sure you have built the front-end project")
79-
79+
8080
else:
8181

8282
@app.get("/", include_in_schema=False)
@@ -92,3 +92,4 @@ async def read_index():
9292
import uvicorn
9393

9494
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
95+
# uvicorn.run("main:mcp_app", host="0.0.0.0", port=8001) # mcp server

backend/template.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,19 @@ template:
4646
您的任务是通过给定的问题和SQL生成 JSON 以进行数据可视化。
4747
请遵守以下规则:
4848
- 如果需要表格,则生成的 JSON 格式应为:
49-
{{"type":"table", "title": "标题", "columns": [{{"name":"中文字段名1", "value": "SQL 查询列 1(有别名用别名)"}}, {{"name": "中文字段名 2", "value": "SQL 查询列 2(有别名用别名)"}}]}}
49+
{{"type":"table", "title": "标题", "columns": [{{"name":"中文字段名1", "value": "SQL 查询列 1(有别名用别名,去掉外层的反引号、双引号、方括号)"}}, {{"name": "中文字段名 2", "value": "SQL 查询列 2(有别名用别名,去掉外层的反引号、双引号、方括号)"}}]}}
5050
必须从 SQL 查询列中提取“columns”。
5151
- 如果需要柱状图,则生成的 JSON 格式应为:
52-
{{"type":"column", "title": "标题", "axis": {{"x": {{"name":"x轴的中文名称", "value": "SQL 查询 x 轴的列(有别名用别名)"}}, "y": {{"name":"y轴的中文名称","value": "SQL 查询 y 轴的列(有别名用别名)"}}}}
52+
{{"type":"column", "title": "标题", "axis": {{"x": {{"name":"x轴的中文名称", "value": "SQL 查询 x 轴的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}, "y": {{"name":"y轴的中文名称","value": "SQL 查询 y 轴的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}}}
5353
必须从 SQL 查询列中提取“x”和“y”。
5454
- 如果需要条形图,则生成的 JSON 格式应为:
55-
{{"type":"bar", "title": "标题", "axis": {{"x": {{"name":"x轴的中文名称", "value": "SQL 查询 x 轴的列(有别名用别名)"}}, "y": {{"name":"y轴的中文名称","value": "SQL 查询 y 轴的列(有别名用别名)"}}}}
55+
{{"type":"bar", "title": "标题", "axis": {{"x": {{"name":"x轴的中文名称", "value": "SQL 查询 x 轴的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}, "y": {{"name":"y轴的中文名称","value": "SQL 查询 y 轴的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}}}
5656
必须从 SQL 查询列中提取“x”和“y”。
5757
- 如果需要折线图,则生成的 JSON 格式应为:
58-
{{"type":"line", "title": "标题", "axis": {{"x": {{"name":"x轴的中文名称","value": "SQL 查询 x 轴的列(有别名用别名)"}}, "y": {{"name":"y轴的中文名称","value": "SQL 查询 y 轴的列(有别名用别名)"}}}}
58+
{{"type":"line", "title": "标题", "axis": {{"x": {{"name":"x轴的中文名称","value": "SQL 查询 x 轴的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}, "y": {{"name":"y轴的中文名称","value": "SQL 查询 y 轴的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}}}
5959
其中“x”和“y”必须从SQL查询列中提取。
6060
- 如果需要饼图,则生成的 JSON 格式应为:
61-
{{"type":"pie", "title": "标题", "axis": {{"y": {{"值轴的中文名称","value":"SQL 查询数值的列(有别名用别名)"}}, "series": {{"name":"分类的中文名称","value":"SQL 查询分类的列(有别名用别名)"}}}}
61+
{{"type":"pie", "title": "标题", "axis": {{"y": {{"值轴的中文名称","value":"SQL 查询数值的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}, "series": {{"name":"分类的中文名称","value":"SQL 查询分类的列(有别名用别名,去掉外层的反引号、双引号、方括号)"}}}}
6262
其中“column”必须从SQL查询列中提取。
6363
- 如果答案未知或者与生成JSON无关,则生成的 JSON 格式应为:
6464
{{"type":"error", "reason": "抱歉,我无法回答您的问题。"}}

frontend/src/components/layout/index.vue

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,6 @@
149149
import {ref, computed, onMounted} from 'vue'
150150
import {useRouter, useRoute} from 'vue-router'
151151
import {useUserStore} from '@/stores/user'
152-
import folder from '@/assets/svg/folder.svg'
153152
import ds from '@/assets/svg/ds.svg'
154153
import dashboard from '@/assets/svg/dashboard.svg'
155154
import chat from '@/assets/svg/chat.svg'
@@ -184,12 +183,12 @@ const sysRouterList = computed(() => {
184183
const showSubmenu = computed(() => {
185184
return route.path.includes('/system')
186185
})
187-
const workspace = ref('1')
188-
const options = [
186+
// const workspace = ref('1')
187+
/* const options = [
189188
{value: '1', label: 'Default workspace'},
190189
{value: '2', label: 'Workspace 2'},
191190
{value: '3', label: 'Workspace 3'}
192-
]
191+
] */
193192
const currentPageTitle = computed(() => {
194193
if (route.path.includes('/system')) {
195194
return 'System Settings'

frontend/src/router/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import ds from "@/views/ds/index.vue";
88
import DashboardEditor from "@/views/dashboard/editor/index.vue";
99
import Dashboard from "@/views/dashboard/index.vue";
1010
import Model from "@/views/system/model/index.vue";
11-
import User from "@/views/system/user/index.vue";
11+
// import User from "@/views/system/user/index.vue";
1212
import { watchRouter } from "./watch";
1313
const router = createRouter({
1414
history: createWebHashHistory(),

frontend/src/stores/user.ts

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { defineStore } from 'pinia'
2-
import { ref } from 'vue'
2+
// import { ref } from 'vue'
33
import { AuthApi } from '@/api/login'
44
import { useCache } from '@/utils/useCache'
55
import { i18n } from '@/i18n'
@@ -17,18 +17,19 @@ interface UserState {
1717
language: string
1818
exp: number
1919
time: number
20+
[key: string]: string | number
2021
}
2122

2223
export const UserStore = defineStore('user', {
2324
state: (): UserState => {
2425
return {
25-
token: null,
26-
uid: null,
27-
name: null,
28-
oid: null,
26+
token: '',
27+
uid: '',
28+
name: '',
29+
oid: '',
2930
language: 'zh-CN',
30-
exp: null,
31-
time: null
31+
exp: 0,
32+
time: 0
3233
}
3334
},
3435
getters: {
@@ -69,13 +70,19 @@ export const UserStore = defineStore('user', {
6970
const res: any = await AuthApi.info()
7071
const res_data = res || {}
7172

72-
const keys: string[] = ['uid', 'name', 'oid', 'language', 'exp', 'time']
73-
73+
const keys = ['uid', 'name', 'oid', 'language', 'exp', 'time'] as const
74+
7475
keys.forEach(key => {
7576
const dkey = key === 'uid' ? 'id' : key
76-
this[key] = res_data[dkey]
77-
wsCache.set('user.' + key, this[key])
77+
const value = res_data[dkey]
78+
if (key === 'exp' || key === 'time') {
79+
this[key] = Number(value)
80+
} else {
81+
this[key] = String(value)
82+
}
83+
wsCache.set('user.' + key, value)
7884
})
85+
7986
this.setLanguage(this.language)
8087
},
8188
setToken(token: string) {

frontend/src/views/chat/WelcomeBlock.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ onMounted(() => {
7575
</div>
7676
<div class="ds-row-container">
7777
<template v-for="(item, _index) in dsList" :key="_index">
78-
<DatasourceItemCard :ds="item" @click="selectDs(item)" v-if="_index<3 || item?.id===modelValue"
78+
<DatasourceItemCard :ds="item" @click="selectDs(item)"
7979
class="ds-card" :class="[item?.id===modelValue? 'ds-card-selected': '']"/>
8080
</template>
8181
</div>

0 commit comments

Comments
 (0)