diff --git a/backend/apps/system/api/user.py b/backend/apps/system/api/user.py index 1c6ef120..f5b61379 100644 --- a/backend/apps/system/api/user.py +++ b/backend/apps/system/api/user.py @@ -138,7 +138,7 @@ async def create(session: SessionDep, creator: UserCreator): session.commit() @router.put("") -@clear_cache(namespace=CacheNamespace.AUTH_INFO, cacheName=CacheName.USER_INFO, keyExpression="editor.id") +#@clear_cache(namespace=CacheNamespace.AUTH_INFO, cacheName=CacheName.USER_INFO, keyExpression="editor.id") async def update(session: SessionDep, editor: UserEditor): user_model: UserModel = get_db_user(session = session, user_id = editor.id) origin_oid: int = user_model.oid @@ -186,7 +186,7 @@ async def langChange(session: SessionDep, current_user: CurrentUser, language: U session.commit() @router.patch("/pwd/{id}") -@clear_cache(namespace=CacheNamespace.AUTH_INFO, cacheName=CacheName.USER_INFO, keyExpression="id") +#@clear_cache(namespace=CacheNamespace.AUTH_INFO, cacheName=CacheName.USER_INFO, keyExpression="id") async def pwdReset(session: SessionDep, current_user: CurrentUser, id: int): if not current_user.isAdmin: raise HTTPException('only for admin') diff --git a/backend/apps/system/crud/user.py b/backend/apps/system/crud/user.py index 8731aa7e..c0549f63 100644 --- a/backend/apps/system/crud/user.py +++ b/backend/apps/system/crud/user.py @@ -22,7 +22,7 @@ def get_user_by_account(*, session: Session, account: str) -> BaseUserDTO | None return None return BaseUserDTO.model_validate(db_user.model_dump()) -@cache(namespace=CacheNamespace.AUTH_INFO, cacheName=CacheName.USER_INFO, keyExpression="user_id") +#@cache(namespace=CacheNamespace.AUTH_INFO, cacheName=CacheName.USER_INFO, keyExpression="user_id") async def get_user_info(*, session: Session, user_id: int) -> UserInfoDTO | None: db_user: UserModel = get_db_user(session = session, user_id = user_id) userInfo = UserInfoDTO.model_validate(db_user.model_dump()) @@ -58,7 +58,7 @@ async def user_ws_options(session: Session, uid: int, trans: Optional[I18n] = No for id, name in result.all() ] -@clear_cache(namespace=CacheNamespace.AUTH_INFO, cacheName=CacheName.USER_INFO, keyExpression="id") +#@clear_cache(namespace=CacheNamespace.AUTH_INFO, cacheName=CacheName.USER_INFO, keyExpression="id") async def single_delete(session: SessionDep, id: int): user_model: UserModel = get_db_user(session = session, user_id = id) del_stmt = sqlmodel_delete(UserWsModel).where(UserWsModel.uid == id) @@ -66,6 +66,6 @@ async def single_delete(session: SessionDep, id: int): session.delete(user_model) session.commit() -@clear_cache(namespace=CacheNamespace.AUTH_INFO, cacheName=CacheName.USER_INFO, keyExpression="id") +#@clear_cache(namespace=CacheNamespace.AUTH_INFO, cacheName=CacheName.USER_INFO, keyExpression="id") async def clean_user_cache(id: int): logging.info(f"User cache for [{id}] has been cleaned") diff --git a/backend/template.yaml b/backend/template.yaml index 4544b459..0d414876 100644 --- a/backend/template.yaml +++ b/backend/template.yaml @@ -13,7 +13,13 @@ template: - 如数据库引擎是 PostgreSQL、Oracle,则在schema、表名、字段名、别名外层加双引号; - 如数据库引擎是 MySQL,则在表名、字段名、别名外层加反引号; - 如数据库引擎是 Microsoft SQL Server,则在schema、表名、字段名、别名外层加方括号。 - - 如果生成SQL的字段内有时间格式的字段,若提问中没有指定,则默认按时间升序排序,且格式化为yyyy-MM-dd HH:mm:ss的格式,生成的格式化语法需要适配对应的数据库引擎。 + - 如果生成SQL的字段内有时间格式的字段: + - 若提问中没有指定查询顺序,则默认按时间升序排序 + - 若提问是时间,且没有指定具体格式,则格式化为yyyy-MM-dd HH:mm:ss的格式 + - 若提问是日期,且没有指定具体格式,则格式化为yyyy-MM-dd的格式 + - 若提问是年月,且没有指定具体格式,则格式化为yyyy-MM的格式 + - 若提问是年,且没有指定具体格式,则格式化为yyyy的格式 + - 生成的格式化语法需要适配对应的数据库引擎。 - 生成的SQL使用JSON格式返回: {{"success":true,"sql":"生成的SQL语句","tables":["表名1","表名2",...]}} - 问题与生成SQL无关时,直接回答: diff --git a/frontend/src/assets/svg/chart/bar.svg b/frontend/src/assets/svg/chart/bar.svg deleted file mode 100644 index ade22f57..00000000 --- a/frontend/src/assets/svg/chart/bar.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/frontend/src/assets/svg/chart/column.svg b/frontend/src/assets/svg/chart/column.svg deleted file mode 100644 index 2eb3504a..00000000 --- a/frontend/src/assets/svg/chart/column.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/frontend/src/assets/svg/chart/icon_bar_outlined.svg b/frontend/src/assets/svg/chart/icon_bar_outlined.svg new file mode 100644 index 00000000..2fecb922 --- /dev/null +++ b/frontend/src/assets/svg/chart/icon_bar_outlined.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/assets/svg/chart/icon_chart-line.svg b/frontend/src/assets/svg/chart/icon_chart-line.svg new file mode 100644 index 00000000..4899f0b1 --- /dev/null +++ b/frontend/src/assets/svg/chart/icon_chart-line.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/src/assets/svg/chart/icon_dashboard_outlined.svg b/frontend/src/assets/svg/chart/icon_dashboard_outlined.svg new file mode 100644 index 00000000..309baacc --- /dev/null +++ b/frontend/src/assets/svg/chart/icon_dashboard_outlined.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/assets/svg/chart/icon_form_outlined.svg b/frontend/src/assets/svg/chart/icon_form_outlined.svg new file mode 100644 index 00000000..2311fa4c --- /dev/null +++ b/frontend/src/assets/svg/chart/icon_form_outlined.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/assets/svg/chart/icon_pie_outlined.svg b/frontend/src/assets/svg/chart/icon_pie_outlined.svg new file mode 100644 index 00000000..3efd2a8c --- /dev/null +++ b/frontend/src/assets/svg/chart/icon_pie_outlined.svg @@ -0,0 +1,4 @@ + + + + diff --git a/frontend/src/assets/svg/chart/line.svg b/frontend/src/assets/svg/chart/line.svg deleted file mode 100644 index b8ecfcc7..00000000 --- a/frontend/src/assets/svg/chart/line.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/frontend/src/assets/svg/chart/pie.svg b/frontend/src/assets/svg/chart/pie.svg deleted file mode 100644 index 096513bf..00000000 --- a/frontend/src/assets/svg/chart/pie.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/frontend/src/assets/svg/chart/table.svg b/frontend/src/assets/svg/chart/table.svg deleted file mode 100644 index 4fbddcc2..00000000 --- a/frontend/src/assets/svg/chart/table.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/frontend/src/assets/svg/icon_export_outlined.svg b/frontend/src/assets/svg/icon_export_outlined.svg new file mode 100644 index 00000000..ba55b6cb --- /dev/null +++ b/frontend/src/assets/svg/icon_export_outlined.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/assets/svg/icon_into-item_outlined.svg b/frontend/src/assets/svg/icon_into-item_outlined.svg new file mode 100644 index 00000000..9a313704 --- /dev/null +++ b/frontend/src/assets/svg/icon_into-item_outlined.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/assets/svg/icon_sql_outlined.svg b/frontend/src/assets/svg/icon_sql_outlined.svg new file mode 100644 index 00000000..d4b1e28f --- /dev/null +++ b/frontend/src/assets/svg/icon_sql_outlined.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/frontend/src/assets/svg/icon_window-max_outlined.svg b/frontend/src/assets/svg/icon_window-max_outlined.svg new file mode 100644 index 00000000..1a37a458 --- /dev/null +++ b/frontend/src/assets/svg/icon_window-max_outlined.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/assets/svg/icon_window-mini_outlined.svg b/frontend/src/assets/svg/icon_window-mini_outlined.svg new file mode 100644 index 00000000..4629abd5 --- /dev/null +++ b/frontend/src/assets/svg/icon_window-mini_outlined.svg @@ -0,0 +1,3 @@ + + + diff --git a/frontend/src/i18n/zh-CN.json b/frontend/src/i18n/zh-CN.json index fcb110d5..b8ff7f19 100644 --- a/frontend/src/i18n/zh-CN.json +++ b/frontend/src/i18n/zh-CN.json @@ -372,6 +372,7 @@ "no_fields_yet": "暂无字段" }, "chat": { + "type": "图表类型", "chart_type": { "table": "明细表", "bar": "条形图", @@ -379,6 +380,13 @@ "line": "折线图", "pie": "饼图" }, + "show_sql": "查看SQL", + "export_to": "导出为", + "excel": "Excel", + "picture": "图片", + "add_to_dashboard": "添加到仪表板", + "full_screen": "全屏", + "exit_full_screen": "退出全屏", "sql_generation": "生成SQL", "chart_generation": "生成图表", "inference_process": "思考过程", diff --git a/frontend/src/views/chat/ChatAnswer.vue b/frontend/src/views/chat/ChatAnswer.vue index 40a4e850..eab61123 100644 --- a/frontend/src/views/chat/ChatAnswer.vue +++ b/frontend/src/views/chat/ChatAnswer.vue @@ -6,11 +6,11 @@ import MdComponent from './component/MdComponent.vue' import DisplayChartBlock from './component/DisplayChartBlock.vue' import type { ChartTypes } from '@/views/chat/component/BaseChart.ts' import { ArrowDown } from '@element-plus/icons-vue' -import ICON_BAR from '@/assets/svg/chart/bar.svg' -import ICON_COLUMN from '@/assets/svg/chart/column.svg' -import ICON_LINE from '@/assets/svg/chart/line.svg' -import ICON_PIE from '@/assets/svg/chart/pie.svg' -import ICON_TABLE from '@/assets/svg/chart/table.svg' +import ICON_BAR from '@/assets/svg/chart/icon_bar_outlined.svg' +import ICON_COLUMN from '@/assets/svg/chart/icon_dashboard_outlined.svg' +import ICON_LINE from '@/assets/svg/chart/icon_chart-line.svg' +import ICON_PIE from '@/assets/svg/chart/icon_pie_outlined.svg' +import ICON_TABLE from '@/assets/svg/chart/icon_form_outlined.svg' import { find } from 'lodash-es' import { useI18n } from 'vue-i18n' diff --git a/frontend/src/views/chat/chat-block/ChartBlock.vue b/frontend/src/views/chat/chat-block/ChartBlock.vue index 5162fdcc..588dd037 100644 --- a/frontend/src/views/chat/chat-block/ChartBlock.vue +++ b/frontend/src/views/chat/chat-block/ChartBlock.vue @@ -4,17 +4,36 @@ import DisplayChartBlock from '@/views/chat/component/DisplayChartBlock.vue' import { computed, ref } from 'vue' import { concat } from 'lodash-es' import type { ChartTypes } from '@/views/chat/component/BaseChart.ts' +import ICON_BAR from '@/assets/svg/chart/icon_bar_outlined.svg' +import ICON_COLUMN from '@/assets/svg/chart/icon_dashboard_outlined.svg' +import ICON_LINE from '@/assets/svg/chart/icon_chart-line.svg' +import ICON_PIE from '@/assets/svg/chart/icon_pie_outlined.svg' +import ICON_TABLE from '@/assets/svg/chart/icon_form_outlined.svg' +import icon_sql_outlined from '@/assets/svg/icon_sql_outlined.svg' +import icon_export_outlined from '@/assets/svg/icon_export_outlined.svg' +import icon_into_item_outlined from '@/assets/svg/icon_into-item_outlined.svg' +import icon_window_max_outlined from '@/assets/svg/icon_window-max_outlined.svg' +import icon_window_mini_outlined from '@/assets/svg/icon_window-mini_outlined.svg' +import { useI18n } from 'vue-i18n' const props = withDefaults( defineProps<{ message: ChatMessage isPredict?: boolean + chatType?: ChartTypes + enlarge?: boolean }>(), { isPredict: false, + chatType: undefined, + enlarge: false, } ) +const { t } = useI18n() + +const emits = defineEmits(['exitFullScreen']) + const dataObject = computed<{ fields: Array data: Array<{ [key: string]: any }> @@ -92,12 +111,79 @@ const chartType = computed({ if (currentChartType.value) { return currentChartType.value } - return chartObject.value.type ?? 'table' + return props.chatType ?? chartObject.value.type ?? 'table' }, set(v) { currentChartType.value = v }, }) + +const chartTypeList = computed(() => { + const _list = [] + if (chartObject.value) { + switch (chartObject.value.type) { + case 'table': + break + case 'column': + case 'bar': + case 'line': + _list.push({ + value: 'column', + name: t('chat.chart_type.column'), + icon: ICON_COLUMN, + }) + _list.push({ + value: 'bar', + name: t('chat.chart_type.bar'), + icon: ICON_BAR, + }) + _list.push({ + value: 'line', + name: t('chat.chart_type.line'), + icon: ICON_LINE, + }) + break + case 'pie': + _list.push({ + value: 'pie', + name: t('chat.chart_type.pie'), + icon: ICON_PIE, + }) + } + } + + return _list +}) + +function changeTable() { + chartType.value = 'table' + onTypeChange() +} + +function onTypeChange() { + chartRef.value?.onTypeChange() +} + +const dialogVisible = ref(false) + +function openFullScreen() { + dialogVisible.value = true +} + +function closeFullScreen() { + emits('exitFullScreen') +} + +function onExitFullScreen() { + dialogVisible.value = false +} + +function showSql() { + console.log('todo') +} +function addToDashboard() { + console.log('todo') +} +