update: Integrate Electron support with new main and preload scripts, update package.json for Electron build configurations, and adjust API base URL handling in request utility for compatibility

This commit is contained in:
Lexcubia 2025-04-20 22:07:15 +08:00
parent d395352947
commit 756c380d7b
8 changed files with 113 additions and 1734 deletions

1
.gitignore vendored
View File

@ -10,6 +10,7 @@ lerna-debug.log*
node_modules node_modules
dist dist
dist-ssr dist-ssr
release
*.local *.local
# Editor directories and files # Editor directories and files

20
dist-electron/main.js Normal file
View File

@ -0,0 +1,20 @@
const { app: e, BrowserWindow: t } = require("electron"), i = require("path");
function o() {
const n = new t({
width: 1200,
height: 800,
webPreferences: {
nodeIntegration: !0,
contextIsolation: !1
}
});
process.env.NODE_ENV === "development" ? (n.loadURL("http://localhost:5173"), n.webContents.openDevTools()) : n.loadFile(i.join(__dirname, "../dist/index.html"));
}
e.whenReady().then(() => {
o(), e.on("activate", () => {
t.getAllWindows().length === 0 && o();
});
});
e.on("window-all-closed", () => {
process.platform !== "darwin" && e.quit();
});

1
dist-electron/preload.js Normal file
View File

@ -0,0 +1 @@
window.electron = require("electron");

38
electron/main.js Normal file
View File

@ -0,0 +1,38 @@
const { app, BrowserWindow } = require('electron')
const path = require('path')
function createWindow() {
const win = new BrowserWindow({
width: 1200,
height: 800,
webPreferences: {
nodeIntegration: true,
contextIsolation: false
}
})
// 开发环境下加载 Vite 开发服务器
if (process.env.NODE_ENV === 'development') {
win.loadURL('http://localhost:5173')
win.webContents.openDevTools()
} else {
// 生产环境下加载打包后的文件
win.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()
}
})

View File

@ -3,13 +3,39 @@
"private": true, "private": true,
"version": "0.0.0", "version": "0.0.0",
"type": "module", "type": "module",
"main": "electron/main.js",
"scripts": { "scripts": {
"dev": "vite --mode development", "dev": "vite --mode development",
"dev:test": "vite --mode test", "dev:test": "vite --mode test",
"build": "vite build", "build": "vite build",
"build:dev": "vite build --mode development", "build:dev": "vite build --mode development",
"build:prod": "vite build --mode production", "build:prod": "vite build --mode production",
"preview": "vite preview" "preview": "vite preview",
"electron:dev": "vite --mode development & electron .",
"electron:build": "vite build && electron-builder",
"electron:preview": "electron ."
},
"build": {
"appId": "com.wx.chat",
"productName": "WX Chat",
"directories": {
"output": "release"
},
"files": [
"dist/**/*",
"electron/**/*"
],
"win": {
"target": [
"nsis"
]
},
"nsis": {
"oneClick": false,
"allowToChangeInstallationDirectory": true,
"createDesktopShortcut": true,
"createStartMenuShortcut": true
}
}, },
"dependencies": { "dependencies": {
"@element-plus/icons-vue": "^2.3.1", "@element-plus/icons-vue": "^2.3.1",
@ -25,8 +51,11 @@
}, },
"devDependencies": { "devDependencies": {
"@vitejs/plugin-vue": "^5.2.1", "@vitejs/plugin-vue": "^5.2.1",
"electron": "^35.2.0",
"electron-builder": "^26.0.12",
"sass": "^1.86.3", "sass": "^1.86.3",
"sass-embedded": "^1.86.3", "sass-embedded": "^1.86.3",
"vite": "^6.2.0" "vite": "^6.2.0",
"vite-plugin-electron": "^0.29.0"
} }
} }

View File

@ -1,8 +1,11 @@
import axios from 'axios' import axios from 'axios'
import { fetchEventSource } from '@microsoft/fetch-event-source' import { fetchEventSource } from '@microsoft/fetch-event-source'
// 判断是否在 Electron 环境中
const isElectron = window && window.process && window.process.type
const service = axios.create({ const service = axios.create({
baseURL: process.env.VITE_APP_BASE_API, baseURL: isElectron ? process.env.VITE_APP_BASE_API : import.meta.env.VITE_APP_BASE_API,
timeout: 30000 timeout: 30000
}) })
@ -38,7 +41,8 @@ service.interceptors.response.use(
export const sseRequest = (config) => { export const sseRequest = (config) => {
return new Promise((resolve) => { return new Promise((resolve) => {
try { try {
const url = new URL(`${config.url}`, window.location.origin) const baseURL = isElectron ? process.env.VITE_APP_BASE_API : import.meta.env.VITE_APP_BASE_API
const url = new URL(`${config.url}`, baseURL)
const ctrl = new AbortController() const ctrl = new AbortController()
let messageQueue = [] let messageQueue = []
let resolveQueue = null let resolveQueue = null
@ -49,11 +53,22 @@ export const sseRequest = (config) => {
headers: { headers: {
'Authorization': config.headers?.Authorization || `Bearer ${localStorage.getItem('token')}`, 'Authorization': config.headers?.Authorization || `Bearer ${localStorage.getItem('token')}`,
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Accept': 'text/event-stream' 'Accept': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
}, },
body: JSON.stringify(config.params), body: JSON.stringify(config.params),
signal: ctrl.signal, signal: ctrl.signal,
openWhenHidden: true, openWhenHidden: true,
credentials: 'include',
keepalive: true,
retry: 1000,
onopen(response) {
if (response.ok && response.headers.get('content-type')?.includes('text/event-stream')) {
return;
}
throw new Error(`Failed to open SSE connection: ${response.status} ${response.statusText}`);
},
onmessage: (event) => { onmessage: (event) => {
try { try {
const data = JSON.parse(event.data) const data = JSON.parse(event.data)

View File

@ -2,6 +2,7 @@ import { fileURLToPath, URL } from 'node:url'
import { defineConfig, loadEnv } from 'vite' import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue' import vue from '@vitejs/plugin-vue'
import electron from 'vite-plugin-electron'
// import vueDevTools from 'vite-plugin-vue-devtools' // import vueDevTools from 'vite-plugin-vue-devtools'
// https://vite.dev/config/ // https://vite.dev/config/
@ -17,6 +18,9 @@ export default defineConfig(({ command, mode }) => {
return { return {
plugins: [ plugins: [
vue(), vue(),
electron({
entry: 'electron/main.js',
}),
// vueDevTools(), // vueDevTools(),
], ],
resolve: { resolve: {

1729
yarn.lock

File diff suppressed because it is too large Load Diff