Merge remote-tracking branch 'origin/developing' into team

This commit is contained in:
JiaJu Zhuang
2023-08-05 14:17:46 +08:00
26 changed files with 200 additions and 107 deletions

View File

@ -285,7 +285,7 @@ jobs:
content: |
{
"title": "Windows-release-打包完成通知",
"text": "# Windows-release-打包完成通知 \n ![bang]http://oss.sqlgpt.cn/static/happy100.jpg) \n ### 任务id[${{ github.run_id }}](https://github.com/chat2db/Chat2DB/actions/runs/${{ github.run_id }}) \n ### Windows下载地址[https://oss-chat2db.alibaba.com/release/${{ steps.chat2db_version.outputs.substring }}/Chat2DB%20Setup%20${{ steps.chat2db_version.outputs.substring }}.exe]http://oss.sqlgpt.cn/release/${{ steps.chat2db_version.outputs.substring }}/Chat2DB%20Setup%20${{ steps.chat2db_version.outputs.substring }}.exe) "
"text": "# Windows-release-打包完成通知 \n ![bang](https://oss.sqlgpt.cn/static/happy100.jpg) \n ### 任务id[${{ github.run_id }}](https://github.com/chat2db/Chat2DB/actions/runs/${{ github.run_id }}) \n ### Windows下载地址[https://oss.sqlgpt.cn/release/${{ steps.chat2db_version.outputs.substring }}/Chat2DB%20Setup%20${{ steps.chat2db_version.outputs.substring }}.exe](https://oss.sqlgpt.cn/release/${{ steps.chat2db_version.outputs.substring }}/Chat2DB%20Setup%20${{ steps.chat2db_version.outputs.substring }}.exe) "
}
# 构建完成通知
@ -298,7 +298,7 @@ jobs:
content: |
{
"title": "MacOS-amd64-release-构建完成通知",
"text": "# MacOS-amd64-release-打包完成通知 \n ![bang]http://oss.sqlgpt.cn/static/happy100.jpg) \n ### 任务id[${{ github.run_id }}](https://github.com/chat2db/Chat2DB/actions/runs/${{ github.run_id }}) \n ### Intel芯片下载地址[https://oss-chat2db.alibaba.com/release/${{ steps.chat2db_version.outputs.substring }}/Chat2DB-${{ steps.chat2db_version.outputs.substring }}.dmg]http://oss.sqlgpt.cn/release/${{ steps.chat2db_version.outputs.substring }}/Chat2DB-${{ steps.chat2db_version.outputs.substring }}.dmg) \n ### jar包下载地址[https://oss-chat2db.alibaba.com/release/${{ steps.chat2db_version.outputs.substring }}/chat2db-server-start.zip]http://oss.sqlgpt.cn/release/${{ steps.chat2db_version.outputs.substring }}/chat2db-server-start.zip) "
"text": "# MacOS-amd64-release-打包完成通知 \n ![bang](https://oss.sqlgpt.cn/static/happy100.jpg) \n ### 任务id[${{ github.run_id }}](https://github.com/chat2db/Chat2DB/actions/runs/${{ github.run_id }}) \n ### Intel芯片下载地址[https://oss.sqlgpt.cn/release/${{ steps.chat2db_version.outputs.substring }}/Chat2DB-${{ steps.chat2db_version.outputs.substring }}.dmg](https://oss.sqlgpt.cn/release/${{ steps.chat2db_version.outputs.substring }}/Chat2DB-${{ steps.chat2db_version.outputs.substring }}.dmg) \n ### jar包下载地址[https://oss.sqlgpt.cn/release/${{ steps.chat2db_version.outputs.substring }}/chat2db-server-start.zip](https://oss.sqlgpt.cn/release/${{ steps.chat2db_version.outputs.substring }}/chat2db-server-start.zip) "
}
# 构建完成通知
@ -311,7 +311,7 @@ jobs:
content: |
{
"title": "MacOS-arm64-release-构建完成通知",
"text": "# MacOS-arm64-release-打包完成通知 \n ![bang]http://oss.sqlgpt.cn/static/happy100.jpg) \n ### 任务id[${{ github.run_id }}](https://github.com/chat2db/Chat2DB/actions/runs/${{ github.run_id }}) \n ### Apple芯片下载地址[https://oss-chat2db.alibaba.com/release/${{ steps.chat2db_version.outputs.substring }}/Chat2DB-${{ steps.chat2db_version.outputs.substring }}-arm64.dmg]http://oss.sqlgpt.cn/release/${{ steps.chat2db_version.outputs.substring }}/Chat2DB-${{ steps.chat2db_version.outputs.substring }}-arm64.dmg) "
"text": "# MacOS-arm64-release-打包完成通知 \n ![bang](https://oss.sqlgpt.cn/static/happy100.jpg) \n ### 任务id[${{ github.run_id }}](https://github.com/chat2db/Chat2DB/actions/runs/${{ github.run_id }}) \n ### Apple芯片下载地址[https://oss.sqlgpt.cn/release/${{ steps.chat2db_version.outputs.substring }}/Chat2DB-${{ steps.chat2db_version.outputs.substring }}-arm64.dmg](https://oss.sqlgpt.cn/release/${{ steps.chat2db_version.outputs.substring }}/Chat2DB-${{ steps.chat2db_version.outputs.substring }}-arm64.dmg) "
}
# 构建完成通知
@ -324,5 +324,5 @@ jobs:
content: |
{
"title": "Linux-test-打包完成通知",
"text": "# Linux-test-打包完成通知 \n ![bang]http://oss.sqlgpt.cn/static/happy100.jpg) \n ### 任务id[${{ github.run_id }}](https://github.com/chat2db/Chat2DB/actions/runs/${{ github.run_id }}) \n ### Linux下载地址[https://oss-chat2db.alibaba.com/release/${{ steps.chat2db_version.outputs.substring }}/Chat2DB-${{ steps.chat2db_version.outputs.substring }}.AppImage]http://oss.sqlgpt.cn/release/${{ steps.chat2db_version.outputs.substring }}/Chat2DB-${{ steps.chat2db_version.outputs.substring }}.AppImage)"
"text": "# Linux-test-打包完成通知 \n ![bang](https://oss.sqlgpt.cn/static/happy100.jpg) \n ### 任务id[${{ github.run_id }}](https://github.com/chat2db/Chat2DB/actions/runs/${{ github.run_id }}) \n ### Linux下载地址[https://oss.sqlgpt.cn/release/${{ steps.chat2db_version.outputs.substring }}/Chat2DB-${{ steps.chat2db_version.outputs.substring }}.AppImage](https://oss.sqlgpt.cn/release/${{ steps.chat2db_version.outputs.substring }}/Chat2DB-${{ steps.chat2db_version.outputs.substring }}.AppImage)"
}

View File

@ -274,7 +274,7 @@ jobs:
content: |
{
"title": "Windows-test-打包完成通知",
"text": "# Windows-test-打包完成通知 \n ![bang](http://oss.sqlgpt.cn/static/bang100.gif) \n ### 任务id[${{ github.run_id }}](https://github.com/chat2db/Chat2DB/actions/runs/${{ github.run_id }}) \n ### Windows下载地址[http://oss.sqlgpt.cn/test/99.0.${{ github.run_id }}/Chat2DB-Test%20Setup%2099.0.${{ github.run_id }}-Test.exe](http://oss.sqlgpt.cn/test/99.0.${{ github.run_id }}/Chat2DB-Test%20Setup%2099.0.${{ github.run_id }}-Test.exe) "
"text": "# Windows-test-打包完成通知 \n ![bang](https://oss.sqlgpt.cn/static/bang100.gif) \n ### 任务id[${{ github.run_id }}](https://github.com/chat2db/Chat2DB/actions/runs/${{ github.run_id }}) \n ### Windows下载地址[https://oss.sqlgpt.cn/test/99.0.${{ github.run_id }}/Chat2DB-Test%20Setup%2099.0.${{ github.run_id }}-Test.exe](https://oss.sqlgpt.cn/test/99.0.${{ github.run_id }}/Chat2DB-Test%20Setup%2099.0.${{ github.run_id }}-Test.exe) "
}
# 构建完成通知
@ -287,7 +287,7 @@ jobs:
content: |
{
"title": "MacOS-amd64-test-构建完成通知",
"text": "# MacOS-amd64-test-打包完成通知 \n ![bang](http://oss.sqlgpt.cn/static/bang100.gif) \n ### 任务id[${{ github.run_id }}](https://github.com/chat2db/Chat2DB/actions/runs/${{ github.run_id }}) \n ### Intel芯片下载地址[http://oss.sqlgpt.cn/test/99.0.${{ github.run_id }}/Chat2DB-Test-99.0.${{ github.run_id }}-Test.dmg](http://oss.sqlgpt.cn/test/99.0.${{ github.run_id }}/Chat2DB-Test-99.0.${{ github.run_id }}-Test.dmg) \n ### jar包下载地址[http://oss.sqlgpt.cn/test/99.0.${{ github.run_id }}/chat2db-server-start.zip](http://oss.sqlgpt.cn/test/99.0.${{ github.run_id }}/${{ github.run_id }}/chat2db-server-start.zip) "
"text": "# MacOS-amd64-test-打包完成通知 \n ![bang](https://oss.sqlgpt.cn/static/bang100.gif) \n ### 任务id[${{ github.run_id }}](https://github.com/chat2db/Chat2DB/actions/runs/${{ github.run_id }}) \n ### Intel芯片下载地址[https://oss.sqlgpt.cn/test/99.0.${{ github.run_id }}/Chat2DB-Test-99.0.${{ github.run_id }}-Test.dmg](https://oss.sqlgpt.cn/test/99.0.${{ github.run_id }}/Chat2DB-Test-99.0.${{ github.run_id }}-Test.dmg) \n ### jar包下载地址[https://oss.sqlgpt.cn/test/99.0.${{ github.run_id }}/chat2db-server-start.zip](https://oss.sqlgpt.cn/test/99.0.${{ github.run_id }}/${{ github.run_id }}/chat2db-server-start.zip) "
}
# 构建完成通知
@ -300,7 +300,7 @@ jobs:
content: |
{
"title": "MacOS-arm64-test-构建完成通知",
"text": "# MacOS-arm64-test-打包完成通知 \n ![bang](http://oss.sqlgpt.cn/static/bang100.gif) \n ### 任务id[${{ github.run_id }}](https://github.com/chat2db/Chat2DB/actions/runs/${{ github.run_id }}) \n ### Apple芯片下载地址[http://oss.sqlgpt.cn/test/99.0.${{ github.run_id }}/Chat2DB-Test-99.0.${{ github.run_id }}-Test-arm64.dmg](http://oss.sqlgpt.cn/test/99.0.${{ github.run_id }}/Chat2DB-Test-99.0.${{ github.run_id }}-Test-arm64.dmg) "
"text": "# MacOS-arm64-test-打包完成通知 \n ![bang](https://oss.sqlgpt.cn/static/bang100.gif) \n ### 任务id[${{ github.run_id }}](https://github.com/chat2db/Chat2DB/actions/runs/${{ github.run_id }}) \n ### Apple芯片下载地址[https://oss.sqlgpt.cn/test/99.0.${{ github.run_id }}/Chat2DB-Test-99.0.${{ github.run_id }}-Test-arm64.dmg](https://oss.sqlgpt.cn/test/99.0.${{ github.run_id }}/Chat2DB-Test-99.0.${{ github.run_id }}-Test-arm64.dmg) "
}
# 构建完成通知
@ -313,5 +313,5 @@ jobs:
content: |
{
"title": "Linux-test-打包完成通知",
"text": "# Linux-test-打包完成通知 \n ![bang](http://oss.sqlgpt.cn/static/bang100.gif) \n ### 任务id[${{ github.run_id }}](https://github.com/chat2db/Chat2DB/actions/runs/${{ github.run_id }}) \n ### Linux下载地址[http://oss.sqlgpt.cn/test/99.0.${{ github.run_id }}/Chat2DB-Test-99.0.${{ github.run_id }}-Test.AppImage](http://oss.sqlgpt.cn/test/99.0.${{ github.run_id }}/Chat2DB-Test-99.0.${{ github.run_id }}-Test.AppImage) "
"text": "# Linux-test-打包完成通知 \n ![bang](https://oss.sqlgpt.cn/static/bang100.gif) \n ### 任务id[${{ github.run_id }}](https://github.com/chat2db/Chat2DB/actions/runs/${{ github.run_id }}) \n ### Linux下载地址[https://oss.sqlgpt.cn/test/99.0.${{ github.run_id }}/Chat2DB-Test-99.0.${{ github.run_id }}-Test.AppImage](https://oss.sqlgpt.cn/test/99.0.${{ github.run_id }}/Chat2DB-Test-99.0.${{ github.run_id }}-Test.AppImage) "
}

View File

@ -8,6 +8,8 @@
# fail-fast: false
# matrix:
# include:
# - os: macos-latest
# arch: amd64
# - os: ubuntu-latest
# runs-on: ${{ matrix.os }}
# steps:
@ -24,7 +26,7 @@
#
# # java.security 开放tls1 Linux
# - name: Enable tls1
# if: ${{ runner.os == 'Linux' }}
# run: |
# sed -i "s/\(^jdk.tls.disabledAlgorithms=\)\(.*\)\( TLSv1, TLSv1.1,\)\(.*\)/\1\2\4/" ${{ env.JAVA_HOME }}/conf/security/java.security
# cat ${{ env.JAVA_HOME }}/conf/security/java.security
# ls ${{ env.JAVA_HOME }}
# ls ${{ env.JAVA_HOME }}/legal/jdk.zipfs/
# cat ${{ env.JAVA_HOME }}/legal/jdk.zipfs/ADDITIONAL_LICENSE_INFO

View File

@ -1,4 +1,28 @@
# 2.0.9
## 🐞 Bug Fixes
-Fix the issue of Windows flash back
## 🐞 问题修复
- 修复windows闪退的问题
# 2.0.8
## 🐞 Bug Fixes
- Repair the Scientific notation in some databases [Issue #378](https://github.com/chat2db/Chat2DB/issues/378)
- Fix some cases where data is not displayed
## 🐞 问题修复
- 修复部分数据库出现科学计数法的情况 [Issue #378](https://github.com/chat2db/Chat2DB/issues/378)
- 修复部分情况数据不展示
# 2.0.7
## ⭐ New Features
- Export query result as file is supported
@ -7,12 +31,20 @@
- Fixed ai config issues [Issue #346](https://github.com/chat2db/Chat2DB/issues/346)
## ⭐ 新特性
- 支持导出查询结果
## 🐞 问题修复
- 修复ai配置 [Issue #346](https://github.com/chat2db/Chat2DB/issues/346)
# 2.0.6
## 🐞 Bug Fixes
- Fixed: When there are too many tables under the selected library, the "New Console" button at the bottom disappears [Issue #314](https://github.com/chat2db/Chat2DB/issues/314)
- Fixed: When there are too many tables under the selected library, the "New Console" button at the bottom
disappears [Issue #314](https://github.com/chat2db/Chat2DB/issues/314)
## 🐞 问题修复

View File

@ -169,7 +169,7 @@ $ yarn run start:web
$ cd ../chat2db-server
$ mvn clean install # maven 3.8 or later needs to be installed
$ cd chat2db-server/chat2db-server-start/target/
$ java -jar -Dchatgpt.apiKey=xxxxx chat2db-server-start.jar # To launch the chat application, you need to enter the ChatGPT key for the chatgpt.apiKey. Without entering it, you won't be able to use the AIGC function.
$ java -jar -Dloader.path=/lib -Dchatgpt.apiKey=xxxxx chat2db-server-start.jar # To launch the chat application, you need to enter the ChatGPT key for the chatgpt.apiKey. Without entering it, you won't be able to use the AIGC function.
```
## 📑 Documentation

View File

@ -162,7 +162,7 @@ $ yarn run start:web
$ cd ../chat2db-server
$ mvn clean install # 需要安装maven 3.8以上版本
$ cd chat2db-server/chat2db-server-start/target/
$ java -jar -Dchatgpt.apiKey=xxxxx chat2db-server-start.jar # 启动应用 chatgpt.apiKey 需要输入ChatGPT的key,如果不输入无法使用AIGC功能
$ java -jar -Dloader.path=/lib -Dchatgpt.apiKey=xxxxx chat2db-server-start.jar # 启动应用 chatgpt.apiKey 需要输入ChatGPT的key,如果不输入无法使用AIGC功能
```
## 📑 文档

View File

@ -1,8 +1,7 @@
import { defineConfig } from 'umi';
import { extractYarnConfig } from './src/utils/webpack';
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
// const UMI_PublicPath = process.env.UMI_PublicPath || './static/front/';
const UMI_PublicPath = process.env.UMI_PublicPath || './static/front/';
const yarn_config = extractYarnConfig(process.argv);
const chainWebpack = (config: any, { webpack }: any) => {
@ -14,7 +13,7 @@ const chainWebpack = (config: any, { webpack }: any) => {
};
export default defineConfig({
publicPath: './static/front/',
publicPath: UMI_PublicPath,
chainWebpack,
define: {
'process.env.UMI_ENV': process.env.UMI_ENV,

View File

@ -44,6 +44,9 @@ export default defineConfig({
changeOrigin: true,
},
},
targets:{
chrome: 80,
},
headScripts: [
`if (localStorage.getItem('app-local-storage-versions') !== 'v2') {
localStorage.clear();

View File

@ -35,6 +35,7 @@
"USERANDPASSWORD",
"ahooks",
"antd",
"bgcolor",
"chatgpt",
"datas",
"datasource",
@ -42,6 +43,7 @@
"echarts",
"favicons",
"findstr",
"gtag",
"lsof",
"netstat",
"pgsql",

View File

@ -16,7 +16,7 @@
"build:prod": "npm run build:web:prod && npm run build:main:prod",
"build:web": "umi build",
"build:web:desktop": "cross-env UMI_ENV=desktop cross-env APP_VERSION=${npm_config_app_version} cross-env APP_PORT=${npm_config_app_port} umi build",
"build:web:prod": "cross-env UMI_ENV=prod cross-env APP_VERSION=${npm_config_app_version} cross-env APP_PORT=${npm_config_app_port} umi build",
"build:web:prod": "cross-env UMI_ENV=prod cross-env APP_VERSION=${npm_config_app_version} cross-env APP_PORT=${npm_config_app_port} cross-env UMI_PublicPath=${npm_config_public_path} umi build",
"postinstall": "umi setup",
"lint": "umi lint",
"start": "concurrently \"npm run start:web\" \"npm run start:main\"",
@ -28,6 +28,7 @@
"ahooks": "^3.7.7",
"ali-react-table": "^2.6.1",
"antd": "^5.6.0",
"copy-to-clipboard": "^3.3.3",
"echarts": "^5.4.2",
"echarts-for-react": "^3.0.2",
"event-source-polyfill": "^1.0.31",
@ -52,7 +53,7 @@
"@umijs/plugins": "^4.0.55",
"concurrently": "^8.1.0",
"cross-env": "^7.0.3",
"electron": "^22.0.0",
"electron": "^22.3.0",
"electron-builder": "^23.6.0",
"electron-debug": "^3.2.0",
"electron-reload": "^2.0.0-alpha.1",

View File

@ -63,7 +63,7 @@
padding: 4px 12px;
&:hover {
cursor: pointer;
//cursor: pointer;
}
}

View File

@ -73,7 +73,7 @@ function ChatInput(props: IProps) {
<div
className={styles.remainBlock}
onClick={() => {
props.onClickRemainBtn && props.onClickRemainBtn();
// props.onClickRemainBtn && props.onClickRemainBtn();
}}
>
{i18n('chat.input.remain', remainCnt)}

View File

@ -206,7 +206,7 @@ function MonacoEditor(props: IProps, ref: ForwardedRef<IExportRefFunction>) {
return Object.keys(hintData).map((key) => ({
label: key,
kind: monaco.languages.CompletionItemKind.Method,
insertText: key,
insertText: `\`${key}\``,
detail: '<Database>',
}));
};

View File

@ -11,13 +11,14 @@ import aiServer from '@/service/ai';
import { v4 as uuidv4 } from 'uuid';
import { DatabaseTypeCode, ConsoleStatus } from '@/constants';
import Iconfont from '../Iconfont';
import { ITreeNode } from '@/typings';
import { IAiConfig, ITreeNode } from '@/typings';
import { IAIState } from '@/models/ai';
import Popularize from '@/components/Popularize';
import { handleLocalStorageSavedConsole, readLocalStorageSavedConsoleText } from '@/utils';
import { chatErrorForKey, chatErrorToLogin } from '@/constants/chat';
import { AiSqlSourceType } from '@/typings/ai';
import i18n from '@/i18n';
import configService from '@/service/config';
import styles from './index.less';
enum IPromptType {
@ -213,8 +214,14 @@ function Console(props: IProps) {
}
};
const handleAiChat = async (content: string, promptType: IPromptType) => {
const { apiKey } = aiModel?.aiConfig || {};
const handleAIChatInEditor = async (content: string, promptType: IPromptType) => {
const aiConfig = await configService.getAiSystemConfig({});
handleAiChat(content, promptType, aiConfig);
};
const handleAiChat = async (content: string, promptType: IPromptType, aiConfig?: IAiConfig) => {
const { apiKey, aiSqlSource } = aiConfig || props.aiModel?.aiConfig || {};
const isChat2DBAi = aiSqlSource === AiSqlSourceType.CHAT2DBAI;
if (!apiKey && isChat2DBAi) {
handleApiKeyEmptyOrGetQrCode(true);
return;
@ -345,26 +352,23 @@ function Console(props: IProps) {
});
};
const addAction = useMemo(
() => [
{
id: 'explainSQL',
label: i18n('common.text.explainSQL'),
action: (selectedText: string) => handleAiChat(selectedText, IPromptType.SQL_EXPLAIN),
},
{
id: 'optimizeSQL',
label: i18n('common.text.optimizeSQL'),
action: (selectedText: string) => handleAiChat(selectedText, IPromptType.SQL_OPTIMIZER),
},
{
id: 'changeSQL',
label: i18n('common.text.conversionSQL'),
action: (selectedText: string) => handleAiChat(selectedText, IPromptType.SQL_2_SQL),
},
],
[],
);
const addAction = [
{
id: 'explainSQL',
label: i18n('common.text.explainSQL'),
action: (selectedText: string) => handleAIChatInEditor(selectedText, IPromptType.SQL_EXPLAIN),
},
{
id: 'optimizeSQL',
label: i18n('common.text.optimizeSQL'),
action: (selectedText: string) => handleAIChatInEditor(selectedText, IPromptType.SQL_OPTIMIZER),
},
{
id: 'changeSQL',
label: i18n('common.text.conversionSQL'),
action: (selectedText: string) => handleAIChatInEditor(selectedText, IPromptType.SQL_2_SQL),
},
];
const handleClickRemainBtn = async () => {
if (!isChat2DBAi) return;
@ -382,11 +386,12 @@ function Console(props: IProps) {
*/
const handlePopUp = () => {
setModalProps({
imageUrl: 'http://oss.sqlgpt.cn/static/chat2db-wechat.jpg?x-oss-process=image/auto-orient,1/resize,m_lfit,w_256/quality,Q_80/format,webp',
imageUrl:
'http://oss.sqlgpt.cn/static/chat2db-wechat.jpg?x-oss-process=image/auto-orient,1/resize,m_lfit,w_256/quality,Q_80/format,webp',
tip: (
<>
{aiModel.remainingUse?.remainingUses === 0 && <p>Key次数用完或者过期</p>}
<p> 25 AI 使</p>
<p> AI 使</p>
</>
),
});
@ -432,7 +437,7 @@ function Console(props: IProps) {
onExecute={executeSQL}
options={props.editorOptions}
tables={props.tables}
// onChange={}
// onChange={}
/>
{/* <Modal open={modelConfig.open}>{modelConfig.content}</Modal> */}
<Drawer open={isAiDrawerOpen} getContainer={false} mask={false} onClose={() => setIsAiDrawerOpen(false)}>

View File

@ -1,21 +1,22 @@
import React, { useMemo, useState } from 'react';
import { TableDataType } from '@/constants/table';
import { IManageResultData, IResultConfig } from '@/typings/database';
import { formatDate } from '@/utils/date';
import { Button, Dropdown, MenuProps, message, Modal, Space } from 'antd';
import { BaseTable, ArtColumn, useTablePipeline, features, SortItem } from 'ali-react-table';
import Iconfont from '../../Iconfont';
import classnames from 'classnames';
import StateIndicator from '../../StateIndicator';
import MonacoEditor from '../../Console/MonacoEditor';
import { useTheme } from '@/hooks/useTheme';
import styled from 'styled-components';
import { ThemeType } from '@/constants';
import classnames from 'classnames';
import i18n from '@/i18n';
import { ThemeType } from '@/constants';
import { TableDataType } from '@/constants/table';
import { useTheme } from '@/hooks/useTheme';
import { IManageResultData, IResultConfig } from '@/typings/database';
import { compareStrings } from '@/utils/sort';
import MyPagination from '../Pagination';
import { DownOutlined, UserOutlined } from '@ant-design/icons';
import { ExportSizeEnum, ExportTypeEnum } from '@/typings/resultTable';
import { formatDate } from '@/utils/date';
import { copy } from '@/utils';
import Iconfont from '../../Iconfont';
import StateIndicator from '../../StateIndicator';
import MonacoEditor from '../../Console/MonacoEditor';
import MyPagination from '../Pagination';
import styles from './index.less';
interface ITableProps {
@ -49,10 +50,11 @@ const DarkSupportBaseTable: any = styled(BaseTable)`
export default function TableBox(props: ITableProps) {
const { className, data, config, onConfigChange, onSearchTotal } = props;
const { headerList, dataList, duration, description } = data || {};
const { headerList, dataList, duration, description, sqlType } = data || {};
const [viewTableCellData, setViewTableCellData] = useState<IViewTableCellData | null>(null);
const [appTheme] = useTheme();
const isDarkTheme = useMemo(() => appTheme.backgroundColor === ThemeType.Dark, [appTheme]);
const [messageApi, contextHolder] = message.useMessage();
const handleExport = (exportType: ExportTypeEnum, exportSize: ExportSizeEnum) => {
props.onExport && props.onExport(data.sql, data.originalSql, exportType, exportSize);
@ -61,7 +63,7 @@ export default function TableBox(props: ITableProps) {
const items: MenuProps['items'] = useMemo(
() => [
{
label: '导出全部数据为csv',
label: i18n('workspace.table.export.all.csv'),
key: '1',
// icon: <UserOutlined />,
onClick: () => {
@ -69,7 +71,7 @@ export default function TableBox(props: ITableProps) {
},
},
{
label: '导出全部数据为插入语句',
label: i18n('workspace.table.export.all.insert'),
key: '2',
// icon: <UserOutlined />,
onClick: () => {
@ -77,7 +79,7 @@ export default function TableBox(props: ITableProps) {
},
},
{
label: '导出当前页数据为csv',
label: i18n('workspace.table.export.cur.csv'),
key: '3',
// icon: <UserOutlined />,
onClick: () => {
@ -85,7 +87,7 @@ export default function TableBox(props: ITableProps) {
},
},
{
label: '导出当前页数据为插入语句',
label: i18n('workspace.table.export.cur.insert'),
key: '4',
// icon: <UserOutlined />,
onClick: () => {
@ -110,8 +112,8 @@ export default function TableBox(props: ITableProps) {
}
function copyTableCell(data: IViewTableCellData) {
navigator.clipboard.writeText(data?.value || viewTableCellData?.value);
message.success(i18n('common.button.copySuccessfully'));
copy(data?.value || viewTableCellData?.value);
messageApi.success(i18n('common.button.copySuccessfully'));
}
function handleCancel() {
@ -175,12 +177,11 @@ export default function TableBox(props: ITableProps) {
if (type === TableDataType.DATETIME && i) {
rowData[columns[index].name] = formatDate(i, 'yyyy-MM-dd hh:mm:ss');
} else if (i === null) {
rowData[columns[index].name] = '';
rowData[columns[index].name] = '<null>';
} else {
rowData[columns[index].name] = i;
}
});
rowData.key = rowIndex;
return rowData;
});
}
@ -220,9 +221,24 @@ export default function TableBox(props: ITableProps) {
return await props.onSearchTotal();
}
};
return (
<div className={classnames(className, styles.tableBox)}>
{columns.length ? (
const renderContent = () => {
const bottomStatus = (
<div className={styles.statusBar}>
<span>{`${i18n('common.text.result')}${description}.`}</span>
<span>{`${i18n('common.text.timeConsuming')}${duration}ms.`}</span>
<span>{`${i18n('common.text.searchRow')}${tableData.length} ${i18n('common.text.row')}.`}</span>
</div>
);
if (!columns.length || sqlType !== 'SELECT') {
return (
<>
<StateIndicator state="success" text={i18n('common.text.successfulExecution')} />
<div style={{ position: 'absolute', bottom: 0 }}>{bottomStatus}</div>
</>
);
} else {
return (
<>
<div className={styles.toolBar}>
<div className={styles.toolBarItem}>
@ -250,15 +266,14 @@ export default function TableBox(props: ITableProps) {
stickyTop={31}
{...pipeline.getProps()}
/>
<div className={styles.statusBar}>
<span>{`${i18n('common.text.result')}${description}.`}</span>
<span>{`${i18n('common.text.timeConsuming')}${duration}ms.`}</span>
<span>{`${i18n('common.text.searchRow')}${tableData.length} ${i18n('common.text.row')}.`}</span>
</div>
{bottomStatus}
</>
) : (
<StateIndicator state="success" text={i18n('common.text.successfulExecution')} />
)}
);
}
};
return (
<div className={classnames(className, styles.tableBox)}>
{renderContent()}
<Modal
title={viewTableCellData?.name}
open={!!viewTableCellData?.name}
@ -289,6 +304,7 @@ export default function TableBox(props: ITableProps) {
/>
</div>
</Modal>
{contextHolder}
</div>
);
}

View File

@ -11,4 +11,8 @@ export default {
'The table name you entered is not the same as the table name you want to delete, please confirm again',
'workspace.table.total': 'Total',
'workspace.table.total.tip': 'Load total number of rows',
'workspace.table.export.all.csv': 'Export result set csv',
'workspace.table.export.cur.csv': 'Export result of current page set csv',
'workspace.table.export.all.insert': 'Export result set insert sql',
'workspace.table.export.cur.insert': 'Export result of current page set insert sql',
};

View File

@ -10,4 +10,8 @@ export default {
'workspace.tips.affirmDeleteTable': '输入的表名与要删除的表名不一致,请再次确认',
'workspace.table.total': '总数',
'workspace.table.total.tip': '加载总行数',
'workspace.table.export.all.csv': '导出结果集 csv',
'workspace.table.export.cur.csv': '导出当前页结果集 csv',
'workspace.table.export.all.insert': '导出结果集 insert sql',
'workspace.table.export.cur.insert': '导出当前页结果集 insert sql',
};

View File

@ -47,6 +47,8 @@ function createWindow() {
// const menu = Menu.buildFromTemplate(menuBar);
// Menu.setApplicationMenu(menu);
app.commandLine.appendSwitch('--disable-gpu-sandbox');
app.on('ready', () => {
createWindow();
registerAppMenu();

View File

@ -65,7 +65,7 @@ function TreeNodeRightClick(props: IProps) {
handle: () => {
mysqlServer.exportCreateTableSql({
...curWorkspaceParams,
tableName: data.name
tableName: data.key
} as any).then(res => {
setMonacoDefaultValue(res);
setMonacoVerifyDialog(true);
@ -91,7 +91,7 @@ function TreeNodeRightClick(props: IProps) {
text: '新建表',
icon: '\ue6b6',
handle: () => {
const operationData: IOperationData = {
const operationData = {
type: 'new',
nodeData: data
}
@ -132,9 +132,7 @@ function TreeNodeRightClick(props: IProps) {
return {
text: data.pinned ? i18n('workspace.menu.unPin') : i18n('workspace.menu.pin'),
icon: data.pinned ? '\ue61d' : '\ue627',
handle: () => {
handelTop();
}
handle: handelTop
}
},
}
@ -143,7 +141,7 @@ function TreeNodeRightClick(props: IProps) {
const api = data.pinned ? 'deleteTablePin' : 'addTablePin'
mysqlServer[api]({
...curWorkspaceParams,
tableName: data.name
tableName: data.key
} as any).then(res => {
dispatch({
type: 'workspace/fetchGetCurTableList',
@ -173,10 +171,10 @@ function TreeNodeRightClick(props: IProps) {
}
function handleOk() {
if (verifyTableName === data.name) {
if (verifyTableName === data.key) {
let p: any = {
...data.extraParams,
tableName: data.name,
tableName: data.key,
}
mysqlServer.deleteTable(p).then(res => {
// notificationApi.success(
@ -257,11 +255,12 @@ function TreeNodeRightClick(props: IProps) {
}
<Modal
maskClosable={false}
title={`${i18n('workspace.menu.deleteTable')}-${data.name}`}
title={`${i18n('workspace.menu.deleteTable')}-${data.key}`}
open={verifyDialog}
onOk={handleOk}
width={400}
onCancel={(() => { setVerifyDialog(false) })}>
onCancel={(() => { setVerifyDialog(false) })}
>
<Input placeholder={i18n('workspace.menu.deleteTablePlaceHolder')} value={verifyTableName} onChange={(e) => { setVerifyTableName(e.target.value) }}></Input>
</Modal>
{/* 这里后续肯定是要提出去的 */}
@ -269,10 +268,12 @@ function TreeNodeRightClick(props: IProps) {
monacoVerifyDialog &&
<Modal
maskClosable={false}
title={`${data.name}-DDL`}
title={`${data.key}-DDL`}
open={monacoVerifyDialog}
width="600px"
onCancel={(() => { setMonacoVerifyDialog(false) })}>
onCancel={(() => { setMonacoVerifyDialog(false) })}
footer={false}
>
<div className={styles.monacoEditorBox}>
<MonacoEditor
id='edit-dialog'

View File

@ -1,5 +1,6 @@
import { ThemeType } from '@/constants';
import { ITreeNode } from '@/typings';
import clipboardCopy from 'copy-to-clipboard';
import lodash from 'lodash';
export function getOsTheme() {
@ -198,7 +199,7 @@ export function isVersionHigher(version: string, currentVersion: string): boolea
// Copy
export function copy(message: string) {
navigator.clipboard.writeText(message);
clipboardCopy(message);
}
// 获取应用的一些基本信息

View File

@ -2422,9 +2422,9 @@
integrity sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==
"@types/node@^16.11.26":
version "16.18.38"
resolved "https://registry.npmmirror.com/@types/node/-/node-16.18.38.tgz#1dcdb6c54d02b323f621213745f2e44af30c73e6"
integrity sha512-6sfo1qTulpVbkxECP+AVrHV9OoJqhzCsfTNp5NIG+enM4HyM3HvZCO798WShIXBN0+QtDIcutJCjsVYnQP5rIQ==
version "16.18.39"
resolved "https://registry.npmmirror.com/@types/node/-/node-16.18.39.tgz#aa39a1a87a40ef6098ee69689a1acb0c1b034832"
integrity sha512-8q9ZexmdYYyc5/cfujaXb4YOucpQxAV4RMG0himLyDUOEr8Mr79VrqsFI+cQ2M2h89YIuy95lbxuYjxT4Hk4kQ==
"@types/parse-json@^4.0.0":
version "4.0.0"
@ -4093,7 +4093,7 @@ copy-anything@^3.0.2:
dependencies:
is-what "^4.1.8"
copy-to-clipboard@^3.2.0:
copy-to-clipboard@^3.2.0, copy-to-clipboard@^3.3.3:
version "3.3.3"
resolved "https://registry.npmmirror.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz#55ac43a1db8ae639a4bd99511c148cdd1b83a1b0"
integrity sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==
@ -4732,10 +4732,10 @@ electron-to-chromium@^1.4.431:
resolved "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.464.tgz#2f94bad78dff34e527aacbfc5d0b1a33cf046507"
integrity sha512-guZ84yoou4+ILNdj0XEbmGs6DEWj6zpVOWYpY09GU66yEb0DSYvP/biBPzHn0GuW/3RC/pnaYNUWlQE1fJYtgA==
electron@^22.0.0:
version "22.3.17"
resolved "https://registry.npmmirror.com/electron/-/electron-22.3.17.tgz#90a75f78cc761ed536d8210dd001e142fca78691"
integrity sha512-mo9qD1pOkiibvH+pgETsq9RZF0p3O5ACwxzjk3E2ozMYb9cnJenZyE3jxbs4WqzDCFi+rsm6WWahw3hlPhANXw==
electron@^22.3.0:
version "22.3.18"
resolved "https://registry.npmmirror.com/electron/-/electron-22.3.18.tgz#5ee55633b3912fec9df6d8f039acf2c016274cfc"
integrity sha512-JgjB966ghTBszAX/GgVgDY/2CktWCjTZWGJI0WISRHDudBZ8/WPkI/hIjsMiLQLe0wSTk6S+WHOYbIqyw0I/sg==
dependencies:
"@electron/get" "^2.0.0"
"@types/node" "^16.11.26"

View File

@ -2,6 +2,7 @@ package ai.chat2db.server.web.api.controller.ai;
import java.util.Objects;
import ai.chat2db.server.domain.api.enums.AiSqlSourceEnum;
import ai.chat2db.server.domain.api.model.Config;
import ai.chat2db.server.domain.api.param.SystemConfigParam;
import ai.chat2db.server.domain.api.service.ConfigService;
@ -9,6 +10,7 @@ import ai.chat2db.server.tools.base.wrapper.result.DataResult;
import ai.chat2db.server.tools.common.config.Chat2dbProperties;
import ai.chat2db.server.web.api.aspect.ConnectionInfoAspect;
import ai.chat2db.server.web.api.controller.ai.chat2db.client.Chat2dbAIClient;
import ai.chat2db.server.web.api.controller.ai.rest.client.RestAIClient;
import ai.chat2db.server.web.api.http.GatewayClientService;
import ai.chat2db.server.web.api.http.response.ApiKeyResponse;
import ai.chat2db.server.web.api.http.response.InviteQrCodeResponse;
@ -64,6 +66,9 @@ public class AiConfigController {
QrCodeResponse qrCodeResponse = dataResult.getData();
// Representative successfully logged in
if (StringUtils.isNotBlank(qrCodeResponse.getApiKey())) {
SystemConfigParam sqlSourceParam = SystemConfigParam.builder().code(RestAIClient.AI_SQL_SOURCE)
.content(AiSqlSourceEnum.CHAT2DBAI.getCode()).build();
configService.createOrUpdate(sqlSourceParam);
SystemConfigParam param = SystemConfigParam.builder()
.code(Chat2dbAIClient.CHAT2DB_OPENAI_KEY).content(qrCodeResponse.getApiKey())
.build();

View File

@ -118,6 +118,7 @@ public class RdbDmlExportController {
ExcelWrapper excelWrapper = new ExcelWrapper();
try {
ExcelWriterBuilder excelWriterBuilder = EasyExcel.write(response.getOutputStream())
.charset(StandardCharsets.UTF_8)
.excelType(ExcelTypeEnum.CSV);
excelWrapper.setExcelWriterBuilder(excelWriterBuilder);
SQLExecutor.getInstance().executeSql(Chat2DBContext.getConnection(), sql, headerList -> {

View File

@ -38,6 +38,11 @@ public class ExecuteResultVO {
*/
private Boolean success;
/**
* 修改行数 查询sql不会返回
*/
private Integer updateCount;
/**
* 展示头的列表
*/

View File

@ -184,11 +184,11 @@ public class SQLExecutor {
}
}
executeResult.setDuration(timeInterval.interval());
return executeResult;
} finally {
JdbcUtils.closeResultSet(rs);
}
} else {
executeResult.setDuration(timeInterval.interval());
// 修改或者其他
executeResult.setUpdateCount(stmt.getUpdateCount());
}

View File

@ -1,5 +1,6 @@
package ai.chat2db.spi.util;
import java.math.BigDecimal;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Connection;
@ -180,6 +181,15 @@ public class JdbcUtils {
if (obj instanceof LocalDate localDate) {
return Objects.toString(localDate);
}
if (obj instanceof BigDecimal bigDecimal) {
return bigDecimal.toPlainString();
}
if (obj instanceof Double d) {
return BigDecimal.valueOf(d).toPlainString();
}
if (obj instanceof Float f) {
return BigDecimal.valueOf(f).toPlainString();
}
if (obj instanceof Number num) {
return Objects.toString(num);
}
@ -196,11 +206,11 @@ public class JdbcUtils {
* @return
*/
public static DataSourceConnect testConnect(String url, String host, String port,
String userName, String password, String dbType,
DriverConfig driverConfig, SSHInfo ssh, Map<String, Object> properties) {
String userName, String password, String dbType,
DriverConfig driverConfig, SSHInfo ssh, Map<String, Object> properties) {
DataSourceConnect dataSourceConnect = DataSourceConnect.builder()
.success(Boolean.TRUE)
.build();
.success(Boolean.TRUE)
.build();
Session session = null;
Connection connection = null;
// 加载驱动
@ -213,7 +223,7 @@ public class JdbcUtils {
}
// 创建连接
connection = IDriverManager.getConnection(url, userName, password,
driverConfig, properties);
driverConfig, properties);
} catch (Exception e) {
log.error("connection fail:", e);
dataSourceConnect.setSuccess(Boolean.FALSE);
@ -235,7 +245,7 @@ public class JdbcUtils {
}
if (session != null) {
try {
if(StringUtils.isNotBlank(ssh.getLocalPort())) {
if (StringUtils.isNotBlank(ssh.getLocalPort())) {
session.delPortForwardingL(Integer.parseInt(ssh.getLocalPort()));
}
session.disconnect();