diff --git a/.vscode/settings.json b/.vscode/settings.json index 40427078..47ce6195 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,15 +1,17 @@ { "cSpell.words": [ - "Dserver", - "Dspring", - "Sercurity", "ahooks", "antd", "asar", "cascader", + "Dserver", + "Dspring", "echarts", + "favicons", + "iconfont", "nsis", "pgsql", + "Sercurity", "sortablejs", "wireframe" ] diff --git a/chat2db-client/.umirc.desktop.ts b/chat2db-client/.umirc.desktop.ts index 53c37d1f..aafa2beb 100644 --- a/chat2db-client/.umirc.desktop.ts +++ b/chat2db-client/.umirc.desktop.ts @@ -9,13 +9,6 @@ const chainWebpack = (config: any, { webpack }: any) => { languages: ['mysql', 'pgsql', 'sql'], }, ]); - - config.plugin('define').use(require('webpack').DefinePlugin, [ - { - __BUILD_TIME__: JSON.stringify(formatDate(new Date(), 'yyyyMMddhhmmss')), - __APP_VERSION__: JSON.stringify(process.env.APP_VERSION || '0.0.0'), - }, - ]); }; export default defineConfig({ @@ -24,5 +17,5 @@ export default defineConfig({ headScripts: ['if (window.myAPI) { window.myAPI.startServerForSpawn() }'], define: { 'process.env.UMI_ENV': process.env.UMI_ENV, - } + }, }); diff --git a/chat2db-client/.umirc.prod.ts b/chat2db-client/.umirc.prod.ts index 77b1dfea..a0d3b6d7 100644 --- a/chat2db-client/.umirc.prod.ts +++ b/chat2db-client/.umirc.prod.ts @@ -9,13 +9,6 @@ const chainWebpack = (config: any, { webpack }: any) => { languages: ['mysql', 'pgsql', 'sql'], }, ]); - - config.plugin('define').use(require('webpack').DefinePlugin, [ - { - __BUILD_TIME__: JSON.stringify(formatDate(new Date(), 'yyyyMMddhhmmss')), - __APP_VERSION__: JSON.stringify(process.env.APP_VERSION || '0.0.0'), - }, - ]); }; export default defineConfig({ @@ -23,5 +16,5 @@ export default defineConfig({ chainWebpack, define: { 'process.env.UMI_ENV': process.env.UMI_ENV, - } + }, }); diff --git a/chat2db-client/.umirc.ts b/chat2db-client/.umirc.ts index 8a941676..1219b1ad 100644 --- a/chat2db-client/.umirc.ts +++ b/chat2db-client/.umirc.ts @@ -1,7 +1,7 @@ import { formatDate } from './src/utils/date'; import { defineConfig } from 'umi'; const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin'); -console.log(process.env.UMI_ENV) +console.log(process.env.UMI_ENV); const chainWebpack = (config: any, { webpack }: any) => { config.plugin('monaco-editor').use(MonacoWebpackPlugin, [ @@ -37,11 +37,11 @@ export default defineConfig({ changeOrigin: true, }, }, + headScripts: ['if (window.myAPI) { window.myAPI.startServerForSpawn() }'], + favicons: ['logo.ico'], define: { - __ENV: process.env.UMI_ENV , + __ENV: process.env.UMI_ENV, __BUILD_TIME__: formatDate(new Date(), 'yyyyMMddhhmmss'), __APP_VERSION__: process.env.APP_VERSION || '0.0.0', }, - headScripts: ['if (window.myAPI) { window.myAPI.startServerForSpawn() }'], - favicons: ['logo.ico'], }); diff --git a/chat2db-client/src/components/Iconfont/index.less b/chat2db-client/src/components/Iconfont/index.less index 5572157f..0d539e8d 100644 --- a/chat2db-client/src/components/Iconfont/index.less +++ b/chat2db-client/src/components/Iconfont/index.less @@ -14,4 +14,4 @@ -webkit-font-smoothing: antialiased; -webkit-text-stroke-width: 0.2px; -moz-osx-font-smoothing: grayscale; -} +} \ No newline at end of file diff --git a/chat2db-client/src/components/Iconfont/index.tsx b/chat2db-client/src/components/Iconfont/index.tsx index 6ad67dbf..390f5417 100644 --- a/chat2db-client/src/components/Iconfont/index.tsx +++ b/chat2db-client/src/components/Iconfont/index.tsx @@ -6,7 +6,6 @@ import styles from './index.less'; // 只有本地开发时使用cdn,发布线上时要下载iconfont到 /assets/font if (__ENV === 'local') { let container = ` - /* 在线链接服务仅供平台体验和调试使用,平台不承诺服务的稳定性,企业客户需下载字体包自行发布使用并做好备份。 */ @font-face { font-family: 'iconfont'; /* Project id 3633546 */ src: url('//at.alicdn.com/t/a/font_3633546_p80guyu8w2s.woff2?t=1687748230475') format('woff2'), @@ -20,11 +19,16 @@ if (__ENV === 'local') { style.appendChild(document.createTextNode(container)); } - -export default class Iconfont extends PureComponent<{ - code: string; -} & React.DetailedHTMLProps, HTMLElement>> { +export default class Iconfont extends PureComponent< + { + code: string; + } & React.DetailedHTMLProps, HTMLElement> +> { render() { - return {this.props.code} + return ( + + {this.props.code} + + ); } } diff --git a/chat2db-client/src/i18n/en-us/connection.ts b/chat2db-client/src/i18n/en-us/connection.ts index 3b42f8ed..3027aa32 100644 --- a/chat2db-client/src/i18n/en-us/connection.ts +++ b/chat2db-client/src/i18n/en-us/connection.ts @@ -17,5 +17,4 @@ export default { 'connection.message.testSshConnection': 'Test the ssh connection', 'connection.tableHeader.name': 'Name', 'connection.tableHeader.value': 'Value', - 'connection.menu.enterToWorkSpace': 'Go to DataSource', }; \ No newline at end of file diff --git a/chat2db-client/src/i18n/zh-cn/connection.ts b/chat2db-client/src/i18n/zh-cn/connection.ts index 809ffbe3..8ccd75a2 100644 --- a/chat2db-client/src/i18n/zh-cn/connection.ts +++ b/chat2db-client/src/i18n/zh-cn/connection.ts @@ -17,5 +17,4 @@ export default { 'connection.message.testSshConnection': '测试ssh连接', 'connection.tableHeader.name': '名称', 'connection.tableHeader.value': '值', - 'connection.menu.enterToWorkSpace': '前往数据源', } diff --git a/chat2db-client/src/layouts/index.tsx b/chat2db-client/src/layouts/index.tsx index 5376488b..26c39205 100644 --- a/chat2db-client/src/layouts/index.tsx +++ b/chat2db-client/src/layouts/index.tsx @@ -9,15 +9,10 @@ import antdEnUS from 'antd/locale/en_US'; import antdZhCN from 'antd/locale/zh_CN'; import { useTheme } from '@/hooks'; import { isEn } from '@/utils/check'; -import { ThemeType, PrimaryColorType, LangType } from '@/constants'; -import { InjectThemeVar } from '@/theme' +import { ThemeType, PrimaryColorType, LangType } from '@/constants/'; +import { InjectThemeVar } from '@/theme'; import styles from './index.less'; -import { - getLang, - getPrimaryColor, - getTheme, - setLang, -} from '@/utils/localStorage'; +import { getLang, getPrimaryColor, getTheme, setLang } from '@/utils/localStorage'; declare global { interface Window { @@ -59,7 +54,6 @@ export default function Layout() { ); } - function AppContainer() { const { token } = useToken(); const [initEnd, setInitEnd] = useState(false); @@ -67,7 +61,7 @@ function AppContainer() { useEffect(() => { InjectThemeVar(token as any, appTheme.backgroundColor, appTheme.primaryColor); - }, [token]) + }, [token]); useLayoutEffect(() => { collectInitApp(); @@ -102,8 +96,7 @@ function AppContainer() { let theme = getTheme(); if (theme === ThemeType.FollowOs) { theme = - (window.matchMedia && - window.matchMedia('(prefers-color-scheme: dark)').matches + (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? ThemeType.Dark : ThemeType.Light) || ThemeType.Dark; } @@ -119,14 +112,13 @@ function AppContainer() { } } - return
- { - initEnd && -
- -
- } -
+ return ( +
+ {initEnd && ( +
+ +
+ )} +
+ ); } - - diff --git a/chat2db-client/src/models/connection.ts b/chat2db-client/src/models/connection.ts index f047f3d0..f0d91c93 100644 --- a/chat2db-client/src/models/connection.ts +++ b/chat2db-client/src/models/connection.ts @@ -1,36 +1,63 @@ -import { IConnectionDetails } from "@/typings" +import { IConnectionDetails } from '@/typings/connection'; +import { Effect, Reducer } from 'umi'; +import connectionService from '@/service/connection'; +import { IPageResponse } from '@/typings/common'; -export interface ConnectionState { - curConnection: IConnectionDetails - connectionList: IConnectionDetails[] +/** + * 数据源相关 - 链接池、数据库、schema、表 + */ +export interface ConnectionModelState { + curConnection?: IConnectionDetails; + connectionList: IConnectionDetails[]; } +export interface ConnectionModelType { + namespace: 'connection'; + state: ConnectionModelState; + reducers: { + // 设置连接池列表 + setConnectionList: Reducer; + setCurConnection: Reducer; + }; + effects: { + // setConnectionList: Effect; + }; +} -export default { - namespace: 'connection', - state: { - curConnection: null, - connectionList: [], +// const ConnectionModel:ConnectionModelType = { +const ConnectionModel = { + namespace: 'connection', + state: { + curConnection: undefined, + connectionList: [], + }, + reducers: { + // 设置连接池列表 + setConnectionList(state: ConnectionModelState, { payload }: { payload: ConnectionModelState['connectionList'] }) { + return { + ...state, + connectionList: payload, + }; }, - reducers: { - // 获取连接池列表 - setConnectionList(state: ConnectionState, { payload }: { payload: ConnectionState['connectionList'] }) { - return { - ...state, - connectionList: payload - } - }, + // 设置当前选着的Connection + setCurConnection(state: ConnectionModelState, { payload }: { payload: ConnectionModelState['curConnection'] }) { + return { ...state, curConnection: payload }; + }, - // 设置当前选着的Connection - setCurConnection( - state: ConnectionState, - { payload }: { payload: ConnectionState['curConnection'] }, - ) { - return { ...state, curConnection: payload } - }, + }, + effects: { + *fetchConnectionList(_, { call, put }) { + const res = (yield connectionService.getList({ pageNo: 1, pageSize: 999 })) as IPageResponse; + console.log('fetchConnectionList==>', res.data); + yield put({ + type: 'setConnectionList', + payload: res.data, + }); + }, + }, +}; - } -} \ No newline at end of file +export default ConnectionModel; diff --git a/chat2db-client/src/models/database.ts b/chat2db-client/src/models/database.ts new file mode 100644 index 00000000..a5f8e5d9 --- /dev/null +++ b/chat2db-client/src/models/database.ts @@ -0,0 +1,43 @@ +import sqlService from '@/service/sql'; + +interface ISchema { + databaseName: string; + name: string; +} +interface IDatabase { + name: string; + schema: ISchema[]; +} + +const DatabaseModel = { + namespace: 'database', + state: { + databaseAndSchemaList: [], + }, + + reducers: { + // 设置 database schema 数据 + setDatabaseAndSchemaList(state, { payload }) { + return { + ...state, + databaseAndSchemaList: payload, + }; + }, + }, + + effects: { + *fetchDatabaseAndSchemaList(p, { call, put }) { + console.log('fetchDatabaseAndSchemaList start', p); + const res = (yield sqlService.getDatabaseSchemaList({ dataSourceId: 2 })) as { + data: { database: IDatabase[]; schema: ISchema[] }; + }; + console.log('fetchDatabaseAndSchemaList end', res); + yield put({ + type: 'setDatabaseAndSchemaList', + payload: res, + }); + }, + }, +}; + +export default DatabaseModel; diff --git a/chat2db-client/src/pages/main/connections/index.less b/chat2db-client/src/pages/main/connection/index.less similarity index 100% rename from chat2db-client/src/pages/main/connections/index.less rename to chat2db-client/src/pages/main/connection/index.less diff --git a/chat2db-client/src/pages/main/connections/index.tsx b/chat2db-client/src/pages/main/connection/index.tsx similarity index 69% rename from chat2db-client/src/pages/main/connections/index.tsx rename to chat2db-client/src/pages/main/connection/index.tsx index ebefd5dd..bbbd1f15 100644 --- a/chat2db-client/src/pages/main/connections/index.tsx +++ b/chat2db-client/src/pages/main/connection/index.tsx @@ -12,7 +12,7 @@ import { Button, Dropdown, Modal } from 'antd'; import { MoreOutlined } from '@ant-design/icons'; import styles from './index.less'; import { connect, history } from 'umi'; -import { ConnectionState } from '@/models/connection'; +import { ConnectionModelType } from '@/models/connection'; interface IMenu { key: number; @@ -20,15 +20,22 @@ interface IMenu { icon: React.ReactNode; meta: IConnectionDetails; } -interface IProps { - connectionList: IConnectionDetails[]; - curConnection: IConnectionDetails; - dispatch: (p: { type: string, payload: any }) => void +interface IProps { + connectionModel: { + connectionList: IConnectionDetails[]; + curConnection: IConnectionDetails; + }; + databaseModel: { + databaseAndSchemaList: any; + }; + dispatch: (p: { type: `connection/${string}` | `database/${string}`; payload?: any }) => void; } function Connections(props: IProps) { - const { connectionList } = props; + console.log('props', props); + const { connectionModel, databaseModel, dispatch } = props; + const { connectionList } = connectionModel; const volatileRef = useRef(); // const [connectionList, setConnectionList] = useState(); const [curConnection, setCurConnection] = useState>({}); @@ -38,18 +45,10 @@ function Connections(props: IProps) { }, []); const getConnectionList = async () => { - let p = { - pageNo: 1, - pageSize: 999, - }; - let res = await connectionService.getList(p) - - props.dispatch({ - type: 'connection/setConnectionList', - payload: res.data, - }) - - } + dispatch({ + type: 'connection/fetchConnectionList', + }); + }; function handleCreateConnections(database: IDatabase) { setCurConnection({ @@ -83,9 +82,7 @@ function Connections(props: IProps) { setCurConnection(menu.meta); }} > -
+
{icon} {label}
@@ -95,13 +92,18 @@ function Connections(props: IProps) { items: [ { key: 'EnterWorkSpace', - label: i18n('connection.menu.enterToWorkSpace'), + label: i18n('connection.button.connect'), onClick: () => { - props.dispatch({ + dispatch({ type: 'connection/setCurConnection', payload: menu.meta, - }) - history.push('/workspace') + }); + + dispatch({ + type: 'database/fetchDatabaseAndSchemaList', + }); + + history.push('/workspace'); // window.location.replace('/workspace'); }, }, @@ -160,35 +162,35 @@ function Connections(props: IProps) { />
) : ( -
- {databaseTypeList.map((t) => { - return ( -
-
-
-
- -
- {t.name} -
-
- +
+ {databaseTypeList.map((t) => { + return ( +
+
+
+
+
+ {t.name} +
+
+
- ); - })} - { - Array.from({ length: 5 }).map(t => { - return
- }) - } -
- )} +
+ ); + })} + {Array.from({ length: 20 }).map((t) => { + return
; + })} +
+ )}
); -}; +} - -export default connect(({ connection }: { connection: ConnectionState }) => (connection))(Connections); +export default connect(({ connection, database }: { connection: ConnectionModelType; database: any }) => ({ + connectionModel: connection, + databaseModel: database, +}))(Connections); diff --git a/chat2db-client/src/pages/main/index.tsx b/chat2db-client/src/pages/main/index.tsx index 4762fef5..dfb502be 100644 --- a/chat2db-client/src/pages/main/index.tsx +++ b/chat2db-client/src/pages/main/index.tsx @@ -7,7 +7,7 @@ import Setting from '@/blocks/Setting'; import Iconfont from '@/components/Iconfont'; import BrandLogo from '@/components/BrandLogo'; -import DataSource from './connections'; +import DataSource from './connection'; import Workspace from './workspace'; import Dashboard from './dashboard'; import Chat from './chat'; diff --git a/chat2db-client/src/service/sql.ts b/chat2db-client/src/service/sql.ts index 590f170d..39d9dfbf 100644 --- a/chat2db-client/src/service/sql.ts +++ b/chat2db-client/src/service/sql.ts @@ -1,4 +1,4 @@ -import createRequest from "./base"; +import createRequest from './base'; import { IPageResponse, ITable, IPageParams } from '@/types'; import { DatabaseTypeCode } from '@/constants'; @@ -10,10 +10,10 @@ export interface IGetListParams extends IPageParams { } export interface IExecuteSqlParams { - sql: string, - dataSourceId: number, - databaseName: string, - consoleId: number, + sql: string; + dataSourceId: number; + databaseName: string; + consoleId: number; } export interface IExecuteSqlResponse { @@ -25,9 +25,9 @@ export interface IExecuteSqlResponse { dataList: any[]; } export interface IConnectConsoleParams { - consoleId: number, - dataSourceId: number, - databaseName: string, + consoleId: number; + dataSourceId: number; + databaseName: string; } const getList = createRequest>('/api/rdb/ddl/list', {}); @@ -83,6 +83,10 @@ const getIndexList = createRequest('/api/rdb/ddl/index_ const getKeyList = createRequest('/api/rdb/ddl/key_list', { method: 'get' }); const getSchemaList = createRequest('/api/rdb/ddl/schema_list', { method: 'get' }); +const getDatabaseSchemaList = createRequest<{ dataSourceId: number; databaseName?: string; schemaName?: string }>( + '/api/rdb/ddl/database_schema_list', + { method: 'get' } +); export default { getList, @@ -96,5 +100,6 @@ export default { getColumnList, getIndexList, getKeyList, - getSchemaList -} \ No newline at end of file + getSchemaList, + getDatabaseSchemaList +}; diff --git a/chat2db-client/src/theme/index.ts b/chat2db-client/src/theme/index.ts index ef7eff1e..affaf40c 100644 --- a/chat2db-client/src/theme/index.ts +++ b/chat2db-client/src/theme/index.ts @@ -1,13 +1,13 @@ import antdDarkTheme from './dark'; import antdLightTheme from './light'; -import { ThemeType, PrimaryColorType } from "@/constants"; -import { ITheme } from '@/typings'; +import { ThemeType, PrimaryColorType } from '@/constants'; +import { ITheme } from '@/typings/theme'; import lodash from 'lodash'; const antdThemeConfigs = { [ThemeType.Dark]: antdDarkTheme, [ThemeType.Light]: antdLightTheme, -} +}; export function getAntdThemeConfig(theme: ITheme) { const antdThemeConfig = lodash.cloneDeep(antdThemeConfigs[theme.backgroundColor]); @@ -15,29 +15,29 @@ export function getAntdThemeConfig(theme: ITheme) { ...antdThemeConfig.token, ...(antdThemeConfig.antdPrimaryColor[theme.primaryColor as PrimaryColorType] || {}), }; - return antdThemeConfig + return antdThemeConfig; } // TODO: 只插入一次 export function InjectThemeVar(token: { [key in string]: string }, theme: ThemeType, primaryColor: PrimaryColorType) { let css = ''; - Object.keys(token).map(t => { + Object.keys(token).map((t) => { const attributeName = camelToDash(t); let value = token[t]; // 将需要px的数字带上px - const joinPxArr = ['fontSize', 'borderRadius'] + const joinPxArr = ['fontSize', 'borderRadius', 'borderRadiusLG']; if (joinPxArr.includes(t)) { - value = value + 'px' + value = value + 'px'; } - css = css + `--${attributeName}: ${value};\n` - }) + css = css + `--${attributeName}: ${value};\n`; + }); const container = `html[theme='${theme}'],html[primary-color='${primaryColor}']{ ${css} - }` + }`; - let style = document.createElement("style"); // 创建style标签 - style.type = "text/css"; + let style = document.createElement('style'); // 创建style标签 + style.type = 'text/css'; style.appendChild(document.createTextNode(container)); document.head.appendChild(style); // 将style标签插入到head标签中 diff --git a/chat2db-client/typings.d.ts b/chat2db-client/typings.d.ts index dc75bbd4..e076dda6 100644 --- a/chat2db-client/typings.d.ts +++ b/chat2db-client/typings.d.ts @@ -4,5 +4,6 @@ declare namespace NodeJS { interface ProcessEnv { readonly NODE_ENV: 'development' | 'production' readonly UMI_ENV: string + readonly __ENV: string; } } \ No newline at end of file