feat: FE Packages

This commit is contained in:
Jerry Fan
2023-06-23 17:05:06 +08:00
parent 6b3b356fdb
commit 131e87d8f0
18 changed files with 169 additions and 45 deletions

14
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,14 @@
{
"cSpell.words": [
"ahooks",
"antd",
"asar",
"Dserver",
"Dspring",
"echarts",
"nsis",
"pgsql",
"Sercurity",
"sortablejs"
]
}

View File

@ -1,7 +1,7 @@
import { formatDate } from './src/utils/date'; import { formatDate } from './src/utils/date';
import { defineConfig } from 'umi'; import { defineConfig } from 'umi';
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin'); const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
const UMI_PublicPath = process.env.UMI_PublicPath || '/static/front/'; const UMI_PublicPath = process.env.UMI_PublicPath || './';
const chainWebpack = (config: any, { webpack }: any) => { const chainWebpack = (config: any, { webpack }: any) => {
config.plugin('monaco-editor').use(MonacoWebpackPlugin, [ config.plugin('monaco-editor').use(MonacoWebpackPlugin, [
@ -10,13 +10,16 @@ const chainWebpack = (config: any, { webpack }: any) => {
}, },
]); ]);
config.plugin('define').use(require('webpack').DefinePlugin, [{ config.plugin('define').use(require('webpack').DefinePlugin, [
__BUILD_TIME__: JSON.stringify(formatDate(new Date(),'yyyyMMddhhmmss')), {
__BUILD_TIME__: JSON.stringify(formatDate(new Date(), 'yyyyMMddhhmmss')),
__APP_VERSION__: JSON.stringify(process.env.APP_VERSION || '0.0.0'), __APP_VERSION__: JSON.stringify(process.env.APP_VERSION || '0.0.0'),
}]); },
]);
}; };
export default defineConfig({ export default defineConfig({
publicPath: UMI_PublicPath, publicPath: UMI_PublicPath,
chainWebpack chainWebpack,
headScripts: ['if (window.myAPI) { window.myAPI.startServerForSpawn() }'],
}); });

View File

@ -19,8 +19,12 @@ const chainWebpack = (config: any, { webpack }: any) => {
export default defineConfig({ export default defineConfig({
title: 'Chat2DB', title: 'Chat2DB',
history: {
type: 'hash',
},
base: '/', base: '/',
publicPath: '/', publicPath: '/',
hash: false,
routes: [ routes: [
{ path: '/demo', component: '@/pages/demo' }, { path: '/demo', component: '@/pages/demo' },
{ path: '/connections', component: 'main' }, { path: '/connections', component: 'main' },
@ -39,4 +43,5 @@ export default defineConfig({
changeOrigin: true, changeOrigin: true,
}, },
}, },
headScripts: ['if (window.myAPI) { window.myAPI.startServerForSpawn() }'],
}); });

View File

@ -8,7 +8,9 @@
"build": "npm run build:web && npm run build:main", "build": "npm run build:web && npm run build:main",
"build:main": "cross-env NODE_ENV=development electron-builder", "build:main": "cross-env NODE_ENV=development electron-builder",
"build:main:prod": "cross-env NODE_ENV=production electron-builder", "build:main:prod": "cross-env NODE_ENV=production electron-builder",
"build:prod": "npm run build:web:prod && npm run build:main:prod",
"build:web": "umi build", "build:web": "umi build",
"build:web:prod": "cross-env UMI_ENV=prod cross-env APP_VERSION=${npm_config_appVersion} cross-env APP_PORT=${npm_config_appPort} umi build",
"postinstall": "umi setup", "postinstall": "umi setup",
"lint": "umi lint", "lint": "umi lint",
"start": "concurrently \"npm run start:web\" \"npm run start:main\"", "start": "concurrently \"npm run start:web\" \"npm run start:main\"",
@ -59,9 +61,10 @@
"output": "release/" "output": "release/"
}, },
"productName": "Chat2DB", "productName": "Chat2DB",
"asar": true, "asar": false,
"files": [ "files": [
"dist/", "dist/",
"static/",
"src/main", "src/main",
"node_modules/", "node_modules/",
"package.json" "package.json"

View File

@ -1,8 +1,8 @@
@font-face { @font-face {
font-family: "iconfont"; /* Project id 3633546 */ font-family: "iconfont"; /* Project id 3633546 */
src: url('iconfont.woff2?t=1685165802134') format('woff2'), src: url('iconfont.woff2?t=1687510856958') format('woff2'),
url('iconfont.woff?t=1685165802134') format('woff'), url('iconfont.woff?t=1687510856958') format('woff'),
url('iconfont.ttf?t=1685165802134') format('truetype'); url('iconfont.ttf?t=1687510856958') format('truetype');
} }
.iconfont { .iconfont {
@ -13,6 +13,62 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.icon-24gl-folderMinus:before {
content: "\eabe";
}
.icon-24gl-folderOpen:before {
content: "\eabf";
}
.icon-24gf-folderOpen:before {
content: "\eac7";
}
.icon-yunshujuku:before {
content: "\e744";
}
.icon-baobiao:before {
content: "\e612";
}
.icon-gongzuotai:before {
content: "\e614";
}
.icon-mongodb:before {
content: "\ec21";
}
.icon-Redis:before {
content: "\e6a2";
}
.icon-HIVE:before {
content: "\e60e";
}
.icon-Kingbase:before {
content: "\e6a0";
}
.icon-yibiaopan:before {
content: "\e60d";
}
.icon-presto_sql:before {
content: "\e60b";
}
.icon-shujukuleixingtubiao-kuozhan-:before {
content: "\e60a";
}
.icon-oceanbase:before {
content: "\e982";
}
.icon-dameng1:before { .icon-dameng1:before {
content: "\e655"; content: "\e655";
} }

View File

@ -350,10 +350,10 @@ function RenderForm(props: IRenderFormProps) {
if (keyName === 'host' && !aliasChanged) { if (keyName === 'host' && !aliasChanged) {
newData.alias = '@' + keyValue; newData.alias = '@' + keyValue;
} }
console.log({ // console.log({
...dataObj, // ...dataObj,
...newData, // ...newData,
}); // });
form.setFieldsValue({ form.setFieldsValue({
...dataObj, ...dataObj,
...newData, ...newData,

View File

@ -1,14 +1,20 @@
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import classnames from 'classnames'; import classnames from 'classnames';
// import desktopStyle from './desktop.less'; import desktopStyle from './desktop.less';
// TODO: windows端加载cdn资源报错
import prodStyle from './prod.less'; import prodStyle from './prod.less';
export default class Iconfont extends PureComponent<{
export default class Iconfont extends PureComponent<
{
code: string; code: string;
} & React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>> { } & React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>
> {
render() { render() {
// const styles = window._ENV !== 'prod' ? desktopStyle : prodStyle const styles = window._ENV !== 'prod' ? desktopStyle : prodStyle;
const styles = prodStyle; // const styles = prodStyle;
return <i {...this.props} className={classnames(this.props.className, styles.iconfont)}>{this.props.code}</i> return (
<i {...this.props} className={classnames(this.props.className, styles.iconfont)}>
{this.props.code}
</i>
);
} }
} }

View File

@ -1,7 +1,7 @@
const DEV_WEB_URL = 'http://localhost:8000/'; const DEV_WEB_URL = 'http://localhost:8000/';
/** jar包名 */ /** jar包名 */
const JAVA_APP_NAME = 'ali-dbhub-server-start.jar'; const JAVA_APP_NAME = 'chat2db-server-start.jar';
const JAVA_PATH = 'jre/bin/java'; const JAVA_PATH = 'jre/bin/java';
module.exports = { module.exports = {

View File

@ -1,5 +1,7 @@
const { app, BrowserWindow, Menu, ipcMain } = require('electron'); const { app, BrowserWindow, Menu, shell, net, ipcMain, dialog } = require('electron');
const path = require('path'); const path = require('path');
const os = require('os');
const fs = require('fs');
const menuBar = require('./menu'); const menuBar = require('./menu');
const { loadMainResource } = require('./utils'); const { loadMainResource } = require('./utils');
let mainWindow = null; let mainWindow = null;
@ -9,12 +11,25 @@ function createWindow() {
minWidth: 1080, minWidth: 1080,
minHeight: 720, minHeight: 720,
show: false, show: false,
webPreferences: {
webSercurity: false,
nodeIntegration: true,
contextIsolation: true,
preload: path.join(__dirname, 'preload.js'),
},
}); });
mainWindow.maximize(); mainWindow.maximize();
mainWindow.show(); mainWindow.show();
// 加载应用-----
loadMainResource(mainWindow); loadMainResource(mainWindow);
// 关闭window时触发下列事件.
mainWindow.on('closed', function (event) {
event.preventDefault();
mainWindow = null;
});
// 监听打开新窗口事件 用默认浏览器打开 // 监听打开新窗口事件 用默认浏览器打开
mainWindow.webContents.on('new-window', function (event, url) { mainWindow.webContents.on('new-window', function (event, url) {
event.preventDefault(); event.preventDefault();
@ -26,14 +41,16 @@ function createWindow() {
}); });
} }
const menu = Menu.buildFromTemplate(menuBar); // const menu = Menu.buildFromTemplate(menuBar);
Menu.setApplicationMenu(menu); // Menu.setApplicationMenu(menu);
app.on('ready', () => { app.on('ready', () => {
createWindow(); createWindow();
app.on('activate', function () { app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow(); if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
}); });
}); });
app.on('window-all-closed', () => { app.on('window-all-closed', () => {
@ -42,8 +59,30 @@ app.on('window-all-closed', () => {
} }
}); });
app.on('before-quit', (event) => {
const request = net.request({
headers: {
'Content-Type': 'application/json',
},
method: 'POST',
url: 'http://127.0.0.1:10824/api/system/stop',
});
request.write(JSON.stringify({}));
request.on('response', (response) => {
response.on('data', (res) => {
let data = JSON.parse(res.toString());
});
response.on('end', () => {});
});
request.end();
});
ipcMain.handle('get-product-name', (event) => { ipcMain.handle('get-product-name', (event) => {
const exePath = app.getPath('exe'); const exePath = app.getPath('exe');
const { name } = path.parse(exePath); const { name } = path.parse(exePath);
return name; return name;
}); });
module.exports = {
mainWindow,
};

View File

@ -1,4 +1,7 @@
const i18n = require('./i18n'); const i18n = require('./i18n');
const { shell } = require('electron');
const { mainWindow } = require('./index');
const menuBar = [ const menuBar = [
{ {
label: 'Chat2DB', label: 'Chat2DB',
@ -37,8 +40,7 @@ const menuBar = [
submenu: [ submenu: [
{ {
label: '打开日志', label: '打开日志',
accelerator: accelerator: process.platform === 'darwin' ? 'Cmd+Shift+L' : 'Ctrl+Shift+L',
process.platform === 'darwin' ? 'Cmd+Shift+L' : 'Ctrl+Shift+L',
click() { click() {
const fileName = '.chat2db/logs/application.log'; const fileName = '.chat2db/logs/application.log';
const url = path.join(os.homedir(), fileName); const url = path.join(os.homedir(), fileName);
@ -47,8 +49,7 @@ const menuBar = [
}, },
{ {
label: '打开控制台', label: '打开控制台',
accelerator: accelerator: process.platform === 'darwin' ? 'Cmd+Shift+I' : 'Ctrl+Shift+I',
process.platform === 'darwin' ? 'Cmd+Shift+I' : 'Ctrl+Shift+I',
click() { click() {
mainWindow && mainWindow.toggleDevTools(); mainWindow && mainWindow.toggleDevTools();
}, },

View File

@ -5,7 +5,7 @@ const path = require('path');
contextBridge.exposeInMainWorld('myAPI', { contextBridge.exposeInMainWorld('myAPI', {
startServerForSpawn: async () => { startServerForSpawn: async () => {
const path1 = path.join(__dirname, `app/${JAVA_APP_NAME}`); const javaPath = path.join(__dirname, '../..', `./static/${JAVA_APP_NAME}`);
const productName = await ipcRenderer.invoke('get-product-name'); const productName = await ipcRenderer.invoke('get-product-name');
@ -13,12 +13,12 @@ contextBridge.exposeInMainWorld('myAPI', {
console.log('productName:', productName, isTest); console.log('productName:', productName, isTest);
const child = spawn(path.join(__dirname, JAVA_PATH), [ const child = spawn(path.join(__dirname, '../..', `./static/${JAVA_PATH}`), [
'-jar', '-jar',
'-Xmx512M', '-Xmx512M',
`-Dspring.profiles.active=${isTest ? 'test' : 'release'}`, `-Dspring.profiles.active=${isTest ? 'test' : 'release'}`,
'-Dserver.address=127.0.0.1', '-Dserver.address=127.0.0.1',
path1, javaPath,
]); ]);
child.stdout.on('data', (buffer) => { child.stdout.on('data', (buffer) => {
@ -30,7 +30,6 @@ contextBridge.exposeInMainWorld('myAPI', {
}); });
child.stderr.on('data', (data) => { child.stderr.on('data', (data) => {
console.error(`stderr: ${data}`); console.error(`stderr: ${data}`);
// alert('启动服务异常');
}); });
child.on('close', (code) => { child.on('close', (code) => {
console.log(`child process exited with code ${code}`); console.log(`child process exited with code ${code}`);

View File

@ -1,6 +1,6 @@
const electronReload = require('electron-reload');
const { DEV_WEB_URL } = require('./constants'); const { DEV_WEB_URL } = require('./constants');
const path = require('path'); const path = require('path');
const url = require('url');
/** /**
* 加载主进程前端资源 * 加载主进程前端资源
@ -12,11 +12,11 @@ function loadMainResource(mainWindow) {
mainWindow.webContents.openDevTools(); mainWindow.webContents.openDevTools();
// 监听应用程序根路径下的所有文件,当文件发生修改时,自动刷新应用程序 // 监听应用程序根路径下的所有文件,当文件发生修改时,自动刷新应用程序
electronReload(path.join(__dirname, '..')); require('electron-reload')(path.join(__dirname, '..'));
} else { } else {
mainWindow.loadURL( mainWindow.loadURL(
url.format({ url.format({
pathname: path.join(__dirname, './dist/index.html'), pathname: path.join(__dirname, '../..', './dist/index.html'),
protocol: 'file:', protocol: 'file:',
slashes: true, slashes: true,
}), }),

View File

@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<link rel="icon" type="image/ico" sizes="32x32" href="./static/front/logo.ico"> <link rel="icon" type="image/ico" sizes="32x32" href="../assets/logo/logo.png">
<title>Chat2DB</title> <title>Chat2DB</title>
<meta name="description" content="Chat2DB 是面向开发人员的免费多平台数据库工具。多种数据库一个工具。它用于查询、创建和管理数据库,数据库可以在本地、服务器或云端。支持 MySQL、PostgreSQL、Microsoft SQL Server、Oracle、H2等未来我们会不断完善其他非关系型数据的支持如Redis。"> <meta name="description" content="Chat2DB 是面向开发人员的免费多平台数据库工具。多种数据库一个工具。它用于查询、创建和管理数据库,数据库可以在本地、服务器或云端。支持 MySQL、PostgreSQL、Microsoft SQL Server、Oracle、H2等未来我们会不断完善其他非关系型数据的支持如Redis。">
<meta name="keywords" content="数据库chatgptchatDBdatabase后端程序员数据库" > <meta name="keywords" content="数据库chatgptchatDBdatabase后端程序员数据库" >
@ -16,8 +16,7 @@
<body> <body>
<div id="root"></div> <div id="root"></div>
<script> <script>
console.log('run startServer'); console.log('run startServer: window.myAPI', window.myAPI);
console.log('window===>', window.myAPI)
if (window.myAPI) { if (window.myAPI) {
window.myAPI.startServerForSpawn(); window.myAPI.startServerForSpawn();
} }

View File

@ -25,8 +25,6 @@ const handleSQLResult2ChartData = (data) => {
return mockData; return mockData;
}; };
console.log('xxx', handleSQLResult2ChartData(data[0]));
function countArrayElements<T>(arr: T[]): { name: T; value: number }[] { function countArrayElements<T>(arr: T[]): { name: T; value: number }[] {
const counts = new Map<T, number>(); const counts = new Map<T, number>();
// 统计每个元素出现的次数 // 统计每个元素出现的次数

View File

@ -180,7 +180,8 @@ public class JdbcUtils {
if ("java.sql.Timestamp".equals(rs.getMetaData().getColumnClassName(index))) { if ("java.sql.Timestamp".equals(rs.getMetaData().getColumnClassName(index))) {
return DateUtil.format(rs.getDate(index), DEFAULT_DATETIME_FORMAT); return DateUtil.format(rs.getDate(index), DEFAULT_DATETIME_FORMAT);
} }
return DateUtil.format(date, DEFAULT_DATETIME_FORMAT); // return DateUtil.format(date, DEFAULT_DATETIME_FORMAT);
return null;
} }
if (obj instanceof LocalDateTime localDateTime) { if (obj instanceof LocalDateTime localDateTime) {
return localDateTime.toString(); return localDateTime.toString();