Resolve conflicts.

This commit is contained in:
fanjin.fjy
2023-06-26 21:21:35 +08:00
parent 13250567b1
commit 549aeb8c13
17 changed files with 213 additions and 153 deletions

View File

@ -1,15 +1,17 @@
{
"cSpell.words": [
"Dserver",
"Dspring",
"Sercurity",
"ahooks",
"antd",
"asar",
"cascader",
"Dserver",
"Dspring",
"echarts",
"favicons",
"iconfont",
"nsis",
"pgsql",
"Sercurity",
"sortablejs",
"wireframe"
]

View File

@ -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,
}
},
});

View File

@ -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,
}
},
});

View File

@ -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'],
});

View File

@ -14,4 +14,4 @@
-webkit-font-smoothing: antialiased;
-webkit-text-stroke-width: 0.2px;
-moz-osx-font-smoothing: grayscale;
}
}

View File

@ -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<React.HTMLAttributes<HTMLElement>, HTMLElement>> {
export default class Iconfont extends PureComponent<
{
code: string;
} & React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>
> {
render() {
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

@ -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',
};

View File

@ -17,5 +17,4 @@ export default {
'connection.message.testSshConnection': '测试ssh连接',
'connection.tableHeader.name': '名称',
'connection.tableHeader.value': '值',
'connection.menu.enterToWorkSpace': '前往数据源',
}

View File

@ -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 <div className={styles.appContainer}>
{
initEnd &&
<div className={styles.app}>
<Outlet />
</div>
}
</div>
return (
<div className={styles.appContainer}>
{initEnd && (
<div className={styles.app}>
<Outlet />
</div>
)}
</div>
);
}

View File

@ -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<ConnectionModelState>;
setCurConnection: Reducer<ConnectionModelState>;
};
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<IConnectionDetails>;
console.log('fetchConnectionList==>', res.data);
yield put({
type: 'setConnectionList',
payload: res.data,
});
},
},
};
}
}
export default ConnectionModel;

View File

@ -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;

View File

@ -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<any>();
// const [connectionList, setConnectionList] = useState<IConnectionDetails[]>();
const [curConnection, setCurConnection] = useState<Partial<IConnectionDetails>>({});
@ -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);
}}
>
<div
className={classnames(styles.menuItemsTitle)}
>
<div className={classnames(styles.menuItemsTitle)}>
{icon}
<span style={{ marginLeft: '8px' }}>{label}</span>
</div>
@ -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) {
/>
</div>
) : (
<div className={styles.dataBaseList}>
{databaseTypeList.map((t) => {
return (
<div key={t.code} className={styles.databaseItem} onClick={handleCreateConnections.bind(null, t)}>
<div className={styles.databaseItemMain}>
<div className={styles.databaseItemLeft}>
<div className={styles.logoBox}>
<Iconfont code={t.icon} />
</div>
{t.name}
</div>
<div className={styles.databaseItemRight}>
<Iconfont code="&#xe631;" />
<div className={styles.dataBaseList}>
{databaseTypeList.map((t) => {
return (
<div key={t.code} className={styles.databaseItem} onClick={handleCreateConnections.bind(null, t)}>
<div className={styles.databaseItemMain}>
<div className={styles.databaseItemLeft}>
<div className={styles.logoBox}>
<Iconfont code={t.icon} />
</div>
{t.name}
</div>
<div className={styles.databaseItemRight}>
<Iconfont code="&#xe631;" />
</div>
</div>
);
})}
{
Array.from({ length: 5 }).map(t => {
return <div className={styles.databaseItemSpacer}></div>
})
}
</div>
)}
</div>
);
})}
{Array.from({ length: 20 }).map((t) => {
return <div className={styles.databaseItemSpacer}></div>;
})}
</div>
)}
</div>
</div>
);
};
}
export default connect(({ connection }: { connection: ConnectionState }) => (connection))(Connections);
export default connect(({ connection, database }: { connection: ConnectionModelType; database: any }) => ({
connectionModel: connection,
databaseModel: database,
}))(Connections);

View File

@ -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';

View File

@ -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<IGetListParams, IPageResponse<ITable>>('/api/rdb/ddl/list', {});
@ -83,6 +83,10 @@ const getIndexList = createRequest<ITableParams, IColumn[]>('/api/rdb/ddl/index_
const getKeyList = createRequest<ITableParams, IColumn[]>('/api/rdb/ddl/key_list', { method: 'get' });
const getSchemaList = createRequest<ISchemaParams, ISchemaResponse[]>('/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
}
getSchemaList,
getDatabaseSchemaList
};

View File

@ -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标签中

View File

@ -4,5 +4,6 @@ declare namespace NodeJS {
interface ProcessEnv {
readonly NODE_ENV: 'development' | 'production'
readonly UMI_ENV: string
readonly __ENV: string;
}
}