Compare commits
2 Commits
e2c223b22e
...
b584915bb7
| Author | SHA1 | Date |
|---|---|---|
|
|
b584915bb7 | |
|
|
3c12f72410 |
|
|
@ -24,18 +24,18 @@ export default defineConfig({
|
||||||
},
|
},
|
||||||
// 路由配置
|
// 路由配置
|
||||||
routes: [
|
routes: [
|
||||||
// {
|
|
||||||
// path: '/',
|
|
||||||
// component: '@/pages/welcome',
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// path: '/login',
|
|
||||||
// component: '@/pages/login',
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
component: '@/pages/components/Layout/index',
|
component: '@/pages/components/Layout/index',
|
||||||
routes: [
|
routes: [
|
||||||
|
{
|
||||||
|
path: '/imagesList',
|
||||||
|
component: '@/pages/imagesList',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/login',
|
||||||
|
component: '@/pages/login',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/grpc',
|
path: '/grpc',
|
||||||
component: '@/pages/grpc/grpc',
|
component: '@/pages/grpc/grpc',
|
||||||
|
|
@ -44,10 +44,6 @@ export default defineConfig({
|
||||||
path: '/welcome',
|
path: '/welcome',
|
||||||
component: '@/pages/welcome',
|
component: '@/pages/welcome',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: '/login',
|
|
||||||
component: '@/pages/login',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: '/configSteps',
|
path: '/configSteps',
|
||||||
component: '@/pages/configSteps',
|
component: '@/pages/configSteps',
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 3.4 KiB |
|
|
@ -1 +1,28 @@
|
||||||
getBrowserWindowRuntime().webContents.openDevTools();
|
getBrowserWindowRuntime().webContents.openDevTools();
|
||||||
|
|
||||||
|
// import { BrowserWindow } from 'electron';
|
||||||
|
// import path from 'path';
|
||||||
|
|
||||||
|
// // 修复:添加默认值处理
|
||||||
|
// const APP_ROOT = process.env.APP_ROOT || '.';
|
||||||
|
// const MAIN_DIST = path.join(APP_ROOT, 'dist-electron');
|
||||||
|
|
||||||
|
// getBrowserWindowRuntime().webContents.openDevTools();
|
||||||
|
|
||||||
|
// const createNewWindow = () => {
|
||||||
|
// const newWindow = new BrowserWindow({
|
||||||
|
// width: 200,
|
||||||
|
// height: 200,
|
||||||
|
// webPreferences: {
|
||||||
|
// nodeIntegration: true,
|
||||||
|
// contextIsolation: false
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
// // 加载页面内容
|
||||||
|
// newWindow.loadURL('file:/' + __dirname + '/index.html');
|
||||||
|
|
||||||
|
// return newWindow;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// createNewWindow();
|
||||||
|
|
@ -12,16 +12,54 @@ const window = getBrowserWindowRuntime();
|
||||||
|
|
||||||
let currentServerIp: string | undefined;
|
let currentServerIp: string | undefined;
|
||||||
|
|
||||||
|
// 添加处理窗口调整
|
||||||
|
ipcMain.handle('adjust-window-for-normal', async (event) => {
|
||||||
|
try {
|
||||||
|
const window = BrowserWindow.fromWebContents(event.sender);
|
||||||
|
if (window) {
|
||||||
|
// 调整窗口大小和配置
|
||||||
|
window.setKiosk(false); // 退出全屏模式
|
||||||
|
window.setMinimumSize(1200, 800);
|
||||||
|
window.setSize(1200, 800);
|
||||||
|
window.setResizable(true);
|
||||||
|
window.setMaximizable(true);
|
||||||
|
window.setMinimizable(true);
|
||||||
|
// 保持无边框和隐藏标题栏的设置
|
||||||
|
window.setFullScreen(false);
|
||||||
|
}
|
||||||
|
return { success: true };
|
||||||
|
} catch (error) {
|
||||||
|
console.error('调整窗口失败:', error);
|
||||||
|
return { success: false, };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**拖动窗口 */
|
||||||
|
ipcMain.handle('drag-window', (event) => {
|
||||||
|
const focusedWindow = BrowserWindow.getFocusedWindow();
|
||||||
|
if (focusedWindow) {
|
||||||
|
// 通知渲染进程开始拖拽
|
||||||
|
focusedWindow.webContents.send('start-drag');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// 监听渲染进程发送的消息
|
// 监听渲染进程发送的消息
|
||||||
ipcMain.handle('getPlatform', () => {
|
ipcMain.handle('getPlatform', () => {
|
||||||
return `hi, i'm from ${process.platform}`;
|
return `hi, i'm from ${process.platform}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 窗口控制:最小化,退出全屏
|
// 窗口控制:最小化,退出全屏,关闭,
|
||||||
|
// 获取窗口最大化状态
|
||||||
|
ipcMain.handle('get-window-maximized', (event) => {
|
||||||
|
const window = BrowserWindow.fromWebContents(event.sender);
|
||||||
|
return window?.isMaximized() || false;
|
||||||
|
});
|
||||||
|
|
||||||
ipcMain.on('close-app', () => {
|
ipcMain.on('close-app', () => {
|
||||||
app.quit();
|
app.quit();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 最小化
|
||||||
ipcMain.on('minimize-app', () => {
|
ipcMain.on('minimize-app', () => {
|
||||||
const focusedWindow = BrowserWindow.getFocusedWindow();
|
const focusedWindow = BrowserWindow.getFocusedWindow();
|
||||||
if (focusedWindow) {
|
if (focusedWindow) {
|
||||||
|
|
@ -30,16 +68,39 @@ ipcMain.on('minimize-app', () => {
|
||||||
// window?.minimize();
|
// window?.minimize();
|
||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on('exit-kiosk', () => {
|
// 退出全屏
|
||||||
|
ipcMain.on('restore-window', () => {
|
||||||
const focusedWindow = BrowserWindow.getFocusedWindow();
|
const focusedWindow = BrowserWindow.getFocusedWindow();
|
||||||
if (focusedWindow) {
|
if (focusedWindow) {
|
||||||
focusedWindow.setFullScreen(false);
|
focusedWindow.unmaximize();
|
||||||
}
|
}
|
||||||
// if (window) {
|
// if (window) {
|
||||||
// window.setFullScreen(false);
|
// window.setFullScreen(false);
|
||||||
// }
|
// }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 设置全屏
|
||||||
|
ipcMain.on('maximize-window', () => {
|
||||||
|
const focusedWindow = BrowserWindow.getFocusedWindow();
|
||||||
|
if (focusedWindow) {
|
||||||
|
focusedWindow.maximize();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 监听窗口状态变化并通知渲染进程
|
||||||
|
ipcMain.on('register-window-state-listeners', (event) => {
|
||||||
|
const window = BrowserWindow.fromWebContents(event.sender);
|
||||||
|
if (window) {
|
||||||
|
window.on('maximize', () => {
|
||||||
|
event.sender.send('window-maximized');
|
||||||
|
});
|
||||||
|
|
||||||
|
window.on('unmaximize', () => {
|
||||||
|
event.sender.send('window-unmaximized');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
ipcMain.handle('get-device-id',async()=>{
|
ipcMain.handle('get-device-id',async()=>{
|
||||||
const deviceId = await getDeviceId();
|
const deviceId = await getDeviceId();
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,14 @@ contextBridge.exposeInMainWorld('electronAPI', {
|
||||||
},
|
},
|
||||||
closeApp: () => ipcRenderer.send('close-app'),
|
closeApp: () => ipcRenderer.send('close-app'),
|
||||||
minimizeApp: () => ipcRenderer.send('minimize-app'),
|
minimizeApp: () => ipcRenderer.send('minimize-app'),
|
||||||
exitKiosk: () => ipcRenderer.send('exit-kiosk'),
|
restoreWindow: () => ipcRenderer.send('restore-window'),
|
||||||
|
maximizeWindow: () => ipcRenderer.send('maximize-window'),
|
||||||
|
getWindowMaximized: () => ipcRenderer.invoke('get-window-maximized'),
|
||||||
|
adjustWindowForNormal:() => ipcRenderer.invoke('adjust-window-for-normal'),
|
||||||
// 版本更新相关API
|
// 版本更新相关API
|
||||||
downloadAndUpdate: (url: string) => ipcRenderer.invoke('download-and-update', url),
|
downloadAndUpdate: (url: string) => ipcRenderer.invoke('download-and-update', url),
|
||||||
// 服务器IP获取
|
// 服务器IP获取
|
||||||
getCurrentServerIp: () => ipcRenderer.invoke('get-current-server-ip'),
|
getCurrentServerIp: () => ipcRenderer.invoke('get-current-server-ip'),
|
||||||
|
|
||||||
// 事件监听
|
// 事件监听
|
||||||
onMainProcessMessage: (callback: (data: string) => void) => {
|
onMainProcessMessage: (callback: (data: string) => void) => {
|
||||||
ipcRenderer.on('main-process-message', (_, data) => callback(data));
|
ipcRenderer.on('main-process-message', (_, data) => callback(data));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
// src/pages/components/TitleBar/index.less
|
||||||
|
.title-bar {
|
||||||
|
margin: 20px 0;
|
||||||
|
padding: 0 20px;
|
||||||
|
width: 100%;
|
||||||
|
height: 34px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
-webkit-app-region: drag; // 使整个标题栏可拖动
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
.title-bar-right {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
-webkit-app-region: no-drag; // 使按钮区域不可拖动
|
||||||
|
|
||||||
|
.window-control {
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
border: 1.5px solid rgba(34, 34, 34, 1);
|
||||||
|
margin-left: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&.minimize {
|
||||||
|
// 最小化按钮样式(一条线)
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
width: 10px;
|
||||||
|
height: 1.5px;
|
||||||
|
background-color: rgba(34, 34, 34, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.restore {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
border: 1px solid rgba(34, 34, 34, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 30%;
|
||||||
|
left: 30%;
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
border: 1px solid rgba(34, 34, 34, 1);
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.maximize {
|
||||||
|
// 最大化按钮样式(正方形框)
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
border: 1px solid rgba(34, 34, 34, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.close {
|
||||||
|
// 关闭按钮样式(×)
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::before,
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
width: 12px;
|
||||||
|
height: 1.5px;
|
||||||
|
background-color: rgba(34, 34, 34, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
transform: translate(-50%, -50%) rotate(45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
transform: translate(-50%, -50%) rotate(-45deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
// src/pages/components/TitleBar/index.tsx
|
||||||
|
import React,{ useState, useEffect } from 'react';
|
||||||
|
import './index.less';
|
||||||
|
import BarIcon from '@assets/barIcon.png'
|
||||||
|
|
||||||
|
const TitleBar = () => {
|
||||||
|
const [isMaximized, setIsMaximized] = useState(false);
|
||||||
|
|
||||||
|
// 监听窗口状态变化
|
||||||
|
useEffect(() => {
|
||||||
|
if (window.electronAPI) {
|
||||||
|
// 注册窗口状态变化监听器
|
||||||
|
window.electronAPI.send('register-window-state-listeners');
|
||||||
|
|
||||||
|
window.electronAPI.on('window-maximized', () => {
|
||||||
|
setIsMaximized(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
window.electronAPI.on('window-unmaximized', () => {
|
||||||
|
setIsMaximized(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 初始化时获取窗口状态
|
||||||
|
window.electronAPI.getWindowMaximized().then((maximized: boolean) => {
|
||||||
|
setIsMaximized(maximized);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
const closeApp = () => {
|
||||||
|
if (window.electronAPI) {
|
||||||
|
window.electronAPI.closeApp();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const minimizeApp = () => {
|
||||||
|
if (window.electronAPI) {
|
||||||
|
window.electronAPI.minimizeApp();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 区分当前是最小化还是最大化
|
||||||
|
const toggleMaximize = () => {
|
||||||
|
if (window.electronAPI) {
|
||||||
|
if (isMaximized) {
|
||||||
|
window.electronAPI.restoreWindow();
|
||||||
|
} else {
|
||||||
|
window.electronAPI.maximizeWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="title-bar" onMouseDown={(e) => {
|
||||||
|
// 只有点击在标题栏空白处才触发拖动
|
||||||
|
if (e.target === e.currentTarget) {
|
||||||
|
window.electronAPI.send('drag-window');
|
||||||
|
}
|
||||||
|
}}>
|
||||||
|
<div className="title-bar-left">
|
||||||
|
<img src={BarIcon} />
|
||||||
|
</div>
|
||||||
|
<div className="title-bar-right">
|
||||||
|
<div className="window-control minimize" onClick={minimizeApp}></div>
|
||||||
|
<div className={`window-control ${isMaximized ? 'restore' : 'maximize'}`} onClick={toggleMaximize}></div>
|
||||||
|
<div className="window-control close" onClick={closeApp}></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TitleBar;
|
||||||
|
|
@ -74,8 +74,18 @@ const Index = () => {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleSubmit = () => {
|
const handleSubmit = async() => {
|
||||||
|
try {
|
||||||
|
// 调用主进程调整窗口
|
||||||
|
if (window.electronAPI) {
|
||||||
|
await window.electronAPI.adjustWindowForNormal();
|
||||||
|
}
|
||||||
|
// 跳转到登录页面
|
||||||
history.push('/login');
|
history.push('/login');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('跳转登录页失败:', error);
|
||||||
|
message.error('跳转失败,请重试');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const Index = () => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
镜像列表
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Index;
|
||||||
|
|
@ -1,34 +1,142 @@
|
||||||
.login-container {
|
.login-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: space-between;
|
||||||
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-content {
|
.login-content {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 400px;
|
flex: 1;
|
||||||
padding: 20px;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-card {
|
.login-card {
|
||||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
|
width: 390px;
|
||||||
.ant-card-head {
|
height: 520px;
|
||||||
text-align: center;
|
padding: 0 30px;
|
||||||
border-bottom: 1px solid #f0f0f0;
|
padding-top: 79px;
|
||||||
|
box-sizing: border-box;
|
||||||
.ant-card-head-title {
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-card-body {
|
.ant-card-body {
|
||||||
padding: 32px 24px;
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome-text {
|
||||||
|
font-family: "Microsoft YaHei UI";
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: normal;
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 100%;
|
||||||
|
letter-spacing: 0%;
|
||||||
|
color: rgba(36, 47, 72, 1);
|
||||||
|
margin-bottom: 40px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group {
|
||||||
|
margin-bottom: 40px;
|
||||||
|
|
||||||
|
.ant-form-item {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-input {
|
||||||
|
width: 330px;
|
||||||
|
height: 39px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: rgba(255, 255, 255, 1);
|
||||||
|
border: 1px solid rgba(215, 217, 224, 1);
|
||||||
|
|
||||||
|
.ant-input-prefix {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-icon {
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
margin-left: 10px;
|
||||||
|
margin-right: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::placeholder {
|
||||||
|
font-family: "Microsoft YaHei UI";
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 100%;
|
||||||
|
letter-spacing: 0%;
|
||||||
|
color: rgba(160, 163, 173, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
font-family: "Microsoft YaHei UI";
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 100%;
|
||||||
|
letter-spacing: 0%;
|
||||||
|
color: rgba(160, 163, 173, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-button {
|
||||||
|
height: 39px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: rgba(1, 90, 255, 1);
|
||||||
|
border: none;
|
||||||
|
font-family: "Microsoft YaHei UI";
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 100%;
|
||||||
|
letter-spacing: 0%;
|
||||||
|
color: rgba(255, 255, 255, 1);
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba(1, 90, 255, 0.9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-group {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-checkbox {
|
||||||
|
font-family: "Microsoft YaHei UI";
|
||||||
|
font-weight: 400;
|
||||||
|
font-style: normal;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 100%;
|
||||||
|
letter-spacing: 0%;
|
||||||
|
color: rgba(88, 97, 116, 1);
|
||||||
|
|
||||||
|
.ant-checkbox-inner {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-checkbox-checked .ant-checkbox-inner {
|
||||||
|
background-color: rgba(1, 90, 255, 1);
|
||||||
|
border-color: rgba(1, 90, 255, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -49,30 +157,3 @@
|
||||||
.ant-form-item {
|
.ant-form-item {
|
||||||
margin-bottom: 24px;
|
margin-bottom: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-input-affix-wrapper {
|
|
||||||
border-radius: 6px;
|
|
||||||
border: 1px solid #d9d9d9;
|
|
||||||
|
|
||||||
&:hover,
|
|
||||||
&:focus,
|
|
||||||
&.ant-input-affix-wrapper-focused {
|
|
||||||
border-color: #667eea;
|
|
||||||
box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.ant-btn-primary {
|
|
||||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
||||||
border: none;
|
|
||||||
border-radius: 6px;
|
|
||||||
height: 44px;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 500;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: linear-gradient(135deg, #5a6fd8 0%, #6a4190 100%);
|
|
||||||
transform: translateY(-1px);
|
|
||||||
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +1,14 @@
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { Form, Input, Button, Card, message } from 'antd';
|
import { Form, Input, Button, Card, message, Checkbox } from 'antd';
|
||||||
import { UserOutlined, LockOutlined } from '@ant-design/icons';
|
import { UserOutlined, LockOutlined, LinkOutlined } from '@ant-design/icons';
|
||||||
import { history } from 'umi';
|
import { history } from 'umi';
|
||||||
|
import TitleBar from '../components/TitleBar';
|
||||||
import './index.less';
|
import './index.less';
|
||||||
|
|
||||||
interface LoginForm {
|
interface LoginForm {
|
||||||
username: string;
|
username: string;
|
||||||
password: string;
|
password: string;
|
||||||
|
server: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const LoginPage: React.FC = () => {
|
const LoginPage: React.FC = () => {
|
||||||
|
|
@ -22,7 +24,7 @@ const LoginPage: React.FC = () => {
|
||||||
localStorage.setItem('isLoggedIn', 'true');
|
localStorage.setItem('isLoggedIn', 'true');
|
||||||
localStorage.setItem('username', values.username);
|
localStorage.setItem('username', values.username);
|
||||||
// 跳转到镜像列表页面
|
// 跳转到镜像列表页面
|
||||||
history.push('/images');
|
history.push('/imagesList');
|
||||||
} else {
|
} else {
|
||||||
message.error('用户名或密码错误!');
|
message.error('用户名或密码错误!');
|
||||||
}
|
}
|
||||||
|
|
@ -33,41 +35,35 @@ const LoginPage: React.FC = () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const closeApp = () => {
|
const test = () => {
|
||||||
if (window.electronAPI) {
|
setTimeout(() => {
|
||||||
window.electronAPI.closeApp();
|
// history.push('/login');
|
||||||
|
history.push('/configSteps?tab=terminalGetImage');
|
||||||
|
},1000)
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
const minimizeApp = () => {
|
|
||||||
if (window.electronAPI) {
|
|
||||||
window.electronAPI.minimizeApp();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const exitKioskMode = () => {
|
|
||||||
if (window.electronAPI) {
|
|
||||||
window.electronAPI.exitKiosk();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="login-container">
|
<div className="login-container">
|
||||||
|
<TitleBar />
|
||||||
|
<Button onClick={test}>测试窗口变化样式问题</Button>
|
||||||
<div className="login-content">
|
<div className="login-content">
|
||||||
<Card className="login-card" title="系统登录" bordered={false}>
|
<Card className="login-card" bordered={false}>
|
||||||
|
<div className="welcome-text">欢迎登录 X Space</div>
|
||||||
<Form
|
<Form
|
||||||
name="login"
|
name="login"
|
||||||
onFinish={onFinish}
|
onFinish={onFinish}
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
size="large"
|
size="large"
|
||||||
>
|
>
|
||||||
|
<div className="input-group">
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="username"
|
name="username"
|
||||||
rules={[{ required: true, message: '请输入用户名!' }]}
|
rules={[{ required: true, message: '请输入账户名!' }]}
|
||||||
>
|
>
|
||||||
<Input
|
<Input
|
||||||
prefix={<UserOutlined />}
|
prefix={<UserOutlined className="input-icon" />}
|
||||||
placeholder="用户名"
|
placeholder="请输入账户名"
|
||||||
|
className="custom-input"
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
|
|
@ -76,26 +72,40 @@ const LoginPage: React.FC = () => {
|
||||||
rules={[{ required: true, message: '请输入密码!' }]}
|
rules={[{ required: true, message: '请输入密码!' }]}
|
||||||
>
|
>
|
||||||
<Input.Password
|
<Input.Password
|
||||||
prefix={<LockOutlined />}
|
prefix={<LockOutlined className="input-icon" />}
|
||||||
placeholder="密码"
|
placeholder="请输入密码"
|
||||||
|
className="custom-input"
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
|
<Form.Item
|
||||||
|
name="server"
|
||||||
|
rules={[{ required: true, message: '请输入服务器地址!' }]}
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
prefix={<LinkOutlined className="input-icon" />}
|
||||||
|
placeholder="请输入服务器地址"
|
||||||
|
className="custom-input"
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Form.Item>
|
<Form.Item>
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
htmlType="submit"
|
htmlType="submit"
|
||||||
loading={loading}
|
loading={loading}
|
||||||
block
|
block
|
||||||
|
className="login-button"
|
||||||
>
|
>
|
||||||
登录
|
登录
|
||||||
</Button>
|
</Button>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
<div>
|
|
||||||
<Button onClick={closeApp}>关闭应用</Button>
|
<div className="checkbox-group">
|
||||||
<Button onClick={minimizeApp}>最小化</Button>
|
<Checkbox className="custom-checkbox">自动登录</Checkbox>
|
||||||
<Button onClick={exitKioskMode}>退出全屏模式</Button>
|
<Checkbox className="custom-checkbox">记住密码</Checkbox>
|
||||||
</div>
|
</div>
|
||||||
<div className="login-tips">
|
<div className="login-tips">
|
||||||
<p>提示:用户名 admin,密码 123456</p>
|
<p>提示:用户名 admin,密码 123456</p>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue