From 8e44ce7c573ed66a0d706628f540f1a34cf3c0d3 Mon Sep 17 00:00:00 2001
From: suixy <2277317060@qq.com>
Date: Thu, 11 Jun 2026 15:22:20 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0electron=E6=89=93=E5=8C=85=20?=
=?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=8A=A5=E8=AD=A6=E8=A7=84=E5=88=99?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.env.electron | 33 ++++++
.gitignore | 1 +
electron/main.cjs | 52 +++++++++
electron/preload.cjs | 5 +
package.json | 40 +++++++
src/App.vue | 215 +++++++++++++++++++++++++++++++++---
src/layout/index.vue | 8 +-
src/router/index.ts | 8 +-
src/types/env.d.ts | 1 +
src/utils/alarmReminder.js | 44 +++++++-
vite/plugins/compression.ts | 10 +-
11 files changed, 391 insertions(+), 26 deletions(-)
create mode 100644 .env.electron
create mode 100644 electron/main.cjs
create mode 100644 electron/preload.cjs
diff --git a/.env.electron b/.env.electron
new file mode 100644
index 0000000..373a354
--- /dev/null
+++ b/.env.electron
@@ -0,0 +1,33 @@
+# 页面标题
+VITE_APP_TITLE = HaiWei-Plus能源管理系统
+VITE_APP_LOGO_TITLE = RuoYi-Vue-Plus
+
+# Electron 桌面端配置
+VITE_APP_ENV = 'electron'
+VITE_APP_ELECTRON = true
+
+# Electron 使用 file:// 加载本地页面,静态资源必须使用相对路径
+VITE_APP_CONTEXT_PATH = './'
+
+# 桌面端没有 Vite/Nginx 代理,这里必须配置为真实后端地址。
+# 如后端部署在其他机器,请改为对应地址,例如 'https://example.com/prod-api'。
+VITE_APP_BASE_API = 'http://localhost:8080'
+
+# 监控地址
+VITE_APP_MONITOR_ADMIN = '/admin/applications'
+
+# SnailJob 控制台地址
+VITE_APP_SNAILJOB_ADMIN = '/snail-job'
+
+# 是否在打包时开启压缩,支持 gzip 和 brotli
+VITE_BUILD_COMPRESS = gzip
+
+VITE_APP_PORT = 80
+
+# 接口加密功能开关(如需关闭 后端也必须对应关闭)
+VITE_APP_ENCRYPT = true
+VITE_APP_RSA_PUBLIC_KEY = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=='
+VITE_APP_RSA_PRIVATE_KEY = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAmc3CuPiGL/LcIIm7zryCEIbl1SPzBkr75E2VMtxegyZ1lYRD+7TZGAPkvIsBcaMs6Nsy0L78n2qh+lIZMpLH8wIDAQABAkEAk82Mhz0tlv6IVCyIcw/s3f0E+WLmtPFyR9/WtV3Y5aaejUkU60JpX4m5xNR2VaqOLTZAYjW8Wy0aXr3zYIhhQQIhAMfqR9oFdYw1J9SsNc+CrhugAvKTi0+BF6VoL6psWhvbAiEAxPPNTmrkmrXwdm/pQQu3UOQmc2vCZ5tiKpW10CgJi8kCIFGkL6utxw93Ncj4exE/gPLvKcT+1Emnoox+O9kRXss5AiAMtYLJDaLEzPrAWcZeeSgSIzbL+ecokmFKSDDcRske6QIgSMkHedwND1olF8vlKsJUGK3BcdtM8w4Xq7BpSBwsloE='
+VITE_APP_CLIENT_ID = 'e5cd7e4891bf95d1d19206ce24a7b32e'
+VITE_APP_WEBSOCKET = false
+VITE_APP_SSE = true
diff --git a/.gitignore b/.gitignore
index 1fd56f0..6d59a54 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
.history
node_modules/
dist/
+release/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
diff --git a/electron/main.cjs b/electron/main.cjs
new file mode 100644
index 0000000..8d191db
--- /dev/null
+++ b/electron/main.cjs
@@ -0,0 +1,52 @@
+const { app, BrowserWindow, shell } = require('electron');
+const path = require('path');
+
+const isDev = !app.isPackaged;
+
+function createWindow() {
+ const mainWindow = new BrowserWindow({
+ width: 1440,
+ height: 900,
+ minWidth: 1024,
+ minHeight: 720,
+ show: false,
+ backgroundColor: '#ffffff',
+ webPreferences: {
+ preload: path.join(__dirname, 'preload.cjs'),
+ contextIsolation: true,
+ nodeIntegration: false,
+ sandbox: false
+ }
+ });
+
+ mainWindow.once('ready-to-show', () => {
+ mainWindow.show();
+ });
+
+ mainWindow.webContents.setWindowOpenHandler(({ url }) => {
+ shell.openExternal(url);
+ return { action: 'deny' };
+ });
+
+ if (isDev && process.env.ELECTRON_RENDERER_URL) {
+ mainWindow.loadURL(process.env.ELECTRON_RENDERER_URL);
+ } else {
+ mainWindow.loadFile(path.join(__dirname, '../dist/index.html'));
+ }
+}
+
+app.whenReady().then(() => {
+ createWindow();
+
+ app.on('activate', () => {
+ if (BrowserWindow.getAllWindows().length === 0) {
+ createWindow();
+ }
+ });
+});
+
+app.on('window-all-closed', () => {
+ if (process.platform !== 'darwin') {
+ app.quit();
+ }
+});
diff --git a/electron/preload.cjs b/electron/preload.cjs
new file mode 100644
index 0000000..0018aff
--- /dev/null
+++ b/electron/preload.cjs
@@ -0,0 +1,5 @@
+const { contextBridge } = require('electron');
+
+contextBridge.exposeInMainWorld('electronApp', {
+ platform: process.platform
+});
diff --git a/package.json b/package.json
index 451f480..8491ea9 100644
--- a/package.json
+++ b/package.json
@@ -6,10 +6,14 @@
"author": "LionLi",
"license": "MIT",
"type": "module",
+ "main": "electron/main.cjs",
"scripts": {
"dev": "vite serve --mode development",
"build:prod": "vite build --mode production",
"build:dev": "vite build --mode development",
+ "build:electron": "vite build --mode electron",
+ "electron": "npm run build:electron && electron .",
+ "electron:win": "npm run build:electron && electron-builder --win --x64",
"preview": "vite preview",
"lint:eslint": "eslint",
"lint:eslint:fix": "eslint --fix",
@@ -65,6 +69,8 @@
"@vue/eslint-config-prettier": "10.2.0",
"@vue/eslint-config-typescript": "14.6.0",
"autoprefixer": "10.4.27",
+ "electron": "^39.2.6",
+ "electron-builder": "^26.0.12",
"eslint": "9.39.1",
"eslint-plugin-prettier": "5.5.5",
"eslint-plugin-vue": "9.33.0",
@@ -86,6 +92,40 @@
"overrides": {
"quill": "1.3.7"
},
+ "build": {
+ "appId": "com.haiwei.energy.visual.editor",
+ "productName": "HaiWei Plus",
+ "asar": true,
+ "directories": {
+ "output": "release"
+ },
+ "files": [
+ "dist/**/*",
+ "electron/**/*",
+ "package.json"
+ ],
+ "extraMetadata": {
+ "main": "electron/main.cjs"
+ },
+ "win": {
+ "target": [
+ {
+ "target": "nsis",
+ "arch": [
+ "x64"
+ ]
+ }
+ ],
+ "artifactName": "${productName}-${version}-${os}-${arch}.${ext}"
+ },
+ "nsis": {
+ "oneClick": false,
+ "allowToChangeInstallationDirectory": true,
+ "createDesktopShortcut": true,
+ "createStartMenuShortcut": true,
+ "shortcutName": "HaiWei Plus"
+ }
+ },
"engines": {
"node": ">=20.19.0",
"npm": ">=8.19.0"
diff --git a/src/App.vue b/src/App.vue
index 94cddcc..f929a60 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -3,33 +3,85 @@